mp_aframe_create:
   52|   412k|{
   53|   412k|    struct mp_aframe *frame = talloc_zero(NULL, struct mp_aframe);
  ------------------
  |  |   27|   412k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   412k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   412k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   54|   412k|    frame->av_frame = av_frame_alloc();
   55|   412k|    MP_HANDLE_OOM(frame->av_frame);
  ------------------
  |  |  176|   412k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|   412k|        void *oom_p_ = (x);     \
  |  |  178|   412k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 412k]
  |  |  ------------------
  |  |  179|   412k|            abort();            \
  |  |  180|   412k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   56|   412k|    talloc_set_destructor(frame, free_frame);
  ------------------
  |  |   41|   412k|#define talloc_set_destructor           ta_set_destructor
  ------------------
   57|   412k|    mp_aframe_reset(frame);
   58|   412k|    return frame;
   59|   412k|}
mp_aframe_new_ref:
   62|  2.13k|{
   63|  2.13k|    if (!frame)
  ------------------
  |  Branch (63:9): [True: 0, False: 2.13k]
  ------------------
   64|      0|        return NULL;
   65|       |
   66|  2.13k|    struct mp_aframe *dst = mp_aframe_create();
   67|       |
   68|  2.13k|    dst->chmap = frame->chmap;
   69|  2.13k|    dst->format = frame->format;
   70|  2.13k|    dst->pts = frame->pts;
   71|  2.13k|    dst->speed = frame->speed;
   72|       |
   73|  2.13k|    if (mp_aframe_is_allocated(frame)) {
  ------------------
  |  Branch (73:9): [True: 0, False: 2.13k]
  ------------------
   74|      0|        if (av_frame_ref(dst->av_frame, frame->av_frame) < 0)
  ------------------
  |  Branch (74:13): [True: 0, False: 0]
  ------------------
   75|      0|            abort();
   76|  2.13k|    } else {
   77|       |        // av_frame_ref() would fail.
   78|  2.13k|        mp_aframe_config_copy(dst, frame);
   79|  2.13k|    }
   80|       |
   81|  2.13k|    return dst;
   82|  2.13k|}
mp_aframe_reset:
   86|   425k|{
   87|   425k|    av_frame_unref(frame->av_frame);
   88|   425k|    frame->chmap.num = 0;
   89|   425k|    frame->format = 0;
   90|   425k|    frame->pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   425k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   91|   425k|    frame->speed = 1.0;
   92|   425k|}
mp_aframe_alloc_data:
  109|  1.23k|{
  110|  1.23k|    if (mp_aframe_is_allocated(frame))
  ------------------
  |  Branch (110:9): [True: 0, False: 1.23k]
  ------------------
  111|      0|        return false;
  112|  1.23k|    struct mp_aframe_pool *p = mp_aframe_pool_create(NULL);
  113|  1.23k|    int r = mp_aframe_pool_allocate(p, frame, samples);
  114|  1.23k|    talloc_free(p);
  ------------------
  |  |   47|  1.23k|#define talloc_free                     ta_free
  ------------------
  115|  1.23k|    return r >= 0;
  116|  1.23k|}
mp_aframe_from_avframe:
  122|   373k|{
  123|   373k|    if (!av_frame || av_frame->width > 0 || av_frame->height > 0)
  ------------------
  |  Branch (123:9): [True: 0, False: 373k]
  |  Branch (123:22): [True: 0, False: 373k]
  |  Branch (123:45): [True: 0, False: 373k]
  ------------------
  124|      0|        return NULL;
  125|       |
  126|   373k|    if (!av_channel_layout_check(&av_frame->ch_layout))
  ------------------
  |  Branch (126:9): [True: 0, False: 373k]
  ------------------
  127|      0|        return NULL;
  128|       |
  129|   373k|    struct mp_chmap converted_map = { 0 };
  130|   373k|    if (!mp_chmap_from_av_layout(&converted_map, &av_frame->ch_layout)) {
  ------------------
  |  Branch (130:9): [True: 0, False: 373k]
  ------------------
  131|      0|        return NULL;
  132|      0|    }
  133|       |
  134|   373k|    int format = af_from_avformat(av_frame->format);
  135|   373k|    if (!format && av_frame->format != AV_SAMPLE_FMT_NONE)
  ------------------
  |  Branch (135:9): [True: 0, False: 373k]
  |  Branch (135:20): [True: 0, False: 0]
  ------------------
  136|      0|        return NULL;
  137|       |
  138|   373k|    struct mp_aframe *frame = mp_aframe_create();
  139|       |
  140|       |    // This also takes care of forcing refcounting.
  141|   373k|    if (av_frame_ref(frame->av_frame, av_frame) < 0)
  ------------------
  |  Branch (141:9): [True: 0, False: 373k]
  ------------------
  142|      0|        abort();
  143|       |
  144|   373k|    frame->format = format;
  145|   373k|    frame->chmap = converted_map;
  146|       |
  147|   373k|    if (av_frame->opaque_ref) {
  ------------------
  |  Branch (147:9): [True: 0, False: 373k]
  ------------------
  148|      0|        struct avframe_opaque *op = (void *)av_frame->opaque_ref->data;
  149|      0|        frame->speed = op->speed;
  150|      0|    }
  151|       |
  152|   373k|    return frame;
  153|   373k|}
mp_aframe_is_allocated:
  197|  1.39M|{
  198|  1.39M|    return frame->av_frame->buf[0] || frame->av_frame->extended_data[0];
  ------------------
  |  Branch (198:12): [True: 1.38M, False: 8.01k]
  |  Branch (198:39): [True: 0, False: 8.01k]
  ------------------
  199|  1.39M|}
mp_aframe_config_copy:
  203|  11.6k|{
  204|  11.6k|    mp_aframe_reset(dst);
  205|       |
  206|  11.6k|    dst->chmap = src->chmap;
  207|  11.6k|    dst->format = src->format;
  208|       |
  209|  11.6k|    mp_aframe_copy_attributes(dst, src);
  210|       |
  211|  11.6k|    dst->av_frame->sample_rate = src->av_frame->sample_rate;
  212|  11.6k|    dst->av_frame->format = src->av_frame->format;
  213|       |
  214|  11.6k|    if (av_channel_layout_copy(&dst->av_frame->ch_layout, &src->av_frame->ch_layout) < 0)
  ------------------
  |  Branch (214:9): [True: 0, False: 11.6k]
  ------------------
  215|      0|        abort();
  216|  11.6k|}
mp_aframe_copy_attributes:
  221|  11.6k|{
  222|  11.6k|    dst->pts = src->pts;
  223|  11.6k|    dst->speed = src->speed;
  224|       |
  225|  11.6k|    int rate = dst->av_frame->sample_rate;
  226|       |
  227|  11.6k|    if (av_frame_copy_props(dst->av_frame, src->av_frame) < 0)
  ------------------
  |  Branch (227:9): [True: 0, False: 11.6k]
  ------------------
  228|      0|        abort();
  229|       |
  230|  11.6k|    dst->av_frame->sample_rate = rate;
  231|  11.6k|}
mp_aframe_config_equals:
  236|  1.49M|{
  237|  1.49M|    struct mp_chmap ca = {0}, cb = {0};
  238|  1.49M|    mp_aframe_get_chmap(a, &ca);
  239|  1.49M|    mp_aframe_get_chmap(b, &cb);
  240|  1.49M|    return mp_chmap_equals(&ca, &cb) &&
  ------------------
  |  Branch (240:12): [True: 1.49M, False: 4.78k]
  ------------------
  241|  1.49M|           mp_aframe_get_rate(a) == mp_aframe_get_rate(b) &&
  ------------------
  |  Branch (241:12): [True: 1.48M, False: 1.35k]
  ------------------
  242|  1.49M|           mp_aframe_get_format(a) == mp_aframe_get_format(b);
  ------------------
  |  Branch (242:12): [True: 1.48M, False: 0]
  ------------------
  243|  1.49M|}
mp_aframe_config_is_valid:
  247|  1.42k|{
  248|  1.42k|    return frame->format && frame->chmap.num && frame->av_frame->sample_rate;
  ------------------
  |  Branch (248:12): [True: 1.42k, False: 0]
  |  Branch (248:29): [True: 1.42k, False: 0]
  |  Branch (248:49): [True: 1.42k, False: 0]
  ------------------
  249|  1.42k|}
mp_aframe_get_data_ro:
  255|   373k|{
  256|   373k|    return mp_aframe_is_allocated(frame) ? frame->av_frame->extended_data : NULL;
  ------------------
  |  Branch (256:12): [True: 373k, False: 0]
  ------------------
  257|   373k|}
mp_aframe_get_data_rw:
  262|  1.01M|{
  263|  1.01M|    if (!mp_aframe_is_allocated(frame))
  ------------------
  |  Branch (263:9): [True: 0, False: 1.01M]
  ------------------
  264|      0|        return NULL;
  265|  1.01M|    if (av_frame_make_writable(frame->av_frame) < 0)
  ------------------
  |  Branch (265:9): [True: 0, False: 1.01M]
  ------------------
  266|      0|        return NULL;
  267|  1.01M|    return frame->av_frame->extended_data;
  268|  1.01M|}
mp_aframe_get_format:
  271|  6.69M|{
  272|  6.69M|    return frame->format;
  273|  6.69M|}
mp_aframe_get_chmap:
  276|  3.36M|{
  277|  3.36M|    if (!mp_chmap_is_valid(&frame->chmap))
  ------------------
  |  Branch (277:9): [True: 2.93k, False: 3.36M]
  ------------------
  278|  2.93k|        return false;
  279|  3.36M|    *out = frame->chmap;
  280|  3.36M|    return true;
  281|  3.36M|}
mp_aframe_get_channels:
  284|  1.47M|{
  285|  1.47M|    return frame->chmap.num;
  286|  1.47M|}
mp_aframe_get_rate:
  289|  6.71M|{
  290|  6.71M|    return frame->av_frame->sample_rate;
  291|  6.71M|}
mp_aframe_get_size:
  294|  4.39M|{
  295|  4.39M|    return frame->av_frame->nb_samples;
  296|  4.39M|}
mp_aframe_get_pts:
  299|  3.73M|{
  300|  3.73M|    return frame->pts;
  301|  3.73M|}
mp_aframe_set_format:
  304|  2.05k|{
  305|  2.05k|    if (mp_aframe_is_allocated(frame))
  ------------------
  |  Branch (305:9): [True: 0, False: 2.05k]
  ------------------
  306|      0|        return false;
  307|  2.05k|    enum AVSampleFormat av_format = af_to_avformat(format);
  308|  2.05k|    if (av_format == AV_SAMPLE_FMT_NONE && format) {
  ------------------
  |  Branch (308:9): [True: 0, False: 2.05k]
  |  Branch (308:44): [True: 0, False: 0]
  ------------------
  309|      0|        if (!af_fmt_is_spdif(format))
  ------------------
  |  Branch (309:13): [True: 0, False: 0]
  ------------------
  310|      0|            return false;
  311|      0|        av_format = AV_SAMPLE_FMT_S16;
  312|      0|    }
  313|  2.05k|    frame->format = format;
  314|  2.05k|    frame->av_frame->format = av_format;
  315|  2.05k|    return true;
  316|  2.05k|}
mp_aframe_set_chmap:
  319|  1.35k|{
  320|  1.35k|    if (!mp_chmap_is_valid(in) && !mp_chmap_is_empty(in))
  ------------------
  |  Branch (320:9): [True: 0, False: 1.35k]
  |  Branch (320:35): [True: 0, False: 0]
  ------------------
  321|      0|        return false;
  322|  1.35k|    if (mp_aframe_is_allocated(frame) && in->num != frame->chmap.num)
  ------------------
  |  Branch (322:9): [True: 0, False: 1.35k]
  |  Branch (322:42): [True: 0, False: 0]
  ------------------
  323|      0|        return false;
  324|       |
  325|  1.35k|    frame->chmap = *in;
  326|  1.35k|    mp_chmap_to_av_layout(&frame->av_frame->ch_layout, in);
  327|       |
  328|  1.35k|    return true;
  329|  1.35k|}
mp_aframe_set_rate:
  332|  1.35k|{
  333|  1.35k|    if (rate < 1 || rate > 10000000)
  ------------------
  |  Branch (333:9): [True: 0, False: 1.35k]
  |  Branch (333:21): [True: 116, False: 1.23k]
  ------------------
  334|    116|        return false;
  335|  1.23k|    frame->av_frame->sample_rate = rate;
  336|  1.23k|    return true;
  337|  1.35k|}
mp_aframe_set_pts:
  348|   747k|{
  349|   747k|    frame->pts = pts;
  350|   747k|}
mp_aframe_get_effective_rate:
  379|  2.98M|{
  380|  2.98M|    return mp_aframe_get_rate(frame) / frame->speed;
  381|  2.98M|}
mp_aframe_get_planes:
  385|  1.47M|{
  386|  1.47M|    return af_fmt_is_planar(mp_aframe_get_format(frame))
  ------------------
  |  Branch (386:12): [True: 1.43M, False: 40.6k]
  ------------------
  387|  1.47M|           ? mp_aframe_get_channels(frame) : 1;
  388|  1.47M|}
mp_aframe_get_sstride:
  392|  1.11M|{
  393|  1.11M|    int format = mp_aframe_get_format(frame);
  394|  1.11M|    return af_fmt_to_bytes(format) *
  395|  1.11M|           (af_fmt_is_planar(format) ? 1 : mp_aframe_get_channels(frame));
  ------------------
  |  Branch (395:13): [True: 1.07M, False: 40.6k]
  ------------------
  396|  1.11M|}
mp_aframe_get_total_plane_samples:
  400|   379k|{
  401|   379k|    return frame->av_frame->nb_samples *
  402|   379k|           (af_fmt_is_planar(mp_aframe_get_format(frame))
  ------------------
  |  Branch (402:13): [True: 379k, False: 0]
  ------------------
  403|   379k|            ? 1 : mp_aframe_get_channels(frame));
  404|   379k|}
mp_aframe_format_str_buf:
  407|  5.45k|{
  408|  5.45k|    char ch[128];
  409|  5.45k|    mp_chmap_to_str_buf(ch, sizeof(ch), &fmt->chmap);
  410|  5.45k|    char *hr_ch = mp_chmap_to_str_hr(&fmt->chmap);
  ------------------
  |  |  137|  5.45k|#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_(m, MP_NUM_CHANNELS * 4)
  |  |  ------------------
  |  |  |  |  136|  5.45k|#define mp_chmap_to_str_hr_(m, sz) mp_chmap_to_str_hr_buf((char[sz]){0}, sz, (m))
  |  |  ------------------
  ------------------
  411|  5.45k|    if (strcmp(hr_ch, ch) != 0)
  ------------------
  |  Branch (411:9): [True: 176, False: 5.27k]
  ------------------
  412|    176|        mp_snprintf_cat(ch, sizeof(ch), " (%s)", hr_ch);
  413|  5.45k|    snprintf(buf, buf_size, "%dHz %s %dch %s", fmt->av_frame->sample_rate,
  414|  5.45k|             ch, fmt->chmap.num, af_fmt_to_str(fmt->format));
  415|  5.45k|    return buf;
  416|  5.45k|}
mp_aframe_skip_samples:
  420|   373k|{
  421|   373k|    mp_assert(samples >= 0 && samples <= mp_aframe_get_size(f));
  ------------------
  |  |   41|   373k|#define mp_assert assert
  ------------------
  422|       |
  423|   373k|    if (av_frame_make_writable(f->av_frame) < 0)
  ------------------
  |  Branch (423:9): [True: 0, False: 373k]
  ------------------
  424|      0|        return; // go complain to ffmpeg
  425|       |
  426|   373k|    int num_planes = mp_aframe_get_planes(f);
  427|   373k|    size_t sstride = mp_aframe_get_sstride(f);
  428|   783k|    for (int n = 0; n < num_planes; n++) {
  ------------------
  |  Branch (428:21): [True: 410k, False: 373k]
  ------------------
  429|   410k|        memmove(f->av_frame->extended_data[n],
  430|   410k|                f->av_frame->extended_data[n] + samples * sstride,
  431|   410k|                (f->av_frame->nb_samples - samples) * sstride);
  432|   410k|    }
  433|       |
  434|   373k|    f->av_frame->nb_samples -= samples;
  435|       |
  436|   373k|    if (f->pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (436:9): [True: 373k, False: 0]
  ------------------
  437|   373k|        f->pts += samples / mp_aframe_get_effective_rate(f);
  438|   373k|}
mp_aframe_sanitize_float:
  447|   373k|{
  448|   373k|    int format = af_fmt_from_planar(mp_aframe_get_format(mpa));
  449|   373k|    if (format != AF_FORMAT_FLOAT && format != AF_FORMAT_DOUBLE)
  ------------------
  |  Branch (449:9): [True: 21.5k, False: 351k]
  |  Branch (449:38): [True: 21.5k, False: 0]
  ------------------
  450|  21.5k|        return;
  451|   351k|    int num_planes = mp_aframe_get_planes(mpa);
  452|   351k|    uint8_t **planes = mp_aframe_get_data_rw(mpa);
  453|   351k|    if (!planes)
  ------------------
  |  Branch (453:9): [True: 0, False: 351k]
  ------------------
  454|      0|        return;
  455|   731k|    for (int p = 0; p < num_planes; p++) {
  ------------------
  |  Branch (455:21): [True: 379k, False: 351k]
  ------------------
  456|   379k|        void *ptr = planes[p];
  457|   379k|        int total = mp_aframe_get_total_plane_samples(mpa);
  458|   379k|        switch (format) {
  ------------------
  |  Branch (458:17): [True: 0, False: 379k]
  ------------------
  459|   379k|        case AF_FORMAT_FLOAT:
  ------------------
  |  Branch (459:9): [True: 379k, False: 0]
  ------------------
  460|   110M|            for (int s = 0; s < total; s++)
  ------------------
  |  Branch (460:29): [True: 109M, False: 379k]
  ------------------
  461|   109M|                sanitizef(((float *)ptr)[s]);
  ------------------
  |  |  441|   110M|#define sanitizef(f) do {       \
  |  |  442|   109M|    if (!isnormal(f))           \
  |  |  ------------------
  |  |  |  Branch (442:9): [True: 96.1M, False: 13.5M]
  |  |  ------------------
  |  |  443|   109M|        (f) = 0;                \
  |  |  444|   109M|} while (0)
  |  |  ------------------
  |  |  |  Branch (444:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  462|   379k|            break;
  463|      0|        case AF_FORMAT_DOUBLE:
  ------------------
  |  Branch (463:9): [True: 0, False: 379k]
  ------------------
  464|      0|            for (int s = 0; s < total; s++)
  ------------------
  |  Branch (464:29): [True: 0, False: 0]
  ------------------
  465|      0|                sanitizef(((double *)ptr)[s]);
  ------------------
  |  |  441|      0|#define sanitizef(f) do {       \
  |  |  442|      0|    if (!isnormal(f))           \
  |  |  ------------------
  |  |  |  Branch (442:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  443|      0|        (f) = 0;                \
  |  |  444|      0|} while (0)
  |  |  ------------------
  |  |  |  Branch (444:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  466|      0|            break;
  467|   379k|        }
  468|   379k|    }
  469|   351k|}
mp_aframe_end_pts:
  473|  1.49M|{
  474|  1.49M|    double rate = mp_aframe_get_effective_rate(f);
  475|  1.49M|    if (f->pts == MP_NOPTS_VALUE || rate <= 0)
  ------------------
  |  |   38|  2.98M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (475:9): [True: 328, False: 1.49M]
  |  Branch (475:37): [True: 0, False: 1.49M]
  ------------------
  476|    328|        return MP_NOPTS_VALUE;
  ------------------
  |  |   38|    328|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  477|  1.49M|    return f->pts + f->av_frame->nb_samples / rate;
  478|  1.49M|}
mp_aframe_duration:
  482|   373k|{
  483|   373k|    double rate = mp_aframe_get_effective_rate(f);
  484|   373k|    if (rate <= 0)
  ------------------
  |  Branch (484:9): [True: 0, False: 373k]
  ------------------
  485|      0|        return 0;
  486|   373k|    return f->av_frame->nb_samples / rate;
  487|   373k|}
mp_aframe_clip_timestamps:
  493|   747k|{
  494|   747k|    double f_end = mp_aframe_end_pts(f);
  495|   747k|    double rate = mp_aframe_get_effective_rate(f);
  496|   747k|    if (f_end == MP_NOPTS_VALUE)
  ------------------
  |  |   38|   747k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (496:9): [True: 164, False: 746k]
  ------------------
  497|    164|        return;
  498|   746k|    if (end != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   746k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (498:9): [True: 15, False: 746k]
  ------------------
  499|     15|        if (f_end >= end) {
  ------------------
  |  Branch (499:13): [True: 0, False: 15]
  ------------------
  500|      0|            if (f->pts >= end) {
  ------------------
  |  Branch (500:17): [True: 0, False: 0]
  ------------------
  501|      0|                f->av_frame->nb_samples = 0;
  502|      0|            } else {
  503|      0|                if (af_fmt_is_spdif(mp_aframe_get_format(f)))
  ------------------
  |  Branch (503:21): [True: 0, False: 0]
  ------------------
  504|      0|                    return;
  505|      0|                int new = (end - f->pts) * rate;
  506|      0|                f->av_frame->nb_samples = MPCLAMP(new, 0, f->av_frame->nb_samples);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  507|      0|            }
  508|      0|        }
  509|     15|    }
  510|   746k|    if (start != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   746k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (510:9): [True: 15, False: 746k]
  ------------------
  511|     15|        if (f->pts < start) {
  ------------------
  |  Branch (511:13): [True: 0, False: 15]
  ------------------
  512|      0|            if (f_end <= start) {
  ------------------
  |  Branch (512:17): [True: 0, False: 0]
  ------------------
  513|      0|                f->av_frame->nb_samples = 0;
  514|      0|                f->pts = f_end;
  515|      0|            } else {
  516|      0|                if (af_fmt_is_spdif(mp_aframe_get_format(f)))
  ------------------
  |  Branch (516:21): [True: 0, False: 0]
  ------------------
  517|      0|                    return;
  518|      0|                int skip = (start - f->pts) * rate;
  519|      0|                skip = MPCLAMP(skip, 0, f->av_frame->nb_samples);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  520|      0|                mp_aframe_skip_samples(f, skip);
  521|      0|            }
  522|      0|        }
  523|     15|    }
  524|   746k|}
mp_aframe_approx_byte_size:
  612|   744k|{
  613|       |    // God damn, AVFrame is too fucking annoying. Just go with the size that
  614|       |    // allocating a new frame would use.
  615|   744k|    int planes = mp_aframe_get_planes(frame);
  616|   744k|    size_t sstride = mp_aframe_get_sstride(frame);
  617|   744k|    int samples = frame->av_frame->nb_samples;
  618|   744k|    int plane_size = MP_ALIGN_UP(sstride * MPMAX(samples, 1), 32);
  ------------------
  |  |   52|  1.48M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  |  |  |  Branch (52:34): [True: 744k, False: 26]
  |  |  ------------------
  ------------------
  619|   744k|    return plane_size * planes + sizeof(*frame);
  620|   744k|}
mp_aframe_pool_create:
  628|  1.23k|{
  629|  1.23k|    return talloc_zero(ta_parent, struct mp_aframe_pool);
  ------------------
  |  |   27|  1.23k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.23k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.23k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  630|  1.23k|}
mp_aframe_pool_allocate:
  641|  1.23k|{
  642|  1.23k|    int planes = mp_aframe_get_planes(frame);
  643|  1.23k|    size_t sstride = mp_aframe_get_sstride(frame);
  644|       |    // FFmpeg hardcodes similar hidden possibly-requirements in a number of
  645|       |    // places: av_frame_get_buffer(), libavcodec's get_buffer(), mem.c,
  646|       |    // probably more.
  647|  1.23k|    int align_samples = MP_ALIGN_UP(MPMAX(samples, 1), 32);
  ------------------
  |  |   52|  2.47k|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  |  |  |  Branch (52:34): [True: 1.23k, False: 0]
  |  |  ------------------
  ------------------
  648|  1.23k|    int plane_size = MP_ALIGN_UP(sstride * align_samples, 64);
  ------------------
  |  |   52|  1.23k|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  ------------------
  649|  1.23k|    int size = plane_size * planes;
  650|       |
  651|  1.23k|    if (size <= 0 || mp_aframe_is_allocated(frame))
  ------------------
  |  Branch (651:9): [True: 0, False: 1.23k]
  |  Branch (651:22): [True: 0, False: 1.23k]
  ------------------
  652|      0|        return -1;
  653|       |
  654|  1.23k|    if (!pool->avpool || size > pool->element_size) {
  ------------------
  |  Branch (654:9): [True: 1.23k, False: 0]
  |  Branch (654:26): [True: 0, False: 0]
  ------------------
  655|  1.23k|        size_t alloc = ta_calc_prealloc_elems(size);
  656|  1.23k|        if (alloc >= INT_MAX)
  ------------------
  |  Branch (656:13): [True: 0, False: 1.23k]
  ------------------
  657|      0|            return -1;
  658|  1.23k|        av_buffer_pool_uninit(&pool->avpool);
  659|  1.23k|        pool->element_size = alloc;
  660|  1.23k|        pool->avpool = av_buffer_pool_init(pool->element_size, NULL);
  661|  1.23k|        if (!pool->avpool)
  ------------------
  |  Branch (661:13): [True: 0, False: 1.23k]
  ------------------
  662|      0|            return -1;
  663|  1.23k|        talloc_set_destructor(pool, mp_aframe_pool_destructor);
  ------------------
  |  |   41|  1.23k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  664|  1.23k|    }
  665|       |
  666|       |    // Yes, you have to do all this shit manually.
  667|       |    // At least it's less stupid than av_frame_get_buffer(), which just wipes
  668|       |    // the entire frame struct on error for no reason.
  669|  1.23k|    AVFrame *av_frame = frame->av_frame;
  670|  1.23k|    if (av_frame->extended_data != av_frame->data)
  ------------------
  |  Branch (670:9): [True: 0, False: 1.23k]
  ------------------
  671|      0|        av_freep(&av_frame->extended_data); // sigh
  672|  1.23k|    if (planes > AV_NUM_DATA_POINTERS) {
  ------------------
  |  Branch (672:9): [True: 44, False: 1.19k]
  ------------------
  673|     44|        av_frame->extended_data =
  674|     44|            av_calloc(planes, sizeof(av_frame->extended_data[0]));
  675|     44|        MP_HANDLE_OOM(av_frame->extended_data);
  ------------------
  |  |  176|     44|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|     44|        void *oom_p_ = (x);     \
  |  |  178|     44|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 44]
  |  |  ------------------
  |  |  179|     44|            abort();            \
  |  |  180|     44|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  676|  1.19k|    } else {
  677|  1.19k|        av_frame->extended_data = av_frame->data;
  678|  1.19k|    }
  679|  1.23k|    av_frame->buf[0] = av_buffer_pool_get(pool->avpool);
  680|  1.23k|    if (!av_frame->buf[0])
  ------------------
  |  Branch (680:9): [True: 0, False: 1.23k]
  ------------------
  681|      0|        return -1;
  682|  1.23k|    av_frame->linesize[0] = samples * sstride;
  683|  3.71k|    for (int n = 0; n < planes; n++)
  ------------------
  |  Branch (683:21): [True: 2.48k, False: 1.23k]
  ------------------
  684|  2.48k|        av_frame->extended_data[n] = av_frame->buf[0]->data + n * plane_size;
  685|  1.23k|    if (planes > AV_NUM_DATA_POINTERS) {
  ------------------
  |  Branch (685:9): [True: 44, False: 1.19k]
  ------------------
  686|    396|        for (int n = 0; n < AV_NUM_DATA_POINTERS; n++)
  ------------------
  |  Branch (686:25): [True: 352, False: 44]
  ------------------
  687|    352|            av_frame->data[n] = av_frame->extended_data[n];
  688|     44|    }
  689|  1.23k|    av_frame->nb_samples = samples;
  690|       |
  691|  1.23k|    return 0;
  692|  1.23k|}
aframe.c:free_frame:
   46|   412k|{
   47|   412k|    struct mp_aframe *frame = ptr;
   48|   412k|    av_frame_free(&frame->av_frame);
   49|   412k|}
aframe.c:mp_aframe_pool_destructor:
  633|  1.23k|{
  634|  1.23k|    struct mp_aframe_pool *pool = p;
  635|  1.23k|    av_buffer_pool_uninit(&pool->avpool);
  636|  1.23k|}

mp_chmap_is_valid:
  126|  3.37M|{
  127|  3.37M|    bool mapped[MP_SPEAKER_ID_COUNT] = {0};
  128|  7.07M|    for (int n = 0; n < src->num; n++) {
  ------------------
  |  Branch (128:21): [True: 3.70M, False: 3.37M]
  ------------------
  129|  3.70M|        int sp = src->speaker[n];
  130|  3.70M|        if (sp >= MP_SPEAKER_ID_COUNT || mapped[sp])
  ------------------
  |  Branch (130:13): [True: 0, False: 3.70M]
  |  Branch (130:42): [True: 0, False: 3.70M]
  ------------------
  131|      0|            return false;
  132|  3.70M|        if (sp != MP_SPEAKER_ID_NA)
  ------------------
  |  Branch (132:13): [True: 3.44M, False: 257k]
  ------------------
  133|  3.44M|            mapped[sp] = true;
  134|  3.70M|    }
  135|  3.37M|    return src->num > 0;
  136|  3.37M|}
mp_chmap_is_unknown:
  146|  20.4k|{
  147|  24.9k|    for (int n = 0; n < src->num; n++) {
  ------------------
  |  Branch (147:21): [True: 24.1k, False: 795]
  ------------------
  148|  24.1k|        if (src->speaker[n] != MP_SPEAKER_ID_NA)
  ------------------
  |  Branch (148:13): [True: 19.7k, False: 4.45k]
  ------------------
  149|  19.7k|            return false;
  150|  24.1k|    }
  151|    795|    return mp_chmap_is_valid(src);
  152|  20.4k|}
mp_chmap_equals:
  156|  1.90M|{
  157|  1.90M|    if (a->num != b->num)
  ------------------
  |  Branch (157:9): [True: 28.9k, False: 1.87M]
  ------------------
  158|  28.9k|        return false;
  159|  3.92M|    for (int n = 0; n < a->num; n++) {
  ------------------
  |  Branch (159:21): [True: 2.05M, False: 1.87M]
  ------------------
  160|  2.05M|        if (a->speaker[n] != b->speaker[n])
  ------------------
  |  Branch (160:13): [True: 998, False: 2.05M]
  ------------------
  161|    998|            return false;
  162|  2.05M|    }
  163|  1.87M|    return true;
  164|  1.87M|}
mp_chmap_equals_reordered:
  168|  32.7k|{
  169|  32.7k|    struct mp_chmap t1 = *a, t2 = *b;
  170|  32.7k|    mp_chmap_reorder_norm(&t1);
  171|  32.7k|    mp_chmap_reorder_norm(&t2);
  172|  32.7k|    return mp_chmap_equals(&t1, &t2);
  173|  32.7k|}
mp_chmap_reorder_norm:
  189|  65.5k|{
  190|  65.5k|    uint8_t *arr = &map->speaker[0];
  191|  65.5k|    qsort(arr, map->num, 1, comp_uint8);
  192|  65.5k|}
mp_chmap_remove_na:
  196|  6.80k|{
  197|  6.80k|    struct mp_chmap new = {0};
  198|  20.4k|    for (int n = 0; n < map->num; n++) {
  ------------------
  |  Branch (198:21): [True: 13.6k, False: 6.80k]
  ------------------
  199|  13.6k|        int sp = map->speaker[n];
  200|  13.6k|        if (sp != MP_SPEAKER_ID_NA)
  ------------------
  |  Branch (200:13): [True: 10.8k, False: 2.78k]
  ------------------
  201|  10.8k|            new.speaker[new.num++] = map->speaker[n];
  202|  13.6k|    }
  203|  6.80k|    *map = new;
  204|  6.80k|}
mp_chmap_from_channels:
  218|  23.1k|{
  219|  23.1k|    *dst = (struct mp_chmap) {0};
  220|  23.1k|    if (num_channels >= 0 && num_channels < MP_ARRAY_SIZE(default_layouts))
  ------------------
  |  |   48|  23.1k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (220:9): [True: 23.1k, False: 0]
  |  Branch (220:30): [True: 18.1k, False: 5.02k]
  ------------------
  221|  18.1k|        *dst = default_layouts[num_channels];
  222|  23.1k|    if (!dst->num)
  ------------------
  |  Branch (222:9): [True: 14.3k, False: 8.84k]
  ------------------
  223|  14.3k|        mp_chmap_set_unknown(dst, num_channels);
  224|  23.1k|}
mp_chmap_set_unknown:
  232|  14.3k|{
  233|  14.3k|    if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
  ------------------
  |  |   25|  14.3k|#define MP_NUM_CHANNELS 64
  ------------------
  |  Branch (233:9): [True: 0, False: 14.3k]
  |  Branch (233:29): [True: 0, False: 14.3k]
  ------------------
  234|      0|        *dst = (struct mp_chmap) {0};
  235|  14.3k|    } else {
  236|  14.3k|        dst->num = num_channels;
  237|  71.3k|        for (int n = 0; n < dst->num; n++)
  ------------------
  |  Branch (237:25): [True: 57.0k, False: 14.3k]
  ------------------
  238|  57.0k|            dst->speaker[n] = MP_SPEAKER_ID_NA;
  239|  14.3k|    }
  240|  14.3k|}
mp_chmap_to_lavc_unchecked:
  249|  1.30k|{
  250|  1.30k|    struct mp_chmap t = *src;
  251|  1.30k|    if (t.num > 64)
  ------------------
  |  Branch (251:9): [True: 0, False: 1.30k]
  ------------------
  252|      0|        return 0;
  253|       |    // lavc has no concept for unknown layouts yet, so pick something that does
  254|       |    // the job of signaling the number of channels, even if it makes no sense
  255|       |    // as a proper layout.
  256|  1.30k|    if (mp_chmap_is_unknown(&t))
  ------------------
  |  Branch (256:9): [True: 0, False: 1.30k]
  ------------------
  257|      0|        return t.num == 64 ? (uint64_t)-1 : (1ULL << t.num) - 1;
  ------------------
  |  Branch (257:16): [True: 0, False: 0]
  ------------------
  258|  1.30k|    uint64_t mask = 0;
  259|  3.47k|    for (int n = 0; n < t.num; n++) {
  ------------------
  |  Branch (259:21): [True: 2.16k, False: 1.30k]
  ------------------
  260|  2.16k|        if (t.speaker[n] < 64) // ignore MP_SPEAKER_ID_NA etc.
  ------------------
  |  Branch (260:13): [True: 2.16k, False: 0]
  ------------------
  261|  2.16k|            mask |= 1ULL << t.speaker[n];
  262|  2.16k|    }
  263|  1.30k|    return mask;
  264|  1.30k|}
mp_chmap_to_lavc:
  269|  1.53k|{
  270|  1.53k|    if (!mp_chmap_is_lavc(src))
  ------------------
  |  Branch (270:9): [True: 223, False: 1.30k]
  ------------------
  271|    223|        return 0;
  272|  1.30k|    return mp_chmap_to_lavc_unchecked(src);
  273|  1.53k|}
mp_chmap_from_lavc:
  279|   742k|{
  280|   742k|    dst->num = 0;
  281|  48.2M|    for (int n = 0; n < 64; n++) {
  ------------------
  |  Branch (281:21): [True: 47.5M, False: 742k]
  ------------------
  282|  47.5M|        if (src & (1ULL << n)) {
  ------------------
  |  Branch (282:13): [True: 760k, False: 46.7M]
  ------------------
  283|   760k|            if (dst->num >= MP_NUM_CHANNELS) {
  ------------------
  |  |   25|   760k|#define MP_NUM_CHANNELS 64
  ------------------
  |  Branch (283:17): [True: 0, False: 760k]
  ------------------
  284|      0|                dst->num = 0;
  285|      0|                return;
  286|      0|            }
  287|   760k|            dst->speaker[dst->num] = n;
  288|   760k|            dst->num++;
  289|   760k|        }
  290|  47.5M|    }
  291|   742k|}
mp_chmap_is_lavc:
  294|  1.53k|{
  295|  1.53k|    if (!mp_chmap_is_valid(src))
  ------------------
  |  Branch (295:9): [True: 223, False: 1.30k]
  ------------------
  296|    223|        return false;
  297|  1.30k|    if (mp_chmap_is_unknown(src))
  ------------------
  |  Branch (297:9): [True: 0, False: 1.30k]
  ------------------
  298|      0|        return true;
  299|       |    // lavc's channel layout is a bit mask, and channels are always ordered
  300|       |    // from LSB to MSB speaker bits, so speaker IDs have to increase.
  301|  1.30k|    mp_assert(src->num > 0);
  ------------------
  |  |   41|  1.30k|#define mp_assert assert
  ------------------
  302|  2.16k|    for (int n = 1; n < src->num; n++) {
  ------------------
  |  Branch (302:21): [True: 858, False: 1.30k]
  ------------------
  303|    858|        if (src->speaker[n - 1] >= src->speaker[n])
  ------------------
  |  Branch (303:13): [True: 0, False: 858]
  ------------------
  304|      0|            return false;
  305|    858|    }
  306|  3.47k|    for (int n = 0; n < src->num; n++) {
  ------------------
  |  Branch (306:21): [True: 2.16k, False: 1.30k]
  ------------------
  307|  2.16k|        if (src->speaker[n] >= 64)
  ------------------
  |  Branch (307:13): [True: 0, False: 2.16k]
  ------------------
  308|      0|            return false;
  309|  2.16k|    }
  310|  1.30k|    return true;
  311|  1.30k|}
mp_chmap_to_str_buf:
  368|  16.3k|{
  369|  16.3k|    buf[0] = '\0';
  370|       |
  371|  16.3k|    if (mp_chmap_is_unknown(src)) {
  ------------------
  |  Branch (371:9): [True: 308, False: 15.9k]
  ------------------
  372|    308|        snprintf(buf, buf_size, "unknown%d", src->num);
  373|    308|        return buf;
  374|    308|    }
  375|       |
  376|  42.0k|    for (int n = 0; n < src->num; n++) {
  ------------------
  |  Branch (376:21): [True: 26.0k, False: 15.9k]
  ------------------
  377|  26.0k|        int sp = src->speaker[n];
  378|  26.0k|        const char *s = sp < MP_SPEAKER_ID_COUNT ? speaker_names[sp][0] : NULL;
  ------------------
  |  Branch (378:25): [True: 26.0k, False: 0]
  ------------------
  379|  26.0k|        char sp_buf[10];
  380|  26.0k|        if (!s) {
  ------------------
  |  Branch (380:13): [True: 0, False: 26.0k]
  ------------------
  381|      0|            snprintf(sp_buf, sizeof(sp_buf), "sp%d", sp);
  382|      0|            s = sp_buf;
  383|      0|        }
  384|  26.0k|        mp_snprintf_cat(buf, buf_size, "%s%s", n > 0 ? "-" : "", s);
  ------------------
  |  Branch (384:48): [True: 10.2k, False: 15.7k]
  ------------------
  385|  26.0k|    }
  386|       |
  387|       |    // To standard layout name
  388|  75.2k|    for (int n = 0; std_layout_names[n][0]; n++) {
  ------------------
  |  Branch (388:21): [True: 74.7k, False: 588]
  ------------------
  389|  74.7k|        if (strcmp(buf, std_layout_names[n][1]) == 0) {
  ------------------
  |  Branch (389:13): [True: 15.4k, False: 59.3k]
  ------------------
  390|  15.4k|            snprintf(buf, buf_size, "%s", std_layout_names[n][0]);
  391|  15.4k|            break;
  392|  15.4k|        }
  393|  74.7k|    }
  394|       |
  395|  15.9k|    return buf;
  396|  16.3k|}
mp_chmap_from_str:
  403|  31.4k|{
  404|       |    // Single number corresponds to mp_chmap_from_channels()
  405|  31.4k|    if (src.len > 0) {
  ------------------
  |  Branch (405:9): [True: 31.4k, False: 0]
  ------------------
  406|  31.4k|        bstr t = src;
  407|  31.4k|        bool unknown = bstr_eatstart0(&t, "unknown");
  408|  31.4k|        bstr rest;
  409|  31.4k|        long long count = bstrtoll(t, &rest, 10);
  410|  31.4k|        if (rest.len == 0) {
  ------------------
  |  Branch (410:13): [True: 0, False: 31.4k]
  ------------------
  411|      0|            struct mp_chmap res;
  412|      0|            if (unknown) {
  ------------------
  |  Branch (412:17): [True: 0, False: 0]
  ------------------
  413|      0|                mp_chmap_set_unknown(&res, count);
  414|      0|            } else {
  415|      0|                mp_chmap_from_channels(&res, count);
  416|      0|            }
  417|      0|            if (mp_chmap_is_valid(&res)) {
  ------------------
  |  Branch (417:17): [True: 0, False: 0]
  ------------------
  418|      0|                *dst = res;
  419|      0|                return true;
  420|      0|            }
  421|      0|        }
  422|  31.4k|    }
  423|       |
  424|       |    // From standard layout name
  425|   290k|    for (int n = 0; std_layout_names[n][0]; n++) {
  ------------------
  |  Branch (425:21): [True: 290k, False: 0]
  ------------------
  426|   290k|        if (bstr_equals0(src, std_layout_names[n][0])) {
  ------------------
  |  Branch (426:13): [True: 31.4k, False: 259k]
  ------------------
  427|  31.4k|            src = bstr0(std_layout_names[n][1]);
  428|  31.4k|            break;
  429|  31.4k|        }
  430|   290k|    }
  431|       |
  432|       |    // Explicit speaker list (separated by "-")
  433|  31.4k|    struct mp_chmap res = {0};
  434|   114k|    while (src.len) {
  ------------------
  |  Branch (434:12): [True: 83.2k, False: 31.4k]
  ------------------
  435|  83.2k|        bstr s;
  436|  83.2k|        bstr_split_tok(src, "-", &s, &src);
  437|  83.2k|        int speaker = -1;
  438|   487k|        for (int n = 0; n < MP_SPEAKER_ID_COUNT; n++) {
  ------------------
  |  Branch (438:25): [True: 487k, False: 0]
  ------------------
  439|   487k|            const char *name = speaker_names[n][0];
  440|   487k|            if (name && bstr_equals0(s, name)) {
  ------------------
  |  Branch (440:17): [True: 454k, False: 32.9k]
  |  Branch (440:25): [True: 83.2k, False: 371k]
  ------------------
  441|  83.2k|                speaker = n;
  442|  83.2k|                break;
  443|  83.2k|            }
  444|   487k|        }
  445|  83.2k|        if (speaker < 0) {
  ------------------
  |  Branch (445:13): [True: 0, False: 83.2k]
  ------------------
  446|      0|            if (bstr_eatstart0(&s, "sp")) {
  ------------------
  |  Branch (446:17): [True: 0, False: 0]
  ------------------
  447|      0|                long long sp = bstrtoll(s, &s, 0);
  448|      0|                if (s.len == 0 && sp >= 0 && sp < MP_SPEAKER_ID_COUNT)
  ------------------
  |  Branch (448:21): [True: 0, False: 0]
  |  Branch (448:35): [True: 0, False: 0]
  |  Branch (448:46): [True: 0, False: 0]
  ------------------
  449|      0|                    speaker = sp;
  450|      0|            }
  451|      0|            if (speaker < 0)
  ------------------
  |  Branch (451:17): [True: 0, False: 0]
  ------------------
  452|      0|                return false;
  453|      0|        }
  454|  83.2k|        if (res.num >= MP_NUM_CHANNELS)
  ------------------
  |  |   25|  83.2k|#define MP_NUM_CHANNELS 64
  ------------------
  |  Branch (454:13): [True: 0, False: 83.2k]
  ------------------
  455|      0|            return false;
  456|  83.2k|        res.speaker[res.num] = speaker;
  457|  83.2k|        res.num++;
  458|  83.2k|    }
  459|       |
  460|  31.4k|    *dst = res;
  461|  31.4k|    return true;
  462|  31.4k|}
mp_chmap_to_str_hr_buf:
  468|  6.80k|{
  469|  6.80k|    struct mp_chmap map = *src;
  470|  6.80k|    mp_chmap_remove_na(&map);
  471|  31.6k|    for (int n = 0; std_layout_names[n][0]; n++) {
  ------------------
  |  Branch (471:21): [True: 31.4k, False: 249]
  ------------------
  472|  31.4k|        struct mp_chmap s;
  473|  31.4k|        if (mp_chmap_from_str(&s, bstr0(std_layout_names[n][0])) &&
  ------------------
  |  Branch (473:13): [True: 31.4k, False: 0]
  ------------------
  474|  31.4k|            mp_chmap_equals_reordered(&s, &map))
  ------------------
  |  Branch (474:13): [True: 6.55k, False: 24.8k]
  ------------------
  475|  6.55k|        {
  476|  6.55k|            map = s;
  477|  6.55k|            break;
  478|  6.55k|        }
  479|  31.4k|    }
  480|  6.80k|    return mp_chmap_to_str_buf(buf, buf_size, &map);
  481|  6.80k|}
chmap.c:comp_uint8:
  182|   152k|{
  183|   152k|    return *(const uint8_t *)a - *(const uint8_t *)b;
  184|   152k|}

mp_chmap_from_av_layout:
   24|   765k|{
   25|   765k|    *dst = (struct mp_chmap) {0};
   26|       |
   27|   765k|    switch (src->order) {
   28|  23.1k|    case AV_CHANNEL_ORDER_UNSPEC:
  ------------------
  |  Branch (28:5): [True: 23.1k, False: 742k]
  ------------------
   29|  23.1k|        mp_chmap_from_channels(dst, src->nb_channels);
   30|  23.1k|        return dst->num == src->nb_channels;
   31|   742k|    case AV_CHANNEL_ORDER_NATIVE:
  ------------------
  |  Branch (31:5): [True: 742k, False: 23.1k]
  ------------------
   32|   742k|        mp_chmap_from_lavc(dst, src->u.mask);
   33|   742k|        return dst->num == src->nb_channels;
   34|      0|    default:
  ------------------
  |  Branch (34:5): [True: 0, False: 765k]
  ------------------
   35|       |        // TODO: handle custom layouts
   36|      0|        return false;
   37|   765k|    }
   38|   765k|}
mp_chmap_to_av_layout:
   41|  1.57k|{
   42|  1.57k|    *dst = (AVChannelLayout){
   43|  1.57k|        .order = AV_CHANNEL_ORDER_UNSPEC,
   44|  1.57k|        .nb_channels = src->num,
   45|  1.57k|    };
   46|       |
   47|       |    // TODO: handle custom layouts
   48|  1.57k|    if (!mp_chmap_is_unknown(src)) {
  ------------------
  |  Branch (48:9): [True: 1.53k, False: 44]
  ------------------
   49|  1.53k|        av_channel_layout_from_mask(dst, mp_chmap_to_lavc(src));
   50|  1.53k|    }
   51|  1.57k|}

mp_chmap_sel_add_any:
   88|  1.35k|{
   89|  1.35k|    s->allow_any = true;
   90|  1.35k|}
mp_chmap_sel_add_map:
  100|  1.36k|{
  101|  1.36k|    if (!mp_chmap_is_valid(map))
  ------------------
  |  Branch (101:9): [True: 0, False: 1.36k]
  ------------------
  102|      0|        return;
  103|  1.36k|    if (!s->chmaps)
  ------------------
  |  Branch (103:9): [True: 1.36k, False: 0]
  ------------------
  104|  1.36k|        s->chmaps = s->chmaps_storage;
  105|  1.36k|    if (s->num_chmaps == MP_ARRAY_SIZE(s->chmaps_storage)) {
  ------------------
  |  |   48|  1.36k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (105:9): [True: 0, False: 1.36k]
  ------------------
  106|      0|        if (!s->tmp)
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return;
  108|      0|        s->chmaps = talloc_memdup(s->tmp, s->chmaps, sizeof(s->chmaps_storage));
  ------------------
  |  |   49|      0|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|      0|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  109|      0|    }
  110|  1.36k|    if (s->chmaps != s->chmaps_storage)
  ------------------
  |  Branch (110:9): [True: 0, False: 1.36k]
  ------------------
  111|      0|        MP_TARRAY_GROW(s->tmp, s->chmaps, s->num_chmaps);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  112|  1.36k|    s->chmaps[s->num_chmaps++] = *map;
  113|  1.36k|}
mp_chmap_sel_adjust:
  182|  2.71k|{
  183|  2.71k|    if (test_layout(s, map))
  ------------------
  |  Branch (183:9): [True: 2.71k, False: 0]
  ------------------
  184|  2.71k|        return true;
  185|      0|    if (mp_chmap_is_unknown(map)) {
  ------------------
  |  Branch (185:9): [True: 0, False: 0]
  ------------------
  186|      0|        struct mp_chmap t = {0};
  187|      0|        if (mp_chmap_sel_get_def(s, &t, map->num) && test_layout(s, &t)) {
  ------------------
  |  Branch (187:13): [True: 0, False: 0]
  |  Branch (187:54): [True: 0, False: 0]
  ------------------
  188|      0|            *map = t;
  189|      0|            return true;
  190|      0|        }
  191|      0|    }
  192|       |
  193|      0|    if (mp_chmap_sel_fallback(s, map))
  ------------------
  |  Branch (193:9): [True: 0, False: 0]
  ------------------
  194|      0|        return true;
  195|       |
  196|      0|    for (int i = 0; i < MP_ARRAY_SIZE(speaker_replacements); i++) {
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (196:21): [True: 0, False: 0]
  ------------------
  197|      0|        struct mp_chmap  t = *map;
  198|      0|        struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
  199|      0|        if (replace_speakers(&t, r) && test_layout(s, &t)) {
  ------------------
  |  Branch (199:13): [True: 0, False: 0]
  |  Branch (199:40): [True: 0, False: 0]
  ------------------
  200|      0|            *map = t;
  201|      0|            return true;
  202|      0|        }
  203|      0|    }
  204|       |
  205|       |    // Fallback to mono/stereo as last resort
  206|      0|    *map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
  ------------------
  |  |  103|      0|#define MP_CHMAP_INIT_STEREO MP_CHMAP2(FL, FR)
  |  |  ------------------
  |  |  |  |   88|      0|    {2, {MP_SP(a), MP_SP(b)}}
  |  |  |  |  ------------------
  |  |  |  |  |  |   85|      0|#define MP_SP(speaker) MP_SPEAKER_ID_ ## speaker
  |  |  |  |  ------------------
  |  |  |  |                   {2, {MP_SP(a), MP_SP(b)}}
  |  |  |  |  ------------------
  |  |  |  |  |  |   85|      0|#define MP_SP(speaker) MP_SPEAKER_ID_ ## speaker
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  207|      0|    if (test_layout(s, map))
  ------------------
  |  Branch (207:9): [True: 0, False: 0]
  ------------------
  208|      0|        return true;
  209|      0|    *map = (struct mp_chmap) MP_CHMAP_INIT_MONO;
  ------------------
  |  |  102|      0|#define MP_CHMAP_INIT_MONO {1, {MP_SPEAKER_ID_FC}}
  ------------------
  210|      0|    if (test_layout(s, map))
  ------------------
  |  Branch (210:9): [True: 0, False: 0]
  ------------------
  211|      0|        return true;
  212|      0|    *map = (struct mp_chmap) {0};
  213|      0|    return false;
  214|      0|}
mp_chmap_sel_fallback:
  309|  1.35k|{
  310|  1.35k|    struct mp_chmap best = {0};
  311|       |
  312|  1.35k|    for (int n = 0; n < s->num_chmaps; n++) {
  ------------------
  |  Branch (312:21): [True: 0, False: 1.35k]
  ------------------
  313|      0|        struct mp_chmap e = s->chmaps[n];
  314|       |
  315|      0|        if (mp_chmap_is_unknown(&e))
  ------------------
  |  Branch (315:13): [True: 0, False: 0]
  ------------------
  316|      0|            continue;
  317|       |
  318|      0|        if (mp_chmap_is_better(map, &best, &e))
  ------------------
  |  Branch (318:13): [True: 0, False: 0]
  ------------------
  319|      0|            best = e;
  320|      0|    }
  321|       |
  322|  1.35k|    if (best.num) {
  ------------------
  |  Branch (322:9): [True: 0, False: 1.35k]
  ------------------
  323|      0|        *map = best;
  324|      0|        return true;
  325|      0|    }
  326|       |
  327|  1.35k|    return false;
  328|  1.35k|}
mp_chmal_sel_log:
  359|  1.35k|{
  360|  1.35k|    if (!mp_msg_test(log, lev))
  ------------------
  |  Branch (360:9): [True: 0, False: 1.35k]
  ------------------
  361|      0|        return;
  362|       |
  363|  1.35k|    for (int i = 0; i < s->num_chmaps; i++)
  ------------------
  |  Branch (363:21): [True: 0, False: 1.35k]
  ------------------
  364|      0|        mp_msg(log, lev, " - %s\n", mp_chmap_to_str(&s->chmaps[i]));
  ------------------
  |  |  133|      0|#define mp_chmap_to_str(m) mp_chmap_to_str_(m, MP_NUM_CHANNELS * 4)
  |  |  ------------------
  |  |  |  |  132|      0|#define mp_chmap_to_str_(m, sz) mp_chmap_to_str_buf((char[sz]){0}, sz, (m))
  |  |  ------------------
  ------------------
  365|  89.1k|    for (int i = 0; i < MP_SPEAKER_ID_COUNT; i++) {
  ------------------
  |  Branch (365:21): [True: 87.8k, False: 1.35k]
  ------------------
  366|  87.8k|        if (!s->speakers[i])
  ------------------
  |  Branch (366:13): [True: 87.8k, False: 0]
  ------------------
  367|  87.8k|            continue;
  368|      0|        struct mp_chmap l = {.num = 1, .speaker = { i }};
  369|      0|        mp_msg(log, lev, " - #%s\n",
  370|      0|                    i == MP_SPEAKER_ID_FC ? "fc" : mp_chmap_to_str_hr(&l));
  ------------------
  |  |  137|      0|#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_(m, MP_NUM_CHANNELS * 4)
  |  |  ------------------
  |  |  |  |  136|      0|#define mp_chmap_to_str_hr_(m, sz) mp_chmap_to_str_hr_buf((char[sz]){0}, sz, (m))
  |  |  ------------------
  ------------------
  |  Branch (370:21): [True: 0, False: 0]
  ------------------
  371|      0|    }
  372|  1.35k|    if (s->allow_waveext)
  ------------------
  |  Branch (372:9): [True: 0, False: 1.35k]
  ------------------
  373|      0|        mp_msg(log, lev, " - waveext\n");
  374|  1.35k|    if (s->allow_any)
  ------------------
  |  Branch (374:9): [True: 1.35k, False: 0]
  ------------------
  375|  1.35k|        mp_msg(log, lev, " - anything\n");
  376|  1.35k|}
mp_chmap_sel_list:
  381|  1.35k|{
  382|       |    // This is a separate function to keep messing with mp_chmap_sel internals
  383|       |    // within this source file.
  384|  1.35k|    struct mp_chmap_sel sel = {
  385|  1.35k|        .chmaps = maps,
  386|  1.35k|        .num_chmaps = num_maps,
  387|  1.35k|    };
  388|  1.35k|    mp_chmap_sel_fallback(&sel, c);
  389|  1.35k|}
chmap_sel.c:test_layout:
  167|  2.71k|{
  168|  2.71k|    if (!mp_chmap_is_valid(map))
  ------------------
  |  Branch (168:9): [True: 0, False: 2.71k]
  ------------------
  169|      0|        return false;
  170|       |
  171|  2.71k|    return s->allow_any || test_waveext(s, map) || test_speakers(s, map) ||
  ------------------
  |  Branch (171:12): [True: 1.35k, False: 1.36k]
  |  Branch (171:28): [True: 0, False: 1.36k]
  |  Branch (171:52): [True: 0, False: 1.36k]
  ------------------
  172|  2.71k|           test_maps(s, map);
  ------------------
  |  Branch (172:12): [True: 1.36k, False: 0]
  ------------------
  173|  2.71k|}
chmap_sel.c:test_waveext:
  154|  1.36k|{
  155|  1.36k|    if (s->allow_waveext) {
  ------------------
  |  Branch (155:9): [True: 0, False: 1.36k]
  ------------------
  156|      0|        struct mp_chmap t = *map;
  157|      0|        mp_chmap_reorder_to_waveext(&t);
  ------------------
  |  |  161|      0|#define mp_chmap_reorder_to_waveext mp_chmap_reorder_to_lavc
  ------------------
  158|      0|        if (mp_chmap_is_waveext(&t)) {
  ------------------
  |  |  160|      0|#define mp_chmap_is_waveext mp_chmap_is_lavc
  ------------------
  |  Branch (158:13): [True: 0, False: 0]
  ------------------
  159|      0|            *map = t;
  160|      0|            return true;
  161|      0|        }
  162|      0|    }
  163|  1.36k|    return false;
  164|  1.36k|}
chmap_sel.c:test_speakers:
  134|  1.36k|{
  135|  1.36k|    for (int n = 0; n < map->num; n++) {
  ------------------
  |  Branch (135:21): [True: 1.36k, False: 0]
  ------------------
  136|  1.36k|        if (!s->speakers[map->speaker[n]])
  ------------------
  |  Branch (136:13): [True: 1.36k, False: 0]
  ------------------
  137|  1.36k|            return false;
  138|  1.36k|    }
  139|      0|    return true;
  140|  1.36k|}
chmap_sel.c:test_maps:
  143|  1.36k|{
  144|  1.36k|    for (int n = 0; n < s->num_chmaps; n++) {
  ------------------
  |  Branch (144:21): [True: 1.36k, False: 0]
  ------------------
  145|  1.36k|        if (mp_chmap_equals_reordered(&s->chmaps[n], map)) {
  ------------------
  |  Branch (145:13): [True: 1.36k, False: 0]
  ------------------
  146|  1.36k|            *map = s->chmaps[n];
  147|  1.36k|            return true;
  148|  1.36k|        }
  149|  1.36k|    }
  150|      0|    return false;
  151|  1.36k|}

ad_lavc.c:create:
  295|  1.94k|{
  296|  1.94k|    struct mp_filter *da = mp_filter_create(parent, &ad_lavc_filter);
  297|  1.94k|    if (!da)
  ------------------
  |  Branch (297:9): [True: 0, False: 1.94k]
  ------------------
  298|      0|        return NULL;
  299|       |
  300|  1.94k|    mp_filter_add_pin(da, MP_PIN_IN, "in");
  301|  1.94k|    mp_filter_add_pin(da, MP_PIN_OUT, "out");
  302|       |
  303|  1.94k|    da->log = mp_log_new(da, parent->log, NULL);
  304|       |
  305|  1.94k|    struct priv *priv = da->priv;
  306|  1.94k|    priv->codec = codec;
  307|  1.94k|    priv->public.f = da;
  308|       |
  309|  1.94k|    if (!init(da, codec, decoder)) {
  ------------------
  |  Branch (309:9): [True: 125, False: 1.81k]
  ------------------
  310|    125|        talloc_free(da);
  ------------------
  |  |   47|    125|#define talloc_free                     ta_free
  ------------------
  311|    125|        return NULL;
  312|    125|    }
  313|       |
  314|  1.81k|    codec->codec_desc = priv->avctx->codec_descriptor->long_name;
  315|  1.81k|    mp_chmap_from_av_layout(&priv->codec->channels, &priv->avctx->ch_layout);
  316|       |
  317|  1.81k|    return &priv->public;
  318|  1.94k|}
ad_lavc.c:ad_lavc_destroy:
  155|  1.94k|{
  156|  1.94k|    struct priv *ctx = da->priv;
  157|       |
  158|  1.94k|    avcodec_free_context(&ctx->avctx);
  159|  1.94k|    av_frame_free(&ctx->avframe);
  160|  1.94k|    mp_free_av_packet(&ctx->avpkt);
  161|  1.94k|}
ad_lavc.c:ad_lavc_process:
  278|  2.66M|{
  279|  2.66M|    struct priv *priv = ad->priv;
  280|       |
  281|  2.66M|    lavc_process(ad, &priv->state, send_packet, receive_frame);
  282|  2.66M|}
ad_lavc.c:send_packet:
  176|  1.14M|{
  177|  1.14M|    struct priv *priv = da->priv;
  178|  1.14M|    AVCodecContext *avctx = priv->avctx;
  179|       |
  180|       |    // If the decoder discards the timestamp for some reason, we use the
  181|       |    // interpolated PTS. Initialize it so that it works for the initial
  182|       |    // packet as well.
  183|  1.14M|    if (mpkt && priv->next_pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.13M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (183:9): [True: 1.13M, False: 836]
  |  Branch (183:17): [True: 6.17k, False: 1.13M]
  ------------------
  184|  6.17k|        priv->next_pts = mpkt->pts;
  185|       |
  186|  1.14M|    mp_set_av_packet(priv->avpkt, mpkt, &priv->codec_timebase);
  187|       |
  188|  1.14M|    int ret = avcodec_send_packet(avctx, mpkt ? priv->avpkt : NULL);
  ------------------
  |  Branch (188:42): [True: 1.13M, False: 836]
  ------------------
  189|  1.14M|    if (ret < 0)
  ------------------
  |  Branch (189:9): [True: 765k, False: 374k]
  ------------------
  190|  1.14M|        MP_ERR(da, "Error decoding audio.\n");
  ------------------
  |  |   85|   765k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   765k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  191|  1.14M|    return ret;
  192|  1.14M|}
ad_lavc.c:receive_frame:
  195|  2.66M|{
  196|  2.66M|    struct priv *priv = da->priv;
  197|  2.66M|    AVCodecContext *avctx = priv->avctx;
  198|       |
  199|  2.66M|    int ret = avcodec_receive_frame(avctx, priv->avframe);
  200|       |
  201|  2.66M|    if (ret == AVERROR_EOF) {
  ------------------
  |  Branch (201:9): [True: 836, False: 2.66M]
  ------------------
  202|       |        // If flushing was initialized earlier and has ended now, make it start
  203|       |        // over in case we get new packets at some point in the future.
  204|       |        // (Don't reset the filter itself, we want to keep other state.)
  205|    836|        avcodec_flush_buffers(priv->avctx);
  206|    836|        return ret;
  207|  2.66M|    } else if (ret < 0 && ret != AVERROR(EAGAIN)) {
  ------------------
  |  Branch (207:16): [True: 2.28M, False: 373k]
  |  Branch (207:27): [True: 4.28k, False: 2.28M]
  ------------------
  208|  4.28k|        MP_ERR(da, "Error decoding audio.\n");
  ------------------
  |  |   85|  4.28k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  4.28k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  209|  4.28k|    }
  210|       |
  211|  2.66M|    if (priv->avframe->flags & AV_FRAME_FLAG_DISCARD)
  ------------------
  |  Branch (211:9): [True: 0, False: 2.66M]
  ------------------
  212|      0|        av_frame_unref(priv->avframe);
  213|       |
  214|  2.66M|    if (!priv->avframe->buf[0])
  ------------------
  |  Branch (214:9): [True: 2.28M, False: 373k]
  ------------------
  215|  2.28M|        return ret;
  216|       |
  217|   373k|    mp_codec_info_from_av(avctx, priv->codec);
  218|   373k|    mp_chmap_from_av_layout(&priv->codec->channels, &avctx->ch_layout);
  219|       |
  220|   373k|    double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase);
  221|       |
  222|   373k|    struct mp_aframe *mpframe = mp_aframe_from_avframe(priv->avframe);
  223|   373k|    if (!mpframe) {
  ------------------
  |  Branch (223:9): [True: 0, False: 373k]
  ------------------
  224|      0|        MP_ERR(da, "Converting libavcodec frame to mpv frame failed.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  225|      0|        return ret;
  226|      0|    }
  227|       |
  228|   373k|    if (priv->force_channel_map.num)
  ------------------
  |  Branch (228:9): [True: 0, False: 373k]
  ------------------
  229|      0|        mp_aframe_set_chmap(mpframe, &priv->force_channel_map);
  230|       |
  231|   373k|    if (out_pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (231:9): [True: 147, False: 373k]
  ------------------
  232|    147|        out_pts = priv->next_pts;
  233|   373k|    mp_aframe_set_pts(mpframe, out_pts);
  234|       |
  235|   373k|    priv->next_pts = mp_aframe_end_pts(mpframe);
  236|       |
  237|   373k|    AVFrameSideData *sd =
  238|   373k|        av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
  239|   373k|    if (sd && sd->size >= 10) {
  ------------------
  |  Branch (239:9): [True: 0, False: 373k]
  |  Branch (239:15): [True: 0, False: 0]
  ------------------
  240|      0|        char *d = sd->data;
  241|      0|        priv->skip_samples += AV_RL32(d + 0);
  242|      0|        priv->trim_samples += AV_RL32(d + 4);
  243|      0|    }
  244|       |
  245|   373k|    if (!priv->preroll_done) {
  ------------------
  |  Branch (245:9): [True: 735, False: 372k]
  ------------------
  246|       |        // Skip only if this isn't already handled by AV_FRAME_DATA_SKIP_SAMPLES.
  247|    735|        if (!priv->skip_samples)
  ------------------
  |  Branch (247:13): [True: 735, False: 0]
  ------------------
  248|    735|            priv->skip_samples = avctx->delay;
  249|    735|        priv->preroll_done = true;
  250|    735|    }
  251|       |
  252|   373k|    uint32_t skip = MPMIN(priv->skip_samples, mp_aframe_get_size(mpframe));
  ------------------
  |  |   44|   373k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 373k]
  |  |  ------------------
  ------------------
  253|   373k|    if (skip) {
  ------------------
  |  Branch (253:9): [True: 0, False: 373k]
  ------------------
  254|      0|        mp_aframe_skip_samples(mpframe, skip);
  255|      0|        priv->skip_samples -= skip;
  256|      0|    }
  257|   373k|    uint32_t trim = MPMIN(priv->trim_samples, mp_aframe_get_size(mpframe));
  ------------------
  |  |   44|   373k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 373k]
  |  |  ------------------
  ------------------
  258|   373k|    if (trim) {
  ------------------
  |  Branch (258:9): [True: 0, False: 373k]
  ------------------
  259|      0|        mp_aframe_set_size(mpframe, mp_aframe_get_size(mpframe) - trim);
  260|      0|        priv->trim_samples -= trim;
  261|      0|    }
  262|       |
  263|       |    // Strip possibly bogus float values like Infinity, NaN, denormalized
  264|   373k|    mp_aframe_sanitize_float(mpframe);
  265|       |
  266|   373k|    if (mp_aframe_get_size(mpframe) > 0) {
  ------------------
  |  Branch (266:9): [True: 373k, False: 0]
  ------------------
  267|   373k|        *out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
  ------------------
  |  |   57|   373k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  ------------------
  268|   373k|    } else {
  269|      0|        talloc_free(mpframe);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  270|      0|    }
  271|       |
  272|   373k|    av_frame_unref(priv->avframe);
  273|       |
  274|   373k|    return ret;
  275|   373k|}
ad_lavc.c:ad_lavc_reset:
  164|      2|{
  165|      2|    struct priv *ctx = da->priv;
  166|       |
  167|      2|    avcodec_flush_buffers(ctx->avctx);
  168|      2|    ctx->skip_samples = 0;
  169|      2|    ctx->trim_samples = 0;
  170|      2|    ctx->preroll_done = false;
  171|      2|    ctx->next_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|      2|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  172|      2|    ctx->state = (struct lavc_state){0};
  173|      2|}
ad_lavc.c:init:
   85|  1.94k|{
   86|  1.94k|    struct priv *ctx = da->priv;
   87|  1.94k|    struct MPOpts *mpopts = mp_get_config_group(ctx, da->global, &mp_opt_root);
   88|  1.94k|    struct ad_lavc_params *opts =
   89|  1.94k|        mp_get_config_group(ctx, da->global, &ad_lavc_conf);
   90|  1.94k|    const AVCodec *lavc_codec;
   91|       |
   92|  1.94k|    ctx->codec_timebase = mp_get_codec_timebase(codec);
   93|       |
   94|  1.94k|    if (codec->force_channels)
  ------------------
  |  Branch (94:9): [True: 0, False: 1.94k]
  ------------------
   95|      0|        ctx->force_channel_map = codec->channels;
   96|       |
   97|  1.94k|    lavc_codec = avcodec_find_decoder_by_name(decoder);
   98|  1.94k|    if (!lavc_codec) {
  ------------------
  |  Branch (98:9): [True: 0, False: 1.94k]
  ------------------
   99|      0|        MP_ERR(da, "Cannot find codec '%s' in libavcodec...\n", decoder);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  100|      0|        return false;
  101|      0|    }
  102|       |
  103|  1.94k|    ctx->avctx = avcodec_alloc_context3(lavc_codec);
  104|  1.94k|    MP_HANDLE_OOM(ctx->avctx);
  ------------------
  |  |  176|  1.94k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  1.94k|        void *oom_p_ = (x);     \
  |  |  178|  1.94k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 1.94k]
  |  |  ------------------
  |  |  179|  1.94k|            abort();            \
  |  |  180|  1.94k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  105|  1.94k|    ctx->avframe = av_frame_alloc();
  106|  1.94k|    MP_HANDLE_OOM(ctx->avframe);
  ------------------
  |  |  176|  1.94k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  1.94k|        void *oom_p_ = (x);     \
  |  |  178|  1.94k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 1.94k]
  |  |  ------------------
  |  |  179|  1.94k|            abort();            \
  |  |  180|  1.94k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  107|  1.94k|    ctx->avpkt = av_packet_alloc();
  108|  1.94k|    MP_HANDLE_OOM(ctx->avpkt);
  ------------------
  |  |  176|  1.94k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  1.94k|        void *oom_p_ = (x);     \
  |  |  178|  1.94k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 1.94k]
  |  |  ------------------
  |  |  179|  1.94k|            abort();            \
  |  |  180|  1.94k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  109|  1.94k|    ctx->avctx->codec_type = AVMEDIA_TYPE_AUDIO;
  110|  1.94k|    ctx->avctx->codec_id = lavc_codec->id;
  111|  1.94k|    ctx->avctx->pkt_timebase = ctx->codec_timebase;
  112|       |
  113|  1.94k|    if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) {
  ------------------
  |  Branch (113:9): [True: 0, False: 1.94k]
  |  Branch (113:26): [True: 0, False: 0]
  ------------------
  114|      0|        const struct mp_chmap *requested_layout =
  115|      0|            &mpopts->audio_output_channels.chmaps[0];
  116|      0|        AVChannelLayout av_layout = { 0 };
  117|      0|        mp_chmap_to_av_layout(&av_layout, requested_layout);
  118|       |
  119|       |        // Always try to set requested output layout - currently only something
  120|       |        // supported by AC3, MLP/TrueHD, DTS and the fdk-aac wrapper.
  121|      0|        av_opt_set_chlayout(ctx->avctx, "downmix", &av_layout,
  122|      0|                            AV_OPT_SEARCH_CHILDREN);
  123|       |
  124|      0|        av_channel_layout_uninit(&av_layout);
  125|      0|    }
  126|       |
  127|       |    // Always try to set - option only exists for AC3 at the moment
  128|  1.94k|    av_opt_set_double(ctx->avctx, "drc_scale", opts->ac3drc,
  129|  1.94k|                      AV_OPT_SEARCH_CHILDREN);
  130|       |
  131|       |    // Let decoder add AV_FRAME_DATA_SKIP_SAMPLES.
  132|  1.94k|    av_opt_set(ctx->avctx, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN);
  133|       |
  134|  1.94k|    mp_set_avopts(da->log, ctx->avctx, opts->avopts);
  135|       |
  136|  1.94k|    if (mp_set_avctx_codec_headers(ctx->avctx, codec) < 0) {
  ------------------
  |  Branch (136:9): [True: 0, False: 1.94k]
  ------------------
  137|      0|        MP_ERR(da, "Could not set decoder parameters.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  138|      0|        return false;
  139|      0|    }
  140|       |
  141|  1.94k|    mp_set_avcodec_threads(da->log, ctx->avctx, opts->threads);
  142|       |
  143|       |    /* open it */
  144|  1.94k|    if (avcodec_open2(ctx->avctx, lavc_codec, NULL) < 0) {
  ------------------
  |  Branch (144:9): [True: 125, False: 1.81k]
  ------------------
  145|    125|        MP_ERR(da, "Could not open codec.\n");
  ------------------
  |  |   85|    125|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    125|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  146|    125|        return false;
  147|    125|    }
  148|       |
  149|  1.81k|    ctx->next_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.81k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  150|       |
  151|  1.81k|    return true;
  152|  1.94k|}
ad_lavc.c:add_decoders:
  321|  1.95k|{
  322|  1.95k|    mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO);
  323|  1.95k|}

select_spdif_codec:
  392|  1.95k|{
  393|  1.95k|    struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
  ------------------
  |  |   27|  1.95k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.95k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.95k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  394|       |
  395|  1.95k|    if (!find_codec(codec))
  ------------------
  |  Branch (395:9): [True: 1.94k, False: 5]
  ------------------
  396|  1.94k|        return list;
  397|       |
  398|      5|    bool spdif_allowed = false, dts_hd_allowed = false;
  399|      5|    bstr sel = bstr0(pref);
  400|      5|    while (sel.len) {
  ------------------
  |  Branch (400:12): [True: 0, False: 5]
  ------------------
  401|      0|        bstr decoder;
  402|      0|        bstr_split_tok(sel, ",", &decoder, &sel);
  403|      0|        if (decoder.len) {
  ------------------
  |  Branch (403:13): [True: 0, False: 0]
  ------------------
  404|      0|            if (bstr_equals0(decoder, codec))
  ------------------
  |  Branch (404:17): [True: 0, False: 0]
  ------------------
  405|      0|                spdif_allowed = true;
  406|      0|            if (bstr_equals0(decoder, "dts-hd") && strcmp(codec, "dts") == 0)
  ------------------
  |  Branch (406:17): [True: 0, False: 0]
  |  Branch (406:52): [True: 0, False: 0]
  ------------------
  407|      0|                spdif_allowed = dts_hd_allowed = true;
  408|      0|        }
  409|      0|    }
  410|       |
  411|      5|    if (!spdif_allowed)
  ------------------
  |  Branch (411:9): [True: 5, False: 0]
  ------------------
  412|      5|        return list;
  413|       |
  414|      0|    const char *suffix_name = dts_hd_allowed ? "dts_hd" : codec;
  ------------------
  |  Branch (414:31): [True: 0, False: 0]
  ------------------
  415|      0|    char name[80];
  416|      0|    snprintf(name, sizeof(name), "spdif_%s", suffix_name);
  417|      0|    mp_add_decoder(list, codec, name,
  418|      0|                   "libavformat/spdifenc audio pass-through decoder");
  419|      0|    return list;
  420|      5|}
ad_spdif.c:find_codec:
  379|  1.95k|{
  380|  13.6k|    for (int n = 0; codecs[n] != AV_CODEC_ID_NONE; n++) {
  ------------------
  |  Branch (380:21): [True: 11.7k, False: 1.94k]
  ------------------
  381|  11.7k|        const char *format = mp_codec_from_av_codec_id(codecs[n]);
  382|  11.7k|        if (format && name && strcmp(format, name) == 0)
  ------------------
  |  Branch (382:13): [True: 11.7k, False: 0]
  |  Branch (382:23): [True: 11.7k, False: 0]
  |  Branch (382:31): [True: 5, False: 11.7k]
  ------------------
  383|      5|            return true;
  384|  11.7k|    }
  385|  1.94k|    return false;
  386|  1.95k|}

af_to_avformat:
   45|  2.05k|{
   46|  16.5k|    for (int i = 0; audio_conversion_map[i].fmt; i++) {
  ------------------
  |  Branch (46:21): [True: 16.5k, False: 0]
  ------------------
   47|  16.5k|        if (audio_conversion_map[i].fmt == fmt)
  ------------------
  |  Branch (47:13): [True: 2.05k, False: 14.4k]
  ------------------
   48|  2.05k|            return audio_conversion_map[i].sample_fmt;
   49|  16.5k|    }
   50|      0|    return AV_SAMPLE_FMT_NONE;
   51|  2.05k|}
af_from_avformat:
   54|   373k|{
   55|  3.96M|    for (int i = 0; audio_conversion_map[i].fmt; i++) {
  ------------------
  |  Branch (55:21): [True: 3.96M, False: 0]
  ------------------
   56|  3.96M|        if (audio_conversion_map[i].sample_fmt == sample_fmt)
  ------------------
  |  Branch (56:13): [True: 373k, False: 3.58M]
  ------------------
   57|   373k|            return audio_conversion_map[i].fmt;
   58|  3.96M|    }
   59|      0|    return 0;
   60|   373k|}

af_fmt_to_bytes:
   27|  1.12M|{
   28|  1.12M|    switch (af_fmt_from_planar(format)) {
  ------------------
  |  Branch (28:13): [True: 16, False: 1.12M]
  ------------------
   29|      0|    case AF_FORMAT_U8:      return 1;
  ------------------
  |  Branch (29:5): [True: 0, False: 1.12M]
  ------------------
   30|  67.2k|    case AF_FORMAT_S16:     return 2;
  ------------------
  |  Branch (30:5): [True: 67.2k, False: 1.05M]
  ------------------
   31|      0|    case AF_FORMAT_S32:     return 4;
  ------------------
  |  Branch (31:5): [True: 0, False: 1.12M]
  ------------------
   32|      0|    case AF_FORMAT_S64:     return 8;
  ------------------
  |  Branch (32:5): [True: 0, False: 1.12M]
  ------------------
   33|  1.05M|    case AF_FORMAT_FLOAT:   return 4;
  ------------------
  |  Branch (33:5): [True: 1.05M, False: 67.2k]
  ------------------
   34|      0|    case AF_FORMAT_DOUBLE:  return 8;
  ------------------
  |  Branch (34:5): [True: 0, False: 1.12M]
  ------------------
   35|  1.12M|    }
   36|      0|    if (af_fmt_is_spdif(format))
  ------------------
  |  Branch (36:9): [True: 0, False: 0]
  ------------------
   37|      0|        return 2;
   38|      0|    return 0;
   39|      0|}
af_fmt_is_unsigned:
   43|   680k|{
   44|   680k|    return format == AF_FORMAT_U8 || format == AF_FORMAT_U8P;
  ------------------
  |  Branch (44:12): [True: 0, False: 680k]
  |  Branch (44:38): [True: 0, False: 680k]
  ------------------
   45|   680k|}
af_fmt_is_spdif:
   60|  5.47k|{
   61|  5.47k|    return af_format_sample_alignment(format) > 1;
   62|  5.47k|}
af_fmt_is_pcm:
   65|  2.77k|{
   66|  2.77k|    return af_fmt_is_valid(format) && !af_fmt_is_spdif(format);
  ------------------
  |  Branch (66:12): [True: 2.77k, False: 0]
  |  Branch (66:39): [True: 2.77k, False: 0]
  ------------------
   67|  2.77k|}
af_fmt_is_planar:
   79|  3.63M|{
   80|  18.1M|    for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
  ------------------
  |  |   48|  18.1M|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (80:21): [True: 18.0M, False: 104k]
  ------------------
   81|  18.0M|        if (planar_formats[n][0] == format)
  ------------------
  |  Branch (81:13): [True: 3.53M, False: 14.5M]
  ------------------
   82|  3.53M|            return true;
   83|  18.0M|    }
   84|   104k|    return false;
   85|  3.63M|}
af_fmt_from_planar:
  103|  1.49M|{
  104|  7.47M|    for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) {
  ------------------
  |  |   48|  7.47M|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (104:21): [True: 7.42M, False: 54.6k]
  ------------------
  105|  7.42M|        if (planar_formats[n][0] == format)
  ------------------
  |  Branch (105:13): [True: 1.43M, False: 5.98M]
  ------------------
  106|  1.43M|            return planar_formats[n][1];
  107|  7.42M|    }
  108|  54.6k|    return format;
  109|  1.49M|}
af_fmt_is_valid:
  112|  2.77k|{
  113|  2.77k|    return format > 0 && format < AF_FORMAT_COUNT;
  ------------------
  |  Branch (113:12): [True: 2.77k, False: 0]
  |  Branch (113:26): [True: 2.77k, False: 0]
  ------------------
  114|  2.77k|}
af_fmt_to_str:
  117|  8.15k|{
  118|  8.15k|    switch (format) {
  ------------------
  |  Branch (118:13): [True: 0, False: 8.15k]
  ------------------
  119|      0|    case AF_FORMAT_U8:          return "u8";
  ------------------
  |  Branch (119:5): [True: 0, False: 8.15k]
  ------------------
  120|  1.07k|    case AF_FORMAT_S16:         return "s16";
  ------------------
  |  Branch (120:5): [True: 1.07k, False: 7.07k]
  ------------------
  121|      0|    case AF_FORMAT_S32:         return "s32";
  ------------------
  |  Branch (121:5): [True: 0, False: 8.15k]
  ------------------
  122|      0|    case AF_FORMAT_S64:         return "s64";
  ------------------
  |  Branch (122:5): [True: 0, False: 8.15k]
  ------------------
  123|      0|    case AF_FORMAT_FLOAT:       return "float";
  ------------------
  |  Branch (123:5): [True: 0, False: 8.15k]
  ------------------
  124|      0|    case AF_FORMAT_DOUBLE:      return "double";
  ------------------
  |  Branch (124:5): [True: 0, False: 8.15k]
  ------------------
  125|      0|    case AF_FORMAT_U8P:         return "u8p";
  ------------------
  |  Branch (125:5): [True: 0, False: 8.15k]
  ------------------
  126|  4.84k|    case AF_FORMAT_S16P:        return "s16p";
  ------------------
  |  Branch (126:5): [True: 4.84k, False: 3.31k]
  ------------------
  127|      0|    case AF_FORMAT_S32P:        return "s32p";
  ------------------
  |  Branch (127:5): [True: 0, False: 8.15k]
  ------------------
  128|      0|    case AF_FORMAT_S64P:        return "s64p";
  ------------------
  |  Branch (128:5): [True: 0, False: 8.15k]
  ------------------
  129|  2.23k|    case AF_FORMAT_FLOATP:      return "floatp";
  ------------------
  |  Branch (129:5): [True: 2.23k, False: 5.91k]
  ------------------
  130|      0|    case AF_FORMAT_DOUBLEP:     return "doublep";
  ------------------
  |  Branch (130:5): [True: 0, False: 8.15k]
  ------------------
  131|      0|    case AF_FORMAT_S_AAC:       return "spdif-aac";
  ------------------
  |  Branch (131:5): [True: 0, False: 8.15k]
  ------------------
  132|      0|    case AF_FORMAT_S_AC3:       return "spdif-ac3";
  ------------------
  |  Branch (132:5): [True: 0, False: 8.15k]
  ------------------
  133|      0|    case AF_FORMAT_S_DTS:       return "spdif-dts";
  ------------------
  |  Branch (133:5): [True: 0, False: 8.15k]
  ------------------
  134|      0|    case AF_FORMAT_S_DTSHD:     return "spdif-dtshd";
  ------------------
  |  Branch (134:5): [True: 0, False: 8.15k]
  ------------------
  135|      0|    case AF_FORMAT_S_EAC3:      return "spdif-eac3";
  ------------------
  |  Branch (135:5): [True: 0, False: 8.15k]
  ------------------
  136|      0|    case AF_FORMAT_S_MP3:       return "spdif-mp3";
  ------------------
  |  Branch (136:5): [True: 0, False: 8.15k]
  ------------------
  137|      0|    case AF_FORMAT_S_TRUEHD:    return "spdif-truehd";
  ------------------
  |  Branch (137:5): [True: 0, False: 8.15k]
  ------------------
  138|  8.15k|    }
  139|      0|    return "??";
  140|  8.15k|}
af_fill_silence:
  143|   680k|{
  144|   680k|    memset(dst, af_fmt_is_unsigned(format) ? 0x80 : 0, bytes);
  ------------------
  |  Branch (144:17): [True: 0, False: 680k]
  ------------------
  145|   680k|}
af_format_conversion_score:
  152|  2.06k|{
  153|  2.06k|    if (dst_format == AF_FORMAT_UNKNOWN || src_format == AF_FORMAT_UNKNOWN)
  ------------------
  |  Branch (153:9): [True: 0, False: 2.06k]
  |  Branch (153:44): [True: 0, False: 2.06k]
  ------------------
  154|      0|        return INT_MIN;
  155|  2.06k|    if (dst_format == src_format)
  ------------------
  |  Branch (155:9): [True: 2.06k, False: 0]
  ------------------
  156|  2.06k|        return 1024;
  157|       |    // Can't be normally converted
  158|      0|    if (!af_fmt_is_pcm(dst_format) || !af_fmt_is_pcm(src_format))
  ------------------
  |  Branch (158:9): [True: 0, False: 0]
  |  Branch (158:39): [True: 0, False: 0]
  ------------------
  159|      0|        return INT_MIN;
  160|      0|    int score = 1024;
  161|      0|    if (af_fmt_is_planar(dst_format) != af_fmt_is_planar(src_format))
  ------------------
  |  Branch (161:9): [True: 0, False: 0]
  ------------------
  162|      0|        score -= 1;     // has to (de-)planarize
  163|      0|    if (af_fmt_is_float(dst_format) != af_fmt_is_float(src_format)) {
  ------------------
  |  Branch (163:9): [True: 0, False: 0]
  ------------------
  164|      0|        int dst_bytes = af_fmt_to_bytes(dst_format);
  165|      0|        if (af_fmt_is_float(dst_format)) {
  ------------------
  |  Branch (165:13): [True: 0, False: 0]
  ------------------
  166|       |            // For int->float, consider a lower bound on the precision difference.
  167|      0|            int bytes = (dst_bytes == 4 ? 3 : 6) - af_fmt_to_bytes(src_format);
  ------------------
  |  Branch (167:26): [True: 0, False: 0]
  ------------------
  168|      0|            if (bytes >= 0) {
  ------------------
  |  Branch (168:17): [True: 0, False: 0]
  ------------------
  169|      0|                score -= 8 * bytes;          // excess precision
  170|      0|            } else {
  171|      0|                score += 1024 * (bytes - 1); // precision is lost (i.e. s32 -> float)
  172|      0|            }
  173|      0|        } else {
  174|       |            // float->int is the worst case. Penalize heavily and
  175|       |            // prefer highest bit depth int.
  176|      0|            score -= 1048576 * (8 - dst_bytes);
  177|      0|        }
  178|      0|        score -= 512; // penalty for any float <-> int conversion
  179|      0|    } else {
  180|      0|        int bytes = af_fmt_to_bytes(dst_format) - af_fmt_to_bytes(src_format);
  181|      0|        if (bytes > 0) {
  ------------------
  |  Branch (181:13): [True: 0, False: 0]
  ------------------
  182|      0|            score -= 8 * bytes;          // has to add padding
  183|      0|        } else if (bytes < 0) {
  ------------------
  |  Branch (183:20): [True: 0, False: 0]
  ------------------
  184|      0|            score += 1024 * (bytes - 1); // has to reduce bit depth
  185|      0|        }
  186|      0|    }
  187|      0|    return score;
  188|      0|}
af_select_best_samplerate:
  228|  1.36k|{
  229|  1.36k|    if (!available)
  ------------------
  |  Branch (229:9): [True: 0, False: 1.36k]
  ------------------
  230|      0|        return -1;
  231|       |
  232|  1.36k|    int min_mult_rate = INT_MAX;
  233|  1.36k|    int max_rate      = INT_MIN;
  234|  1.36k|    for (int i = 0; available[i]; i++) {
  ------------------
  |  Branch (234:21): [True: 1.36k, False: 0]
  ------------------
  235|  1.36k|        if (available[i] == src_samplerate)
  ------------------
  |  Branch (235:13): [True: 1.36k, False: 0]
  ------------------
  236|  1.36k|            return available[i];
  237|       |
  238|      0|        if (!(available[i] % src_samplerate))
  ------------------
  |  Branch (238:13): [True: 0, False: 0]
  ------------------
  239|      0|            min_mult_rate = MPMIN(min_mult_rate, available[i]);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  240|       |
  241|      0|        max_rate = MPMAX(max_rate, available[i]);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  242|      0|    }
  243|       |
  244|      0|    if (min_mult_rate < INT_MAX)
  ------------------
  |  Branch (244:9): [True: 0, False: 0]
  ------------------
  245|      0|        return min_mult_rate;
  246|       |
  247|      0|    if (max_rate > INT_MIN)
  ------------------
  |  Branch (247:9): [True: 0, False: 0]
  ------------------
  248|      0|        return max_rate;
  249|       |
  250|      0|    return -1;
  251|      0|}
af_format_sample_alignment:
  256|  6.82k|{
  257|  6.82k|    switch (format) {
  258|      0|    case AF_FORMAT_S_AAC:       return 16384 / 4;
  ------------------
  |  Branch (258:5): [True: 0, False: 6.82k]
  ------------------
  259|      0|    case AF_FORMAT_S_AC3:       return 6144 / 4;
  ------------------
  |  Branch (259:5): [True: 0, False: 6.82k]
  ------------------
  260|      0|    case AF_FORMAT_S_DTSHD:     return 32768 / 16;
  ------------------
  |  Branch (260:5): [True: 0, False: 6.82k]
  ------------------
  261|      0|    case AF_FORMAT_S_DTS:       return 2048 / 4;
  ------------------
  |  Branch (261:5): [True: 0, False: 6.82k]
  ------------------
  262|      0|    case AF_FORMAT_S_EAC3:      return 24576 / 4;
  ------------------
  |  Branch (262:5): [True: 0, False: 6.82k]
  ------------------
  263|      0|    case AF_FORMAT_S_MP3:       return 4608 / 4;
  ------------------
  |  Branch (263:5): [True: 0, False: 6.82k]
  ------------------
  264|      0|    case AF_FORMAT_S_TRUEHD:    return 61440 / 16;
  ------------------
  |  Branch (264:5): [True: 0, False: 6.82k]
  ------------------
  265|  6.82k|    default:                    return 1;
  ------------------
  |  Branch (265:5): [True: 6.82k, False: 0]
  ------------------
  266|  6.82k|    }
  267|  6.82k|}

ao_init_best:
  289|  1.35k|{
  290|  1.35k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  1.35k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  1.35k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  291|  1.35k|    struct ao_opts *opts = mp_get_config_group(tmp, global, &ao_conf);
  292|  1.35k|    struct mp_log *log = mp_log_new(tmp, global->log, "ao");
  293|  1.35k|    struct ao *ao = NULL;
  294|  1.35k|    struct m_obj_settings *ao_list = NULL;
  295|  1.35k|    int ao_num = 0;
  296|       |
  297|  2.70k|    for (int n = 0; opts->audio_driver_list && opts->audio_driver_list[n].name; n++)
  ------------------
  |  Branch (297:21): [True: 2.70k, False: 0]
  |  Branch (297:48): [True: 1.35k, False: 1.35k]
  ------------------
  298|  1.35k|        MP_TARRAY_APPEND(tmp, ao_list, ao_num, opts->audio_driver_list[n]);
  ------------------
  |  |  105|  1.35k|    do {                                            \
  |  |  106|  1.35k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.35k|    do {                                            \
  |  |  |  |   97|  1.35k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.35k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.35k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.35k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 1.35k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.35k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  1.35k|    do {                                                        \
  |  |  |  |  |  |   89|  1.35k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  1.35k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  1.35k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  1.35k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  1.35k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  1.35k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  1.35k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.35k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.35k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.35k|        (idxvar)++;                                 \
  |  |  109|  1.35k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  299|       |
  300|  1.35k|    bool forced_dev = false;
  301|  1.35k|    char *pref_ao, *pref_dev;
  302|  1.35k|    split_ao_device(tmp, opts->audio_device, &pref_ao, &pref_dev);
  303|  1.35k|    if (!ao_num && pref_ao) {
  ------------------
  |  Branch (303:9): [True: 0, False: 1.35k]
  |  Branch (303:20): [True: 0, False: 0]
  ------------------
  304|       |        // Reuse the autoselection code
  305|      0|        MP_TARRAY_APPEND(tmp, ao_list, ao_num,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  306|      0|            (struct m_obj_settings){.name = pref_ao});
  307|      0|        forced_dev = true;
  308|      0|    }
  309|       |
  310|  1.35k|    bool autoprobe = ao_num == 0;
  311|       |
  312|       |    // Something like "--ao=a,b," means do autoprobing after a and b fail.
  313|  1.35k|    if (ao_num && strlen(ao_list[ao_num - 1].name) == 0) {
  ------------------
  |  Branch (313:9): [True: 1.35k, False: 0]
  |  Branch (313:19): [True: 0, False: 1.35k]
  ------------------
  314|      0|        ao_num -= 1;
  315|      0|        autoprobe = true;
  316|      0|    }
  317|       |
  318|  1.35k|    if (autoprobe) {
  ------------------
  |  Branch (318:9): [True: 0, False: 1.35k]
  ------------------
  319|      0|        for (int n = 0; n < MP_ARRAY_SIZE(audio_out_drivers); n++) {
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (319:25): [True: 0, False: 0]
  ------------------
  320|      0|            const struct ao_driver *driver = audio_out_drivers[n];
  321|      0|            if (driver == &audio_out_null)
  ------------------
  |  Branch (321:17): [True: 0, False: 0]
  ------------------
  322|      0|                break;
  323|      0|            MP_TARRAY_APPEND(tmp, ao_list, ao_num,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  324|      0|                (struct m_obj_settings){.name = (char *)driver->name});
  325|      0|        }
  326|      0|    }
  327|       |
  328|  1.35k|    if (init_flags & AO_INIT_NULL_FALLBACK) {
  ------------------
  |  Branch (328:9): [True: 0, False: 1.35k]
  ------------------
  329|      0|        MP_TARRAY_APPEND(tmp, ao_list, ao_num,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  330|      0|            (struct m_obj_settings){.name = "null"});
  331|      0|    }
  332|       |
  333|  1.35k|    for (int n = 0; n < ao_num; n++) {
  ------------------
  |  Branch (333:21): [True: 1.35k, False: 3]
  ------------------
  334|  1.35k|        struct m_obj_settings *entry = &ao_list[n];
  335|  1.35k|        bool probing = n + 1 != ao_num;
  336|  1.35k|        mp_verbose(log, "Trying audio driver '%s'\n", entry->name);
  ------------------
  |  |   75|  1.35k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  337|  1.35k|        char *dev = NULL;
  338|  1.35k|        if (pref_ao && pref_dev && strcmp(entry->name, pref_ao) == 0) {
  ------------------
  |  Branch (338:13): [True: 0, False: 1.35k]
  |  Branch (338:24): [True: 0, False: 0]
  |  Branch (338:36): [True: 0, False: 0]
  ------------------
  339|      0|            dev = pref_dev;
  340|      0|            mp_verbose(log, "Using preferred device '%s'\n", dev);
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  341|      0|        }
  342|  1.35k|        ao = ao_init(probing, global, wakeup_cb, wakeup_ctx, encode_lavc_ctx,
  343|  1.35k|                     init_flags, samplerate, format, channels, dev, entry->name);
  344|  1.35k|        if (ao)
  ------------------
  |  Branch (344:13): [True: 1.34k, False: 3]
  ------------------
  345|  1.34k|            break;
  346|      3|        if (!probing)
  ------------------
  |  Branch (346:13): [True: 3, False: 0]
  ------------------
  347|      3|            mp_err(log, "Failed to initialize audio driver '%s'\n", entry->name);
  ------------------
  |  |   72|      3|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  348|      3|        if (dev && forced_dev) {
  ------------------
  |  Branch (348:13): [True: 0, False: 3]
  |  Branch (348:20): [True: 0, False: 0]
  ------------------
  349|      0|            mp_err(log, "This audio driver/device was forced with the "
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  350|      0|                        "--audio-device option.\nTry unsetting it.\n");
  351|      0|        }
  352|      3|    }
  353|       |
  354|  1.35k|    talloc_free(tmp);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  355|  1.35k|    return ao;
  356|  1.35k|}
ao_query_and_reset_events:
  360|  8.85k|{
  361|  8.85k|    return atomic_fetch_and(&ao->events_, ~(unsigned)events) & events;
  362|  8.85k|}
ao_chmap_sel_adjust:
  388|  1.35k|{
  389|  1.35k|    MP_VERBOSE(ao, "Channel layouts:\n");
  ------------------
  |  |   88|  1.35k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.35k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  390|  1.35k|    mp_chmal_sel_log(s, ao->log, MSGL_V);
  391|  1.35k|    bool r = mp_chmap_sel_adjust(s, map);
  392|  1.35k|    if (r)
  ------------------
  |  Branch (392:9): [True: 1.35k, False: 0]
  ------------------
  393|  1.35k|        MP_VERBOSE(ao, "result: %s\n", mp_chmap_to_str(map));
  ------------------
  |  |   88|  1.35k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.35k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  394|  1.35k|    return r;
  395|  1.35k|}
ao_get_format:
  430|  2.70k|{
  431|  2.70k|    *samplerate = ao->samplerate;
  432|  2.70k|    *format = ao->format;
  433|  2.70k|    *channels = ao->channels;
  434|  2.70k|}
ao_get_name:
  437|  1.34k|{
  438|  1.34k|    return ao->driver->name;
  439|  1.34k|}
ao_get_description:
  442|  1.34k|{
  443|  1.34k|    return ao->driver->description;
  444|  1.34k|}
ao_hotplug_destroy:
  580|  5.81k|{
  581|  5.81k|    if (!hp)
  ------------------
  |  Branch (581:9): [True: 5.81k, False: 0]
  ------------------
  582|  5.81k|        return;
  583|      0|    if (hp->ao && hp->ao->driver->hotplug_uninit)
  ------------------
  |  Branch (583:9): [True: 0, False: 0]
  |  Branch (583:19): [True: 0, False: 0]
  ------------------
  584|      0|        hp->ao->driver->hotplug_uninit(hp->ao);
  585|      0|    talloc_free(hp->ao);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  586|      0|    talloc_free(hp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  587|      0|}
ao_set_gain:
  607|  4.06k|{
  608|  4.06k|    atomic_store(&ao->gain, gain);
  609|  4.06k|}
ao_post_process_data:
  649|   664k|{
  650|   664k|    bool planar = af_fmt_is_planar(ao->format);
  651|   664k|    int planes = planar ? ao->channels.num : 1;
  ------------------
  |  Branch (651:18): [True: 640k, False: 23.1k]
  ------------------
  652|   664k|    int plane_samples = num_samples * (planar ? 1: ao->channels.num);
  ------------------
  |  Branch (652:40): [True: 640k, False: 23.1k]
  ------------------
  653|  1.34M|    for (int n = 0; n < planes; n++)
  ------------------
  |  Branch (653:21): [True: 680k, False: 664k]
  ------------------
  654|   680k|        process_plane(ao, data[n], plane_samples);
  655|   664k|}
ao.c:get_desc:
  112|  47.8k|{
  113|  47.8k|    if (index >= MP_ARRAY_SIZE(audio_out_drivers))
  ------------------
  |  |   48|  47.8k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (113:9): [True: 5.81k, False: 42.0k]
  ------------------
  114|  5.81k|        return false;
  115|  42.0k|    const struct ao_driver *ao = audio_out_drivers[index];
  116|  42.0k|    *dst = (struct m_obj_desc) {
  117|  42.0k|        .name = ao->name,
  118|  42.0k|        .description = ao->description,
  119|  42.0k|        .priv_size = ao->priv_size,
  120|  42.0k|        .priv_defaults = ao->priv_defaults,
  121|  42.0k|        .options = ao->options,
  122|  42.0k|        .options_prefix = ao->options_prefix,
  123|  42.0k|        .global_opts = ao->global_opts,
  124|  42.0k|        .hidden = ao->encode,
  125|  42.0k|        .p = ao,
  126|  42.0k|    };
  127|  42.0k|    return true;
  128|  47.8k|}
ao.c:split_ao_device:
  269|  1.35k|{
  270|  1.35k|    *out_ao = NULL;
  271|  1.35k|    *out_dev = NULL;
  272|  1.35k|    if (!opt)
  ------------------
  |  Branch (272:9): [True: 0, False: 1.35k]
  ------------------
  273|      0|        return;
  274|  1.35k|    if (!opt[0] || strcmp(opt, "auto") == 0)
  ------------------
  |  Branch (274:9): [True: 0, False: 1.35k]
  |  Branch (274:20): [True: 1.35k, False: 0]
  ------------------
  275|  1.35k|        return;
  276|       |    // Split on "/". If "/" is the final character, or absent, out_dev is NULL.
  277|      0|    bstr b_dev, b_ao;
  278|      0|    bstr_split_tok(bstr0(opt), "/", &b_ao, &b_dev);
  279|      0|    if (b_dev.len > 0)
  ------------------
  |  Branch (279:9): [True: 0, False: 0]
  ------------------
  280|      0|        *out_dev = bstrto0(tmp, b_dev);
  281|      0|    *out_ao = bstrto0(tmp, b_ao);
  282|      0|}
ao.c:ao_init:
  200|  1.35k|{
  201|  1.35k|    struct ao *ao = ao_alloc(probing, global, wakeup_cb, wakeup_ctx, name);
  202|  1.35k|    if (!ao)
  ------------------
  |  Branch (202:9): [True: 0, False: 1.35k]
  ------------------
  203|      0|        return NULL;
  204|  1.35k|    ao->samplerate = samplerate;
  205|  1.35k|    ao->channels = channels;
  206|  1.35k|    ao->format = format;
  207|  1.35k|    ao->encode_lavc_ctx = encode_lavc_ctx;
  208|  1.35k|    ao->init_flags = flags;
  209|  1.35k|    if (ao->driver->encode != !!ao->encode_lavc_ctx)
  ------------------
  |  Branch (209:9): [True: 0, False: 1.35k]
  ------------------
  210|      0|        goto fail;
  211|       |
  212|  1.35k|    MP_VERBOSE(ao, "requested format: %d Hz, %s channels, %s\n",
  ------------------
  |  |   88|  1.35k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.35k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  213|  1.35k|               ao->samplerate, mp_chmap_to_str(&ao->channels),
  214|  1.35k|               af_fmt_to_str(ao->format));
  215|       |
  216|  1.35k|    ao->device = talloc_strdup(ao, dev);
  ------------------
  |  |   50|  1.35k|#define talloc_strdup                   ta_xstrdup
  ------------------
  217|  1.35k|    ao->stream_silence = flags & AO_INIT_STREAM_SILENCE;
  218|       |
  219|  1.35k|    init_buffer_pre(ao);
  220|       |
  221|  1.35k|    int r = ao->driver->init(ao);
  222|  1.35k|    if (r < 0) {
  ------------------
  |  Branch (222:9): [True: 0, False: 1.35k]
  ------------------
  223|       |        // Silly exception for coreaudio spdif redirection
  224|      0|        if (ao->redirect) {
  ------------------
  |  Branch (224:13): [True: 0, False: 0]
  ------------------
  225|      0|            char redirect[80], rdevice[80];
  226|      0|            snprintf(redirect, sizeof(redirect), "%s", ao->redirect);
  227|      0|            snprintf(rdevice, sizeof(rdevice), "%s", ao->device ? ao->device : "");
  ------------------
  |  Branch (227:54): [True: 0, False: 0]
  ------------------
  228|      0|            ao_uninit(ao);
  229|      0|            return ao_init(probing, global, wakeup_cb, wakeup_ctx,
  230|      0|                           encode_lavc_ctx, flags, samplerate, format, channels,
  231|      0|                           rdevice, redirect);
  232|      0|        }
  233|      0|        goto fail;
  234|      0|    }
  235|  1.35k|    ao->driver_initialized = true;
  236|       |
  237|  1.35k|    ao->sstride = af_fmt_to_bytes(ao->format);
  238|  1.35k|    ao->num_planes = 1;
  239|  1.35k|    if (af_fmt_is_planar(ao->format)) {
  ------------------
  |  Branch (239:9): [True: 1.17k, False: 179]
  ------------------
  240|  1.17k|        ao->num_planes = ao->channels.num;
  241|  1.17k|    } else {
  242|    179|        ao->sstride *= ao->channels.num;
  243|    179|    }
  244|  1.35k|    ao->bps = (int64_t)ao->samplerate * ao->sstride;
  245|       |
  246|  1.35k|    if (ao->device_buffer <= 0 && ao->driver->write) {
  ------------------
  |  Branch (246:9): [True: 3, False: 1.34k]
  |  Branch (246:35): [True: 3, False: 0]
  ------------------
  247|      3|        MP_ERR(ao, "Device buffer size not set.\n");
  ------------------
  |  |   85|      3|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      3|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  248|      3|        goto fail;
  249|      3|    }
  250|  1.34k|    if (ao->device_buffer)
  ------------------
  |  Branch (250:9): [True: 1.34k, False: 0]
  ------------------
  251|  1.34k|        MP_VERBOSE(ao, "device buffer: %d samples.\n", ao->device_buffer);
  ------------------
  |  |   88|  1.34k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.34k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  252|  1.34k|    ao->buffer = MPMAX(ao->device_buffer, ao->def_buffer * ao->samplerate);
  ------------------
  |  |   43|  1.34k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 1.34k]
  |  |  ------------------
  ------------------
  253|  1.34k|    ao->buffer = MPMAX(ao->buffer, 1);
  ------------------
  |  |   43|  1.34k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 1.34k, False: 0]
  |  |  ------------------
  ------------------
  254|       |
  255|  1.34k|    int align = af_format_sample_alignment(ao->format);
  256|  1.34k|    ao->buffer = (ao->buffer + align - 1) / align * align;
  257|  1.34k|    MP_VERBOSE(ao, "using soft-buffer of %d samples.\n", ao->buffer);
  ------------------
  |  |   88|  1.34k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.34k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  258|       |
  259|  1.34k|    if (!init_buffer_post(ao))
  ------------------
  |  Branch (259:9): [True: 0, False: 1.34k]
  ------------------
  260|      0|        goto fail;
  261|  1.34k|    return ao;
  262|       |
  263|      3|fail:
  264|      3|    ao_uninit(ao);
  265|      3|    return NULL;
  266|  1.34k|}
ao.c:ao_alloc:
  161|  1.35k|{
  162|  1.35k|    mp_assert(wakeup_cb);
  ------------------
  |  |   41|  1.35k|#define mp_assert assert
  ------------------
  163|       |
  164|  1.35k|    struct mp_log *log = mp_log_new(NULL, global->log, "ao");
  165|  1.35k|    struct m_obj_desc desc;
  166|  1.35k|    if (!m_obj_list_find(&desc, &ao_obj_list, bstr0(name))) {
  ------------------
  |  Branch (166:9): [True: 0, False: 1.35k]
  ------------------
  167|      0|        mp_msg(log, MSGL_ERR, "Audio output %s not found!\n", name);
  168|      0|        talloc_free(log);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  169|      0|        return NULL;
  170|  1.35k|    };
  171|  1.35k|    struct ao_opts *opts = mp_get_config_group(NULL, global, &ao_conf);
  172|  1.35k|    struct ao *ao = talloc_ptrtype(NULL, ao);
  ------------------
  |  |   34|  1.35k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  1.35k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.35k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  173|  1.35k|    talloc_steal(ao, log);
  ------------------
  |  |   38|  1.35k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  1.35k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  174|  1.35k|    *ao = (struct ao) {
  175|  1.35k|        .driver = desc.p,
  176|  1.35k|        .probing = probing,
  177|  1.35k|        .global = global,
  178|  1.35k|        .wakeup_cb = wakeup_cb,
  179|  1.35k|        .wakeup_ctx = wakeup_ctx,
  180|  1.35k|        .log = mp_log_new(ao, log, name),
  181|  1.35k|        .def_buffer = opts->audio_buffer,
  182|  1.35k|        .client_name = talloc_strdup(ao, opts->audio_client_name),
  ------------------
  |  |   50|  1.35k|#define talloc_strdup                   ta_xstrdup
  ------------------
  183|  1.35k|    };
  184|  1.35k|    talloc_free(opts);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  185|  1.35k|    ao->priv = m_config_group_from_desc(ao, ao->log, global, &desc, name);
  186|  1.35k|    if (!ao->priv)
  ------------------
  |  Branch (186:9): [True: 0, False: 1.35k]
  ------------------
  187|      0|        goto error;
  188|  1.35k|    ao_set_gain(ao, 1.0f);
  189|  1.35k|    return ao;
  190|      0|error:
  191|      0|    talloc_free(ao);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  192|      0|    return NULL;
  193|  1.35k|}
ao.c:process_plane:
  622|   680k|{
  623|   680k|    float gain = atomic_load_explicit(&ao->gain, memory_order_relaxed);
  624|   680k|    int gi = lrint(256.0 * gain);
  625|   680k|    if (gi == 256)
  ------------------
  |  Branch (625:9): [True: 680k, False: 0]
  ------------------
  626|   680k|        return;
  627|      0|    switch (af_fmt_from_planar(ao->format)) {
  628|      0|    case AF_FORMAT_U8:
  ------------------
  |  Branch (628:5): [True: 0, False: 0]
  ------------------
  629|      0|        MUL_GAIN_i((uint8_t *)data, num_samples, gi, 0, 128, 255);
  ------------------
  |  |  612|      0|    for (int n = 0; n < (num_samples); n++)                                     \
  |  |  ------------------
  |  |  |  Branch (612:21): [True: 0, False: 0]
  |  |  ------------------
  |  |  613|      0|        (d)[n] = MPCLAMP(                                                       \
  |  |  ------------------
  |  |  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  614|      0|            ((((int64_t)((d)[n]) - (center)) * (gain) + 128) >> 8) + (center),  \
  |  |  615|      0|            (low), (high))
  ------------------
  630|      0|        break;
  631|      0|    case AF_FORMAT_S16:
  ------------------
  |  Branch (631:5): [True: 0, False: 0]
  ------------------
  632|      0|        MUL_GAIN_i((int16_t *)data, num_samples, gi, INT16_MIN, 0, INT16_MAX);
  ------------------
  |  |  612|      0|    for (int n = 0; n < (num_samples); n++)                                     \
  |  |  ------------------
  |  |  |  Branch (612:21): [True: 0, False: 0]
  |  |  ------------------
  |  |  613|      0|        (d)[n] = MPCLAMP(                                                       \
  |  |  ------------------
  |  |  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  614|      0|            ((((int64_t)((d)[n]) - (center)) * (gain) + 128) >> 8) + (center),  \
  |  |  615|      0|            (low), (high))
  ------------------
  633|      0|        break;
  634|      0|    case AF_FORMAT_S32:
  ------------------
  |  Branch (634:5): [True: 0, False: 0]
  ------------------
  635|      0|        MUL_GAIN_i((int32_t *)data, num_samples, gi, INT32_MIN, 0, INT32_MAX);
  ------------------
  |  |  612|      0|    for (int n = 0; n < (num_samples); n++)                                     \
  |  |  ------------------
  |  |  |  Branch (612:21): [True: 0, False: 0]
  |  |  ------------------
  |  |  613|      0|        (d)[n] = MPCLAMP(                                                       \
  |  |  ------------------
  |  |  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  614|      0|            ((((int64_t)((d)[n]) - (center)) * (gain) + 128) >> 8) + (center),  \
  |  |  615|      0|            (low), (high))
  ------------------
  636|      0|        break;
  637|      0|    case AF_FORMAT_FLOAT:
  ------------------
  |  Branch (637:5): [True: 0, False: 0]
  ------------------
  638|      0|        MUL_GAIN_f((float *)data, num_samples, gain);
  ------------------
  |  |  618|      0|    for (int n = 0; n < (num_samples); n++)                                     \
  |  |  ------------------
  |  |  |  Branch (618:21): [True: 0, False: 0]
  |  |  ------------------
  |  |  619|      0|        (d)[n] = (d)[n] * (gain)
  ------------------
  639|      0|        break;
  640|      0|    case AF_FORMAT_DOUBLE:
  ------------------
  |  Branch (640:5): [True: 0, False: 0]
  ------------------
  641|      0|        MUL_GAIN_f((double *)data, num_samples, gain);
  ------------------
  |  |  618|      0|    for (int n = 0; n < (num_samples); n++)                                     \
  |  |  ------------------
  |  |  |  Branch (618:21): [True: 0, False: 0]
  |  |  ------------------
  |  |  619|      0|        (d)[n] = (d)[n] * (gain)
  ------------------
  642|      0|        break;
  643|      0|    default:;
  ------------------
  |  Branch (643:5): [True: 0, False: 0]
  ------------------
  644|       |        // all other sample formats are simply not supported
  645|      0|    }
  646|      0|}

ao_null.c:init:
   85|  1.35k|{
   86|  1.35k|    struct priv *priv = ao->priv;
   87|       |
   88|  1.35k|    if (priv->format)
  ------------------
  |  Branch (88:9): [True: 0, False: 1.35k]
  ------------------
   89|      0|        ao->format = priv->format;
   90|       |
   91|  1.35k|    ao->untimed = priv->untimed;
   92|       |
   93|  1.35k|    struct mp_chmap_sel sel = {.tmp = ao};
   94|  1.35k|    if (priv->channel_layouts.num_chmaps) {
  ------------------
  |  Branch (94:9): [True: 0, False: 1.35k]
  ------------------
   95|      0|        for (int n = 0; n < priv->channel_layouts.num_chmaps; n++)
  ------------------
  |  Branch (95:25): [True: 0, False: 0]
  ------------------
   96|      0|            mp_chmap_sel_add_map(&sel, &priv->channel_layouts.chmaps[n]);
   97|  1.35k|    } else {
   98|  1.35k|        mp_chmap_sel_add_any(&sel);
   99|  1.35k|    }
  100|  1.35k|    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
  ------------------
  |  Branch (100:9): [True: 0, False: 1.35k]
  ------------------
  101|      0|        mp_chmap_from_channels(&ao->channels, 2);
  102|       |
  103|  1.35k|    priv->latency = priv->latency_sec * ao->samplerate;
  104|       |
  105|       |    // A "buffer" for this many seconds of audio
  106|  1.35k|    int bursts = (int)(ao->samplerate * priv->bufferlen + 1) / priv->outburst;
  107|  1.35k|    ao->device_buffer = priv->outburst * bursts + priv->latency;
  108|       |
  109|  1.35k|    priv->last_time = mp_time_sec();
  110|       |
  111|  1.35k|    return 0;
  112|  1.35k|}
ao_null.c:uninit:
  116|  1.35k|{
  117|  1.35k|}
ao_null.c:reset:
  121|  1.13k|{
  122|  1.13k|    struct priv *priv = ao->priv;
  123|  1.13k|    priv->paused = false;
  124|  1.13k|    priv->buffered = 0;
  125|  1.13k|    priv->playing = false;
  126|  1.13k|}
ao_null.c:drain:
   64|   671k|{
   65|   671k|    struct priv *priv = ao->priv;
   66|       |
   67|   671k|    if (ao->untimed) {
  ------------------
  |  Branch (67:9): [True: 671k, False: 0]
  ------------------
   68|   671k|        priv->buffered = 0;
   69|   671k|        return;
   70|   671k|    }
   71|       |
   72|      0|    if (priv->paused)
  ------------------
  |  Branch (72:9): [True: 0, False: 0]
  ------------------
   73|      0|        return;
   74|       |
   75|      0|    double now = mp_time_sec();
   76|      0|    if (priv->buffered > 0) {
  ------------------
  |  Branch (76:9): [True: 0, False: 0]
  ------------------
   77|      0|        priv->buffered -= (now - priv->last_time) * ao->samplerate * priv->speed;
   78|      0|        if (priv->buffered < 0)
  ------------------
  |  Branch (78:13): [True: 0, False: 0]
  ------------------
   79|      0|            priv->buffered = 0;
   80|      0|    }
   81|      0|    priv->last_time = now;
   82|      0|}
ao_null.c:start:
  129|  1.24k|{
  130|  1.24k|    struct priv *priv = ao->priv;
  131|       |
  132|  1.24k|    if (priv->paused)
  ------------------
  |  Branch (132:9): [True: 0, False: 1.24k]
  ------------------
  133|  1.24k|        MP_ERR(ao, "illegal state: start() while paused\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  134|       |
  135|  1.24k|    drain(ao);
  136|  1.24k|    priv->paused = false;
  137|  1.24k|    priv->last_time = mp_time_sec();
  138|  1.24k|    priv->playing = true;
  139|  1.24k|}
ao_null.c:audio_write:
  160|   346k|{
  161|   346k|    struct priv *priv = ao->priv;
  162|       |
  163|   346k|    if (priv->buffered <= 0)
  ------------------
  |  Branch (163:9): [True: 346k, False: 0]
  ------------------
  164|   346k|        priv->buffered = priv->latency; // emulate fixed latency
  165|       |
  166|   346k|    priv->buffered += samples;
  167|   346k|    return true;
  168|   346k|}
ao_null.c:get_state:
  171|   670k|{
  172|   670k|    struct priv *priv = ao->priv;
  173|       |
  174|   670k|    drain(ao);
  175|       |
  176|   670k|    state->free_samples = ao->device_buffer - priv->latency - priv->buffered;
  177|   670k|    state->free_samples = state->free_samples / priv->outburst * priv->outburst;
  178|   670k|    state->queued_samples = priv->buffered;
  179|       |
  180|       |    // Note how get_state returns the delay in audio device time (instead of
  181|       |    // adjusting for speed), since most AOs seem to also do that.
  182|   670k|    state->delay = priv->buffered;
  183|       |
  184|       |    // Drivers with broken EOF handling usually always report the same device-
  185|       |    // level delay that is additional to the buffer time.
  186|   670k|    if (priv->broken_eof && priv->buffered < priv->latency)
  ------------------
  |  Branch (186:9): [True: 0, False: 670k]
  |  Branch (186:29): [True: 0, False: 0]
  ------------------
  187|      0|        state->delay = priv->latency;
  188|       |
  189|   670k|    state->delay /= ao->samplerate;
  190|       |
  191|   670k|    if (priv->broken_delay) { // Report only multiples of outburst
  ------------------
  |  Branch (191:9): [True: 0, False: 670k]
  ------------------
  192|      0|        double q = priv->outburst / (double)ao->samplerate;
  193|      0|        if (state->delay > 0)
  ------------------
  |  Branch (193:13): [True: 0, False: 0]
  ------------------
  194|      0|            state->delay = (int)(state->delay / q) * q;
  195|      0|    }
  196|       |
  197|   670k|    state->playing = priv->playing && priv->buffered > 0;
  ------------------
  |  Branch (197:22): [True: 664k, False: 5.52k]
  |  Branch (197:39): [True: 0, False: 664k]
  ------------------
  198|   670k|}

ao_wakeup:
   88|   359k|{
   89|   359k|    struct buffer_state *p = ao->buffer_state;
   90|   359k|    mp_mutex_lock(&p->pt_lock);
  ------------------
  |  |  131|   359k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   91|   359k|    p->need_wakeup = true;
   92|   359k|    mp_cond_broadcast(&p->pt_wakeup);
   93|   359k|    mp_mutex_unlock(&p->pt_lock);
  ------------------
  |  |  133|   359k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   94|   359k|}
ao_get_queue:
  115|  1.36k|{
  116|  1.36k|    struct buffer_state *p = ao->buffer_state;
  117|  1.36k|    return p->queue;
  118|  1.36k|}
ao_control:
  281|  1.35k|{
  282|  1.35k|    struct buffer_state *p = ao->buffer_state;
  283|  1.35k|    int r = CONTROL_UNKNOWN;
  ------------------
  |  |   71|  1.35k|#define CONTROL_UNKNOWN -1
  ------------------
  284|  1.35k|    if (ao->driver->control) {
  ------------------
  |  Branch (284:9): [True: 0, False: 1.35k]
  ------------------
  285|       |        // Only need to lock in push mode.
  286|      0|        if (ao->driver->write)
  ------------------
  |  Branch (286:13): [True: 0, False: 0]
  ------------------
  287|      0|            mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  288|       |
  289|      0|        r = ao->driver->control(ao, cmd, arg);
  290|       |
  291|      0|        if (ao->driver->write)
  ------------------
  |  Branch (291:13): [True: 0, False: 0]
  ------------------
  292|      0|            mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  293|      0|    }
  294|  1.35k|    return r;
  295|  1.35k|}
ao_get_delay:
  298|  5.98k|{
  299|  5.98k|    struct buffer_state *p = ao->buffer_state;
  300|       |
  301|  5.98k|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|  5.98k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  302|       |
  303|  5.98k|    double driver_delay;
  304|  5.98k|    if (ao->driver->write) {
  ------------------
  |  Branch (304:9): [True: 5.98k, False: 0]
  ------------------
  305|  5.98k|        struct mp_pcm_state state;
  306|  5.98k|        get_dev_state(ao, &state);
  307|  5.98k|        driver_delay = state.delay;
  308|  5.98k|    } else {
  309|      0|        int64_t end = p->end_time_ns;
  310|      0|        int64_t now = mp_time_ns();
  311|      0|        driver_delay = MPMAX(0, MP_TIME_NS_TO_S(end - now));
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  312|      0|    }
  313|       |
  314|  5.98k|    int64_t pending = mp_async_queue_get_samples(p->queue);
  315|  5.98k|    if (p->pending)
  ------------------
  |  Branch (315:9): [True: 42, False: 5.94k]
  ------------------
  316|     42|        pending += mp_aframe_get_size(p->pending);
  317|       |
  318|  5.98k|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|  5.98k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  319|  5.98k|    return driver_delay + pending / (double)ao->samplerate;
  320|  5.98k|}
ao_reset:
  324|  1.13k|{
  325|  1.13k|    struct buffer_state *p = ao->buffer_state;
  326|  1.13k|    bool wakeup = false;
  327|  1.13k|    bool do_reset = false;
  328|       |
  329|  1.13k|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|  1.13k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  330|       |
  331|  1.13k|    TA_FREEP(&p->pending);
  ------------------
  |  |   81|  1.13k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  1.13k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  332|  1.13k|    mp_async_queue_reset(p->queue);
  333|  1.13k|    mp_filter_reset(p->filter_root);
  334|  1.13k|    mp_async_queue_resume_reading(p->queue);
  335|       |
  336|  1.13k|    if (!ao->stream_silence && ao->driver->reset) {
  ------------------
  |  Branch (336:9): [True: 1.13k, False: 0]
  |  Branch (336:32): [True: 1.13k, False: 0]
  ------------------
  337|  1.13k|        if (ao->driver->write) {
  ------------------
  |  Branch (337:13): [True: 1.13k, False: 0]
  ------------------
  338|  1.13k|            ao->driver->reset(ao);
  339|  1.13k|        } else {
  340|       |            // Pull AOs may wait for ao_read_data() to return.
  341|       |            // That would deadlock if called from within the lock.
  342|      0|            do_reset = true;
  343|      0|        }
  344|  1.13k|        p->streaming = false;
  345|  1.13k|    }
  346|  1.13k|    wakeup = p->playing;
  347|  1.13k|    p->playing = false;
  348|  1.13k|    p->recover_pause = false;
  349|  1.13k|    p->hw_paused = false;
  350|  1.13k|    p->end_time_ns = 0;
  351|       |
  352|  1.13k|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|  1.13k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  353|       |
  354|  1.13k|    if (do_reset)
  ------------------
  |  Branch (354:9): [True: 0, False: 1.13k]
  ------------------
  355|      0|        ao->driver->reset(ao);
  356|       |
  357|  1.13k|    if (wakeup)
  ------------------
  |  Branch (357:9): [True: 740, False: 397]
  ------------------
  358|    740|        ao_wakeup(ao);
  359|  1.13k|}
ao_start:
  366|  1.36k|{
  367|  1.36k|    struct buffer_state *p = ao->buffer_state;
  368|  1.36k|    bool do_start = false;
  369|       |
  370|  1.36k|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|  1.36k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  371|       |
  372|  1.36k|    p->playing = true;
  373|       |
  374|  1.36k|    if (!ao->driver->write && !p->paused && !p->streaming) {
  ------------------
  |  Branch (374:9): [True: 0, False: 1.36k]
  |  Branch (374:31): [True: 0, False: 0]
  |  Branch (374:45): [True: 0, False: 0]
  ------------------
  375|      0|        p->streaming = true;
  376|      0|        do_start = true;
  377|      0|    }
  378|       |
  379|  1.36k|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|  1.36k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  380|       |
  381|       |    // Pull AOs might call ao_read_data() so do this outside the lock.
  382|  1.36k|    if (do_start)
  ------------------
  |  Branch (382:9): [True: 0, False: 1.36k]
  ------------------
  383|      0|        ao->driver->start(ao);
  384|       |
  385|  1.36k|    ao_wakeup(ao);
  386|  1.36k|}
ao_set_paused:
  389|  1.34k|{
  390|  1.34k|    struct buffer_state *p = ao->buffer_state;
  391|  1.34k|    bool wakeup = false;
  392|  1.34k|    bool do_change_state = false;
  393|  1.34k|    bool is_hw_paused;
  394|       |
  395|       |    // If we are going to pause on eof and ao is still playing,
  396|       |    // be sure to drain the ao first for gapless.
  397|  1.34k|    if (eof && paused && ao_is_playing(ao))
  ------------------
  |  Branch (397:9): [True: 0, False: 1.34k]
  |  Branch (397:16): [True: 0, False: 0]
  |  Branch (397:26): [True: 0, False: 0]
  ------------------
  398|      0|        ao_drain(ao);
  399|       |
  400|  1.34k|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|  1.34k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  401|       |
  402|  1.34k|    if ((p->playing || !ao->driver->write) && !p->paused && paused) {
  ------------------
  |  Branch (402:10): [True: 0, False: 1.34k]
  |  Branch (402:24): [True: 0, False: 1.34k]
  |  Branch (402:47): [True: 0, False: 0]
  |  Branch (402:61): [True: 0, False: 0]
  ------------------
  403|      0|        if (p->streaming && !ao->stream_silence) {
  ------------------
  |  Branch (403:13): [True: 0, False: 0]
  |  Branch (403:29): [True: 0, False: 0]
  ------------------
  404|      0|            if (ao->driver->write) {
  ------------------
  |  Branch (404:17): [True: 0, False: 0]
  ------------------
  405|      0|                if (!p->recover_pause)
  ------------------
  |  Branch (405:21): [True: 0, False: 0]
  ------------------
  406|      0|                    get_dev_state(ao, &p->prepause_state);
  407|      0|                if (ao->driver->set_pause && ao->driver->set_pause(ao, true)) {
  ------------------
  |  Branch (407:21): [True: 0, False: 0]
  |  Branch (407:46): [True: 0, False: 0]
  ------------------
  408|      0|                    p->hw_paused = true;
  409|      0|                } else {
  410|      0|                    ao->driver->reset(ao);
  411|      0|                    p->streaming = false;
  412|      0|                    p->recover_pause = !ao->untimed;
  413|      0|                }
  414|      0|            } else if (ao->driver->reset || ao->driver->set_pause) {
  ------------------
  |  Branch (414:24): [True: 0, False: 0]
  |  Branch (414:45): [True: 0, False: 0]
  ------------------
  415|       |                // See ao_reset() why this is done outside of the lock.
  416|      0|                do_change_state = true;
  417|      0|                p->streaming = false;
  418|      0|                is_hw_paused = p->hw_paused = !!ao->driver->set_pause;
  419|      0|            }
  420|      0|        }
  421|      0|        wakeup = true;
  422|  1.34k|    } else if (p->playing && p->paused && !paused) {
  ------------------
  |  Branch (422:16): [True: 0, False: 1.34k]
  |  Branch (422:30): [True: 0, False: 0]
  |  Branch (422:43): [True: 0, False: 0]
  ------------------
  423|      0|        if (ao->driver->write) {
  ------------------
  |  Branch (423:13): [True: 0, False: 0]
  ------------------
  424|      0|            if (p->hw_paused)
  ------------------
  |  Branch (424:17): [True: 0, False: 0]
  ------------------
  425|      0|                ao->driver->set_pause(ao, false);
  426|      0|            p->hw_paused = false;
  427|      0|        } else {
  428|      0|            if (!p->streaming)
  ------------------
  |  Branch (428:17): [True: 0, False: 0]
  ------------------
  429|      0|                do_change_state = true;
  430|      0|            p->streaming = true;
  431|      0|            is_hw_paused = p->hw_paused;
  432|      0|            p->hw_paused = false;
  433|      0|        }
  434|      0|        wakeup = true;
  435|      0|    }
  436|  1.34k|    p->paused = paused;
  437|       |
  438|  1.34k|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|  1.34k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  439|       |
  440|  1.34k|    if (do_change_state) {
  ------------------
  |  Branch (440:9): [True: 0, False: 1.34k]
  ------------------
  441|      0|        if (is_hw_paused) {
  ------------------
  |  Branch (441:13): [True: 0, False: 0]
  ------------------
  442|      0|            if (paused) {
  ------------------
  |  Branch (442:17): [True: 0, False: 0]
  ------------------
  443|      0|                ao->driver->set_pause(ao, true);
  444|      0|                p->queued_time_ns = p->end_time_ns - mp_time_ns();
  445|      0|            } else {
  446|      0|                p->end_time_ns = p->queued_time_ns + mp_time_ns();
  447|      0|                ao->driver->set_pause(ao, false);
  448|      0|            }
  449|      0|        } else {
  450|      0|            if (paused)
  ------------------
  |  Branch (450:17): [True: 0, False: 0]
  ------------------
  451|      0|                ao->driver->reset(ao);
  452|      0|            else
  453|      0|                ao->driver->start(ao);
  454|      0|        }
  455|      0|    }
  456|       |
  457|  1.34k|    if (wakeup)
  ------------------
  |  Branch (457:9): [True: 0, False: 1.34k]
  ------------------
  458|      0|        ao_wakeup(ao);
  459|  1.34k|}
ao_is_playing:
  466|  19.2k|{
  467|  19.2k|    struct buffer_state *p = ao->buffer_state;
  468|       |
  469|  19.2k|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|  19.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  470|  19.2k|    bool playing = p->playing;
  471|  19.2k|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|  19.2k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  472|       |
  473|  19.2k|    return playing;
  474|  19.2k|}
ao_drain:
  478|    733|{
  479|    733|    struct buffer_state *p = ao->buffer_state;
  480|       |
  481|    733|    mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|    733|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  482|    733|    while (!p->paused && p->playing) {
  ------------------
  |  Branch (482:12): [True: 733, False: 0]
  |  Branch (482:26): [True: 733, False: 0]
  ------------------
  483|    733|        mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|    733|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  484|    733|        double delay = ao_get_delay(ao);
  485|    733|        mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|    733|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  486|       |
  487|       |        // Wait for buffer + arbitrary ~250ms for EOF signal from AO.
  488|    733|        if (mp_cond_timedwait(&p->wakeup, &p->lock,
  ------------------
  |  Branch (488:13): [True: 733, False: 0]
  ------------------
  489|    733|                              MP_TIME_S_TO_NS(MPMAX(delay, 0) + 0.25)))
  ------------------
  |  |   59|  1.46k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  |  |  ------------------
  |  |  |  Branch (59:30): [True: 166, False: 567]
  |  |  ------------------
  ------------------
  490|    733|        {
  491|    733|            MP_VERBOSE(ao, "drain timeout\n");
  ------------------
  |  |   88|    733|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    733|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  492|    733|            break;
  493|    733|        }
  494|       |
  495|      0|        if (!p->playing && mp_async_queue_get_samples(p->queue)) {
  ------------------
  |  Branch (495:13): [True: 0, False: 0]
  |  Branch (495:28): [True: 0, False: 0]
  ------------------
  496|      0|            MP_WARN(ao, "underrun during draining\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  497|      0|            mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  498|      0|            ao_start(ao);
  499|      0|            mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  500|      0|        }
  501|      0|    }
  502|    733|    mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|    733|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  503|       |
  504|    733|    ao_reset(ao);
  505|    733|}
ao_uninit:
  514|  1.35k|{
  515|  1.35k|    struct buffer_state *p = ao->buffer_state;
  516|       |
  517|  1.35k|    if (p && p->thread_valid) {
  ------------------
  |  Branch (517:9): [True: 1.35k, False: 0]
  |  Branch (517:14): [True: 1.34k, False: 3]
  ------------------
  518|  1.34k|        mp_mutex_lock(&p->pt_lock);
  ------------------
  |  |  131|  1.34k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  519|  1.34k|        p->terminate = true;
  520|  1.34k|        mp_cond_broadcast(&p->pt_wakeup);
  521|  1.34k|        mp_mutex_unlock(&p->pt_lock);
  ------------------
  |  |  133|  1.34k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  522|       |
  523|  1.34k|        mp_thread_join(p->thread);
  ------------------
  |  |  212|  1.34k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  524|  1.34k|        p->thread_valid = false;
  525|  1.34k|    }
  526|       |
  527|  1.35k|    if (ao->driver_initialized)
  ------------------
  |  Branch (527:9): [True: 1.35k, False: 0]
  ------------------
  528|  1.35k|        ao->driver->uninit(ao);
  529|       |
  530|  1.35k|    if (p) {
  ------------------
  |  Branch (530:9): [True: 1.35k, False: 0]
  ------------------
  531|  1.35k|        talloc_free(p->filter_root);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  532|  1.35k|        talloc_free(p->queue);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  533|  1.35k|        talloc_free(p->pending);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  534|  1.35k|        talloc_free(p->convert_buffer);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  535|  1.35k|        talloc_free(p->temp_buf);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  536|       |
  537|  1.35k|        mp_cond_destroy(&p->wakeup);
  538|  1.35k|        mp_mutex_destroy(&p->lock);
  ------------------
  |  |  130|  1.35k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  539|       |
  540|  1.35k|        mp_cond_destroy(&p->pt_wakeup);
  541|  1.35k|        mp_mutex_destroy(&p->pt_lock);
  ------------------
  |  |  130|  1.35k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  542|  1.35k|    }
  543|       |
  544|  1.35k|    talloc_free(ao);
  ------------------
  |  |   47|  1.35k|#define talloc_free                     ta_free
  ------------------
  545|  1.35k|}
init_buffer_pre:
  548|  1.35k|{
  549|  1.35k|    ao->buffer_state = talloc_zero(ao, struct buffer_state);
  ------------------
  |  |   27|  1.35k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.35k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.35k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  550|  1.35k|}
init_buffer_post:
  553|  1.34k|{
  554|  1.34k|    struct buffer_state *p = ao->buffer_state;
  555|       |
  556|  1.34k|    mp_assert(ao->driver->start);
  ------------------
  |  |   41|  1.34k|#define mp_assert assert
  ------------------
  557|  1.34k|    if (ao->driver->write) {
  ------------------
  |  Branch (557:9): [True: 1.34k, False: 0]
  ------------------
  558|  1.34k|        mp_assert(ao->driver->reset);
  ------------------
  |  |   41|  1.34k|#define mp_assert assert
  ------------------
  559|  1.34k|        mp_assert(ao->driver->get_state);
  ------------------
  |  |   41|  1.34k|#define mp_assert assert
  ------------------
  560|  1.34k|    }
  561|       |
  562|  1.34k|    mp_mutex_init(&p->lock);
  563|  1.34k|    mp_cond_init(&p->wakeup);
  564|       |
  565|  1.34k|    mp_mutex_init(&p->pt_lock);
  566|  1.34k|    mp_cond_init(&p->pt_wakeup);
  567|       |
  568|  1.34k|    p->queue = mp_async_queue_create();
  569|  1.34k|    p->filter_root = mp_filter_create_root(ao->global);
  570|  1.34k|    p->input = mp_async_queue_create_filter(p->filter_root, MP_PIN_OUT, p->queue);
  571|       |
  572|  1.34k|    mp_async_queue_resume_reading(p->queue);
  573|       |
  574|  1.34k|    struct mp_async_queue_config cfg = {
  575|  1.34k|        .sample_unit = AQUEUE_UNIT_SAMPLES,
  576|  1.34k|        .max_samples = ao->buffer,
  577|  1.34k|        .max_bytes = INT64_MAX,
  578|  1.34k|    };
  579|  1.34k|    mp_async_queue_set_config(p->queue, cfg);
  580|       |
  581|  1.34k|    if (ao->driver->write) {
  ------------------
  |  Branch (581:9): [True: 1.34k, False: 0]
  ------------------
  582|  1.34k|        mp_filter_graph_set_wakeup_cb(p->filter_root, wakeup_filters, ao);
  583|       |
  584|  1.34k|        p->thread_valid = true;
  585|  1.34k|        if (mp_thread_create(&p->thread, ao_thread, ao)) {
  ------------------
  |  |  211|  1.34k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 1.34k]
  |  |  ------------------
  ------------------
  586|      0|            p->thread_valid = false;
  587|      0|            return false;
  588|      0|        }
  589|  1.34k|    } else {
  590|      0|        if (ao->stream_silence) {
  ------------------
  |  Branch (590:13): [True: 0, False: 0]
  ------------------
  591|      0|            ao->driver->start(ao);
  592|      0|            p->streaming = true;
  593|      0|        }
  594|      0|    }
  595|       |
  596|  1.34k|    if (ao->stream_silence) {
  ------------------
  |  Branch (596:9): [True: 0, False: 1.34k]
  ------------------
  597|      0|        MP_WARN(ao, "The --audio-stream-silence option is set. This will break "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  598|      0|                "certain player behavior.\n");
  599|      0|    }
  600|       |
  601|  1.34k|    return true;
  602|  1.34k|}
buffer.c:read_buffer:
  123|   664k|{
  124|   664k|    struct buffer_state *p = ao->buffer_state;
  125|   664k|    int pos = 0;
  126|   664k|    *eof = false;
  127|       |
  128|  1.03M|    while (p->playing && !p->paused && pos < samples) {
  ------------------
  |  Branch (128:12): [True: 1.03M, False: 0]
  |  Branch (128:26): [True: 1.03M, False: 0]
  |  Branch (128:40): [True: 1.03M, False: 2.39k]
  ------------------
  129|  1.03M|        if (!p->pending || !mp_aframe_get_size(p->pending)) {
  ------------------
  |  Branch (129:13): [True: 662k, False: 373k]
  |  Branch (129:28): [True: 371k, False: 2.39k]
  ------------------
  130|  1.03M|            TA_FREEP(&p->pending);
  ------------------
  |  |   81|  1.03M|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  1.03M|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  131|  1.03M|            struct mp_frame frame = mp_pin_out_read(p->input->pins[0]);
  132|  1.03M|            if (!frame.type)
  ------------------
  |  Branch (132:17): [True: 661k, False: 371k]
  ------------------
  133|   661k|                break; // we can't/don't want to block
  134|   371k|            if (frame.type != MP_FRAME_AUDIO) {
  ------------------
  |  Branch (134:17): [True: 617, False: 371k]
  ------------------
  135|    617|                if (frame.type == MP_FRAME_EOF)
  ------------------
  |  Branch (135:21): [True: 617, False: 0]
  ------------------
  136|    617|                    *eof = true;
  137|    617|                mp_frame_unref(&frame);
  138|    617|                continue;
  139|    617|            }
  140|   371k|            p->pending = frame.data;
  141|   371k|        }
  142|       |
  143|   373k|        if (!data)
  ------------------
  |  Branch (143:13): [True: 0, False: 373k]
  ------------------
  144|      0|            break;
  145|       |
  146|   373k|        int copy = mp_aframe_get_size(p->pending);
  147|   373k|        uint8_t **fdata = mp_aframe_get_data_ro(p->pending);
  148|   373k|        copy = MPMIN(copy, samples - pos);
  ------------------
  |  |   44|   373k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 2.39k, False: 371k]
  |  |  ------------------
  ------------------
  149|   783k|        for (int n = 0; n < ao->num_planes; n++) {
  ------------------
  |  Branch (149:25): [True: 410k, False: 373k]
  ------------------
  150|   410k|            memcpy((char *)data[n] + pos * ao->sstride,
  151|   410k|                   fdata[n], copy * ao->sstride);
  152|   410k|        }
  153|   373k|        mp_aframe_skip_samples(p->pending, copy);
  154|   373k|        pos += copy;
  155|   373k|        *eof = false;
  156|   373k|    }
  157|       |
  158|   664k|    if (!data) {
  ------------------
  |  Branch (158:9): [True: 0, False: 664k]
  ------------------
  159|      0|        if (!p->pending)
  ------------------
  |  Branch (159:13): [True: 0, False: 0]
  ------------------
  160|      0|            return 0;
  161|      0|        void **pd = (void *)mp_aframe_get_data_rw(p->pending);
  162|      0|        if (pd)
  ------------------
  |  Branch (162:13): [True: 0, False: 0]
  ------------------
  163|      0|            ao_post_process_data(ao, pd, mp_aframe_get_size(p->pending));
  164|      0|        return 1;
  165|      0|    }
  166|       |
  167|       |    // pad with silence (underflow/paused/eof)
  168|   664k|    if (pad_silence) {
  ------------------
  |  Branch (168:9): [True: 664k, False: 0]
  ------------------
  169|  1.34M|        for (int n = 0; n < ao->num_planes; n++) {
  ------------------
  |  Branch (169:25): [True: 680k, False: 664k]
  ------------------
  170|   680k|            af_fill_silence((char *)data[n] + pos * ao->sstride,
  171|   680k|                    (samples - pos) * ao->sstride,
  172|   680k|                    ao->format);
  173|   680k|        }
  174|   664k|    }
  175|       |
  176|   664k|    ao_post_process_data(ao, data, pos);
  177|   664k|    return pos;
  178|   664k|}
buffer.c:get_dev_state:
   98|   670k|{
   99|   670k|    struct buffer_state *p = ao->buffer_state;
  100|       |
  101|   670k|    if (p->paused && p->playing && !ao->stream_silence) {
  ------------------
  |  Branch (101:9): [True: 0, False: 670k]
  |  Branch (101:22): [True: 0, False: 0]
  |  Branch (101:36): [True: 0, False: 0]
  ------------------
  102|      0|        *state = p->prepause_state;
  103|      0|        return;
  104|      0|    }
  105|       |
  106|   670k|    *state = (struct mp_pcm_state){
  107|   670k|        .free_samples = -1,
  108|   670k|        .queued_samples = -1,
  109|   670k|        .delay = -1,
  110|   670k|    };
  111|   670k|    ao->driver->get_state(ao, state);
  112|   670k|}
buffer.c:wakeup_filters:
  508|   356k|{
  509|   356k|    struct ao *ao = ctx;
  510|   356k|    ao_wakeup(ao);
  511|   356k|}
buffer.c:ao_thread:
  709|  1.34k|{
  710|  1.34k|    struct ao *ao = arg;
  711|  1.34k|    struct buffer_state *p = ao->buffer_state;
  712|  1.34k|    mp_thread_set_name("ao");
  713|   667k|    while (1) {
  ------------------
  |  Branch (713:12): [Folded - Ignored]
  ------------------
  714|   667k|        mp_mutex_lock(&p->lock);
  ------------------
  |  |  131|   667k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  715|       |
  716|   667k|        bool retry = false;
  717|   667k|        if (!ao->driver->initially_blocked || p->initial_unblocked)
  ------------------
  |  Branch (717:13): [True: 667k, False: 0]
  |  Branch (717:47): [True: 0, False: 0]
  ------------------
  718|   667k|            retry = ao_play_data(ao);
  719|       |
  720|       |        // Wait until the device wants us to write more data to it.
  721|       |        // Fallback to guessing.
  722|   667k|        int64_t timeout = INT64_MAX;
  723|   667k|        if (p->streaming && !retry && (!p->paused || ao->stream_silence)) {
  ------------------
  |  Branch (723:13): [True: 662k, False: 4.95k]
  |  Branch (723:29): [True: 316k, False: 346k]
  |  Branch (723:40): [True: 316k, False: 0]
  |  Branch (723:54): [True: 0, False: 0]
  ------------------
  724|       |            // Wake up again if half of the audio buffer has been played.
  725|       |            // Since audio could play at a faster or slower pace, wake up twice
  726|       |            // as often as ideally needed.
  727|   316k|            timeout = MP_TIME_S_TO_NS(ao->device_buffer / (double)ao->samplerate * 0.25);
  ------------------
  |  |   59|   316k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  728|   316k|        }
  729|       |
  730|   667k|        mp_mutex_unlock(&p->lock);
  ------------------
  |  |  133|   667k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  731|       |
  732|   667k|        mp_mutex_lock(&p->pt_lock);
  ------------------
  |  |  131|   667k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  733|   667k|        if (p->terminate) {
  ------------------
  |  Branch (733:13): [True: 1.34k, False: 666k]
  ------------------
  734|  1.34k|            mp_mutex_unlock(&p->pt_lock);
  ------------------
  |  |  133|  1.34k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  735|  1.34k|            break;
  736|  1.34k|        }
  737|   666k|        if (!p->need_wakeup && !retry) {
  ------------------
  |  Branch (737:13): [True: 605k, False: 60.4k]
  |  Branch (737:32): [True: 300k, False: 305k]
  ------------------
  738|   300k|            MP_STATS(ao, "start audio wait");
  ------------------
  |  |   95|   300k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   300k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  739|   300k|            mp_cond_timedwait(&p->pt_wakeup, &p->pt_lock, timeout);
  740|   300k|            MP_STATS(ao, "end audio wait");
  ------------------
  |  |   95|   300k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   300k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  741|   300k|        }
  742|   666k|        p->need_wakeup = false;
  743|   666k|        mp_mutex_unlock(&p->pt_lock);
  ------------------
  |  |  133|   666k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  744|   666k|    }
  745|  1.34k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  1.34k|#define MP_THREAD_RETURN() return NULL
  ------------------
  746|  1.34k|}
buffer.c:ao_play_data:
  628|   667k|{
  629|   667k|    struct buffer_state *p = ao->buffer_state;
  630|       |
  631|   667k|    if ((!p->playing || p->paused) && !ao->stream_silence)
  ------------------
  |  Branch (631:10): [True: 3.61k, False: 664k]
  |  Branch (631:25): [True: 0, False: 664k]
  |  Branch (631:39): [True: 3.61k, False: 0]
  ------------------
  632|  3.61k|        return false;
  633|       |
  634|   664k|    struct mp_pcm_state state;
  635|   664k|    get_dev_state(ao, &state);
  636|       |
  637|   664k|    if (p->streaming && !state.playing && !ao->untimed)
  ------------------
  |  Branch (637:9): [True: 662k, False: 1.96k]
  |  Branch (637:25): [True: 662k, False: 0]
  |  Branch (637:43): [True: 0, False: 662k]
  ------------------
  638|      0|        goto eof;
  639|       |
  640|   664k|    void **planes = NULL;
  641|   664k|    int space = state.free_samples;
  642|   664k|    if (!space)
  ------------------
  |  Branch (642:9): [True: 0, False: 664k]
  ------------------
  643|      0|        return false;
  644|   664k|    mp_assert(space >= 0);
  ------------------
  |  |   41|   664k|#define mp_assert assert
  ------------------
  645|       |
  646|   664k|    int samples = 0;
  647|   664k|    bool got_eof = false;
  648|   664k|    if (ao->driver->write_frames) {
  ------------------
  |  Branch (648:9): [True: 0, False: 664k]
  ------------------
  649|      0|        TA_FREEP(&p->pending);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  650|      0|        samples = read_buffer(ao, NULL, 1, &got_eof, false);
  651|      0|        planes = (void **)&p->pending;
  652|   664k|    } else {
  653|   664k|        if (!realloc_buf(ao, space)) {
  ------------------
  |  Branch (653:13): [True: 116, False: 664k]
  ------------------
  654|    116|            MP_ERR(ao, "Failed to allocate buffer.\n");
  ------------------
  |  |   85|    116|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    116|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  655|    116|            return false;
  656|    116|        }
  657|   664k|        planes = (void **)mp_aframe_get_data_rw(p->temp_buf);
  658|   664k|        mp_assert(planes);
  ------------------
  |  |   41|   664k|#define mp_assert assert
  ------------------
  659|       |
  660|   664k|        if (p->recover_pause) {
  ------------------
  |  Branch (660:13): [True: 0, False: 664k]
  ------------------
  661|      0|            samples = MPCLAMP(p->prepause_state.delay * ao->samplerate, 0, space);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  662|      0|            p->recover_pause = false;
  663|      0|            mp_aframe_set_silence(p->temp_buf, 0, space);
  664|      0|        }
  665|       |
  666|   664k|        if (!samples) {
  ------------------
  |  Branch (666:13): [True: 664k, False: 0]
  ------------------
  667|   664k|            samples = read_buffer(ao, planes, space, &got_eof, true);
  668|   664k|            if (p->paused || (ao->stream_silence && !p->playing))
  ------------------
  |  Branch (668:17): [True: 0, False: 664k]
  |  Branch (668:31): [True: 0, False: 664k]
  |  Branch (668:53): [True: 0, False: 0]
  ------------------
  669|      0|                samples = space; // read_buffer() sets remainder to silent
  670|   664k|        }
  671|   664k|    }
  672|       |
  673|   664k|    if (samples) {
  ------------------
  |  Branch (673:9): [True: 346k, False: 317k]
  ------------------
  674|   346k|        MP_STATS(ao, "start ao fill");
  ------------------
  |  |   95|   346k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   346k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  675|   346k|        if (!ao->driver->write(ao, planes, samples))
  ------------------
  |  Branch (675:13): [True: 0, False: 346k]
  ------------------
  676|   346k|            MP_ERR(ao, "Error writing audio to device.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  677|   346k|        MP_STATS(ao, "end ao fill");
  ------------------
  |  |   95|   346k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   346k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  678|       |
  679|   346k|        if (!p->streaming) {
  ------------------
  |  Branch (679:13): [True: 1.24k, False: 345k]
  ------------------
  680|  1.24k|            MP_VERBOSE(ao, "starting AO\n");
  ------------------
  |  |   88|  1.24k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.24k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  681|  1.24k|            ao->driver->start(ao);
  682|  1.24k|            p->streaming = true;
  683|  1.24k|            state.playing = true;
  684|  1.24k|        }
  685|   346k|    }
  686|       |
  687|   664k|    MP_TRACE(ao, "in=%d space=%d(%d) pl=%d, eof=%d\n",
  ------------------
  |  |   90|   664k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   664k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  688|   664k|             samples, space, state.free_samples, p->playing, got_eof);
  689|       |
  690|   664k|    if (got_eof)
  ------------------
  |  Branch (690:9): [True: 617, False: 663k]
  ------------------
  691|    617|        goto eof;
  692|       |
  693|   663k|    return samples > 0 && (samples < space || ao->untimed);
  ------------------
  |  Branch (693:12): [True: 346k, False: 317k]
  |  Branch (693:28): [True: 343k, False: 2.39k]
  |  Branch (693:47): [True: 2.39k, False: 0]
  ------------------
  694|       |
  695|    617|eof:
  696|    617|    MP_VERBOSE(ao, "audio end or underrun\n");
  ------------------
  |  |   88|    617|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    617|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  697|       |    // Normal AOs signal EOF on underrun, untimed AOs never signal underruns.
  698|    617|    if (ao->untimed || !state.playing || ao->stream_silence) {
  ------------------
  |  Branch (698:9): [True: 617, False: 0]
  |  Branch (698:24): [True: 0, False: 0]
  |  Branch (698:42): [True: 0, False: 0]
  ------------------
  699|    617|        p->streaming = state.playing && !ao->untimed;
  ------------------
  |  Branch (699:24): [True: 145, False: 472]
  |  Branch (699:41): [True: 0, False: 145]
  ------------------
  700|    617|        p->playing = false;
  701|    617|    }
  702|    617|    ao->wakeup_cb(ao->wakeup_ctx);
  703|       |    // For ao_drain().
  704|    617|    mp_cond_broadcast(&p->wakeup);
  705|    617|    return true;
  706|   664k|}
buffer.c:realloc_buf:
  605|   664k|{
  606|   664k|    struct buffer_state *p = ao->buffer_state;
  607|       |
  608|   664k|    samples = MPMAX(1, samples);
  ------------------
  |  |   43|   664k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 664k]
  |  |  ------------------
  ------------------
  609|       |
  610|   664k|    if (!p->temp_buf || samples > mp_aframe_get_size(p->temp_buf)) {
  ------------------
  |  Branch (610:9): [True: 1.35k, False: 662k]
  |  Branch (610:25): [True: 0, False: 662k]
  ------------------
  611|  1.35k|        TA_FREEP(&p->temp_buf);
  ------------------
  |  |   81|  1.35k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  1.35k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  612|  1.35k|        p->temp_buf = mp_aframe_create();
  613|  1.35k|        if (!mp_aframe_set_format(p->temp_buf, ao->format) ||
  ------------------
  |  Branch (613:13): [True: 0, False: 1.35k]
  ------------------
  614|  1.35k|            !mp_aframe_set_chmap(p->temp_buf, &ao->channels) ||
  ------------------
  |  Branch (614:13): [True: 0, False: 1.35k]
  ------------------
  615|  1.35k|            !mp_aframe_set_rate(p->temp_buf, ao->samplerate) ||
  ------------------
  |  Branch (615:13): [True: 116, False: 1.23k]
  ------------------
  616|  1.35k|            !mp_aframe_alloc_data(p->temp_buf, samples))
  ------------------
  |  Branch (616:13): [True: 0, False: 1.23k]
  ------------------
  617|    116|        {
  618|    116|            TA_FREEP(&p->temp_buf);
  ------------------
  |  |   81|    116|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|    116|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  619|    116|            return false;
  620|    116|        }
  621|  1.35k|    }
  622|       |
  623|   664k|    return true;
  624|   664k|}

mp_to_av_stream_type:
   44|    223|{
   45|    223|    switch (type) {
   46|    223|    case STREAM_VIDEO: return AVMEDIA_TYPE_VIDEO;
  ------------------
  |  Branch (46:5): [True: 223, False: 0]
  ------------------
   47|      0|    case STREAM_AUDIO: return AVMEDIA_TYPE_AUDIO;
  ------------------
  |  Branch (47:5): [True: 0, False: 223]
  ------------------
   48|      0|    case STREAM_SUB:   return AVMEDIA_TYPE_SUBTITLE;
  ------------------
  |  Branch (48:5): [True: 0, False: 223]
  ------------------
   49|      0|    default:           return AVMEDIA_TYPE_UNKNOWN;
  ------------------
  |  Branch (49:5): [True: 0, False: 223]
  ------------------
   50|    223|    }
   51|    223|}
mp_codec_params_to_av:
   54|  9.53k|{
   55|  9.53k|    AVCodecParameters *avp = avcodec_parameters_alloc();
   56|  9.53k|    if (!avp)
  ------------------
  |  Branch (56:9): [True: 0, False: 9.53k]
  ------------------
   57|      0|        return NULL;
   58|       |
   59|       |    // If we have lavf demuxer params, they overwrite by definition any others.
   60|  9.53k|    if (c->lav_codecpar) {
  ------------------
  |  Branch (60:9): [True: 9.30k, False: 223]
  ------------------
   61|  9.30k|        if (avcodec_parameters_copy(avp, c->lav_codecpar) < 0)
  ------------------
  |  Branch (61:13): [True: 0, False: 9.30k]
  ------------------
   62|      0|            goto error;
   63|  9.30k|        return avp;
   64|  9.30k|    }
   65|       |
   66|    223|    avp->codec_type = mp_to_av_stream_type(c->type);
   67|    223|    avp->codec_id = mp_codec_to_av_codec_id(c->codec);
   68|    223|    avp->codec_tag = c->codec_tag;
   69|    223|    if (c->extradata_size) {
  ------------------
  |  Branch (69:9): [True: 0, False: 223]
  ------------------
   70|      0|        uint8_t *extradata = c->extradata;
   71|      0|        int size = c->extradata_size;
   72|       |
   73|      0|        if (avp->codec_id == AV_CODEC_ID_FLAC) {
  ------------------
  |  Branch (73:13): [True: 0, False: 0]
  ------------------
   74|       |            // ffmpeg expects FLAC extradata to be just the STREAMINFO,
   75|       |            // so grab only that (and assume it'll be the first block)
   76|      0|            if (size >= 8 && !memcmp(c->extradata, "fLaC", 4)) {
  ------------------
  |  Branch (76:17): [True: 0, False: 0]
  |  Branch (76:30): [True: 0, False: 0]
  ------------------
   77|      0|                extradata += 8;
   78|      0|                size = MPMIN(34, size - 8); // FLAC_STREAMINFO_SIZE
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   79|      0|            }
   80|      0|        }
   81|       |
   82|      0|        avp->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
   83|      0|        if (!avp->extradata)
  ------------------
  |  Branch (83:13): [True: 0, False: 0]
  ------------------
   84|      0|            goto error;
   85|      0|        avp->extradata_size = size;
   86|      0|        memcpy(avp->extradata, extradata, size);
   87|      0|    }
   88|    223|    avp->bits_per_coded_sample = c->bits_per_coded_sample;
   89|       |
   90|       |    // Video only
   91|    223|    avp->width = c->disp_w;
   92|    223|    avp->height = c->disp_h;
   93|       |
   94|       |    // Audio only
   95|    223|    avp->sample_rate = c->samplerate;
   96|    223|    avp->bit_rate = c->bitrate;
   97|    223|    avp->block_align = c->block_align;
   98|       |
   99|    223|    mp_chmap_to_av_layout(&avp->ch_layout, &c->channels);
  100|       |
  101|    223|    return avp;
  102|      0|error:
  103|      0|    avcodec_parameters_free(&avp);
  104|      0|    return NULL;
  105|    223|}
mp_set_avctx_codec_headers:
  109|  9.53k|{
  110|  9.53k|    enum AVMediaType codec_type = avctx->codec_type;
  111|  9.53k|    enum AVCodecID codec_id = avctx->codec_id;
  112|  9.53k|    AVCodecParameters *avp = mp_codec_params_to_av(c);
  113|  9.53k|    if (!avp)
  ------------------
  |  Branch (113:9): [True: 0, False: 9.53k]
  ------------------
  114|      0|        return -1;
  115|       |
  116|  9.53k|    int r = avcodec_parameters_to_context(avctx, avp) < 0 ? -1 : 0;
  ------------------
  |  Branch (116:13): [True: 0, False: 9.53k]
  ------------------
  117|  9.53k|    avcodec_parameters_free(&avp);
  118|       |
  119|  9.53k|    if (avctx->codec_type != AVMEDIA_TYPE_UNKNOWN)
  ------------------
  |  Branch (119:9): [True: 9.53k, False: 0]
  ------------------
  120|  9.53k|        avctx->codec_type = codec_type;
  121|  9.53k|    if (avctx->codec_id != AV_CODEC_ID_NONE)
  ------------------
  |  Branch (121:9): [True: 9.53k, False: 0]
  ------------------
  122|  9.53k|        avctx->codec_id = codec_id;
  123|  9.53k|    return r;
  124|  9.53k|}
mp_get_codec_timebase:
  129|  9.53k|{
  130|  9.53k|    AVRational tb = {c->native_tb_num, c->native_tb_den};
  131|  9.53k|    if (tb.num < 1 || tb.den < 1) {
  ------------------
  |  Branch (131:9): [True: 223, False: 9.30k]
  |  Branch (131:23): [True: 0, False: 9.30k]
  ------------------
  132|    223|        if (c->reliable_fps)
  ------------------
  |  Branch (132:13): [True: 223, False: 0]
  ------------------
  133|    223|            tb = av_inv_q(av_d2q(c->fps, 1000000));
  134|    223|        if (tb.num < 1 || tb.den < 1)
  ------------------
  |  Branch (134:13): [True: 0, False: 223]
  |  Branch (134:27): [True: 0, False: 223]
  ------------------
  135|      0|            tb = AV_TIME_BASE_Q;
  136|    223|    }
  137|       |
  138|       |    // If the timebase is too coarse, raise its precision, or small adjustments
  139|       |    // to timestamps done between decoder and demuxer could be lost.
  140|  9.53k|    int64_t den = tb.den;
  141|  9.53k|    if (av_q2d(tb) > 0.001) {
  ------------------
  |  Branch (141:9): [True: 3.39k, False: 6.13k]
  ------------------
  142|  3.39k|        int64_t scaling_num = tb.num * INT64_C(1000);
  143|  3.39k|        int64_t scaling_den = tb.den;
  144|  3.39k|        den *= (scaling_num + scaling_den - 1) / scaling_den;
  145|  3.39k|    }
  146|       |
  147|  9.53k|    av_reduce(&tb.num, &tb.den, tb.num, den, INT_MAX);
  148|       |
  149|  9.53k|    if (tb.num < 1 || tb.den < 1)
  ------------------
  |  Branch (149:9): [True: 0, False: 9.53k]
  |  Branch (149:23): [True: 0, False: 9.53k]
  ------------------
  150|      0|        tb = AV_TIME_BASE_Q;
  151|       |
  152|  9.53k|    return tb;
  153|  9.53k|}
mp_pts_to_av:
  163|  2.85M|{
  164|  2.85M|    AVRational b = get_def_tb(tb);
  165|  2.85M|    return mp_pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : llrint(mp_pts / av_q2d(b));
  ------------------
  |  |   38|  2.85M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (165:12): [True: 37.7k, False: 2.81M]
  ------------------
  166|  2.85M|}
mp_pts_from_av:
  170|  3.42M|{
  171|  3.42M|    AVRational b = get_def_tb(tb);
  172|  3.42M|    return av_pts == AV_NOPTS_VALUE ? MP_NOPTS_VALUE : av_pts * av_q2d(b);
  ------------------
  |  |   38|  20.4k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (172:12): [True: 20.4k, False: 3.40M]
  ------------------
  173|  3.42M|}
mp_set_av_packet:
  180|  1.42M|{
  181|  1.42M|    dst->side_data = NULL;
  182|  1.42M|    dst->side_data_elems = 0;
  183|  1.42M|    dst->buf = NULL;
  184|  1.42M|    av_packet_unref(dst);
  185|       |
  186|  1.42M|    dst->data = mpkt ? mpkt->buffer : NULL;
  ------------------
  |  Branch (186:17): [True: 1.41M, False: 8.71k]
  ------------------
  187|  1.42M|    dst->size = mpkt ? mpkt->len : 0;
  ------------------
  |  Branch (187:17): [True: 1.41M, False: 8.71k]
  ------------------
  188|       |    /* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info
  189|       |     * from demuxer. */
  190|  1.42M|    if (mpkt && mpkt->keyframe)
  ------------------
  |  Branch (190:9): [True: 1.41M, False: 8.71k]
  |  Branch (190:17): [True: 1.24M, False: 167k]
  ------------------
  191|  1.24M|        dst->flags |= AV_PKT_FLAG_KEY;
  192|  1.42M|    if (mpkt && mpkt->avpacket) {
  ------------------
  |  Branch (192:9): [True: 1.41M, False: 8.71k]
  |  Branch (192:17): [True: 1.41M, False: 0]
  ------------------
  193|  1.41M|        dst->side_data = mpkt->avpacket->side_data;
  194|  1.41M|        dst->side_data_elems = mpkt->avpacket->side_data_elems;
  195|  1.41M|        if (dst->data == mpkt->avpacket->data)
  ------------------
  |  Branch (195:13): [True: 1.41M, False: 0]
  ------------------
  196|  1.41M|            dst->buf = mpkt->avpacket->buf;
  197|  1.41M|        dst->flags |= mpkt->avpacket->flags;
  198|  1.41M|    }
  199|  1.42M|    if (mpkt && tb && tb->num > 0 && tb->den > 0)
  ------------------
  |  Branch (199:9): [True: 1.41M, False: 8.71k]
  |  Branch (199:17): [True: 1.41M, False: 0]
  |  Branch (199:23): [True: 1.41M, False: 0]
  |  Branch (199:38): [True: 1.41M, False: 0]
  ------------------
  200|  1.41M|        dst->duration = mpkt->duration / av_q2d(*tb);
  201|  1.42M|    dst->pts = mp_pts_to_av(mpkt ? mpkt->pts : MP_NOPTS_VALUE, tb);
  ------------------
  |  |   38|  8.71k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (201:29): [True: 1.41M, False: 8.71k]
  ------------------
  202|  1.42M|    dst->dts = mp_pts_to_av(mpkt ? mpkt->dts : MP_NOPTS_VALUE, tb);
  ------------------
  |  |   38|  8.71k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (202:29): [True: 1.41M, False: 8.71k]
  ------------------
  203|  1.42M|}
mp_set_avcodec_threads:
  206|  9.53k|{
  207|  9.53k|    if (threads == 0) {
  ------------------
  |  Branch (207:9): [True: 7.59k, False: 1.94k]
  ------------------
  208|  7.59k|        threads = av_cpu_count();
  209|  7.59k|        if (threads < 1) {
  ------------------
  |  Branch (209:13): [True: 0, False: 7.59k]
  ------------------
  210|      0|            mp_warn(l, "Could not determine thread count to use, defaulting to 1.\n");
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
  211|      0|            threads = 1;
  212|  7.59k|        } else {
  213|  7.59k|            mp_verbose(l, "Detected %d logical cores.\n", threads);
  ------------------
  |  |   75|  7.59k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  214|  7.59k|            if (threads > 1)
  ------------------
  |  Branch (214:17): [True: 7.59k, False: 0]
  ------------------
  215|  7.59k|                threads += 1; // extra thread for better load balancing
  216|  7.59k|        }
  217|       |        // Apparently some libavcodec versions have or had trouble with more
  218|       |        // than 16 threads, and/or print a warning when using > 16.
  219|  7.59k|        threads = MPMIN(threads, 16);
  ------------------
  |  |   44|  7.59k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 7.59k, False: 0]
  |  |  ------------------
  ------------------
  220|  7.59k|    }
  221|  9.53k|    mp_verbose(l, "Requesting %d threads for decoding.\n", threads);
  ------------------
  |  |   75|  9.53k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  222|  9.53k|    avctx->thread_count = threads;
  223|  9.53k|}
mp_add_lavc_decoders:
  243|  10.4k|{
  244|  10.4k|    add_codecs(list, type, true);
  245|  10.4k|}
mp_get_lavf_demuxers:
  254|     34|{
  255|     34|    char **list = NULL;
  256|     34|    void *iter = NULL;
  257|     34|    int num = 0;
  258|  12.1k|    for (;;) {
  259|  12.1k|        const AVInputFormat *cur = av_demuxer_iterate(&iter);
  260|  12.1k|        if (!cur)
  ------------------
  |  Branch (260:13): [True: 34, False: 12.0k]
  ------------------
  261|     34|            break;
  262|  12.0k|        MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(list, cur->name));
  ------------------
  |  |  105|  12.0k|    do {                                            \
  |  |  106|  12.0k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  12.0k|    do {                                            \
  |  |  |  |   97|  12.0k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  12.0k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  12.0k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  12.0k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 272, False: 11.7k]
  |  |  |  |  ------------------
  |  |  |  |   99|  12.0k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    272|    do {                                                        \
  |  |  |  |  |  |   89|    272|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    272|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    272|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    272|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    272|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    272|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    272|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  12.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  12.0k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  12.0k|        (idxvar)++;                                 \
  |  |  109|  12.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  263|  12.0k|    }
  264|     34|    MP_TARRAY_APPEND(NULL, list, num, NULL);
  ------------------
  |  |  105|     34|    do {                                            \
  |  |  106|     34|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     34|    do {                                            \
  |  |  |  |   97|     34|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     34|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     34|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     34|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 34]
  |  |  |  |  ------------------
  |  |  |  |   99|     34|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     34|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     34|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     34|        (idxvar)++;                                 \
  |  |  109|     34|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  265|     34|    return list;
  266|     34|}
mp_get_lavf_protocols:
  269|     51|{
  270|     51|    char **list = NULL;
  271|     51|    int num = 0;
  272|     51|    void *opaque = NULL;
  273|     51|    const char *name;
  274|    612|    while ((name = avio_enum_protocols(&opaque, 0)))
  ------------------
  |  Branch (274:12): [True: 561, False: 51]
  ------------------
  275|    561|        MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(list, name));
  ------------------
  |  |  105|    561|    do {                                            \
  |  |  106|    561|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    561|    do {                                            \
  |  |  |  |   97|    561|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    561|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    561|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    561|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 153, False: 408]
  |  |  |  |  ------------------
  |  |  |  |   99|    561|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    153|    do {                                                        \
  |  |  |  |  |  |   89|    153|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    153|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    153|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    153|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    153|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    153|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    153|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    561|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    561|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    561|        (idxvar)++;                                 \
  |  |  109|    561|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  276|     51|    MP_TARRAY_APPEND(NULL, list, num, NULL);
  ------------------
  |  |  105|     51|    do {                                            \
  |  |  106|     51|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     51|    do {                                            \
  |  |  |  |   97|     51|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     51|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     51|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     51|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |   99|     51|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     51|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     51|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     51|        (idxvar)++;                                 \
  |  |  109|     51|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  277|     51|    return list;
  278|     51|}
mp_codec_to_av_codec_id:
  281|  17.0k|{
  282|  17.0k|    int id = AV_CODEC_ID_NONE;
  283|  17.0k|    if (codec) {
  ------------------
  |  Branch (283:9): [True: 17.0k, False: 0]
  ------------------
  284|  17.0k|        const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(codec);
  285|  17.0k|        if (desc)
  ------------------
  |  Branch (285:13): [True: 17.0k, False: 13]
  ------------------
  286|  17.0k|            id = desc->id;
  287|  17.0k|        if (id == AV_CODEC_ID_NONE) {
  ------------------
  |  Branch (287:13): [True: 13, False: 17.0k]
  ------------------
  288|     13|            const AVCodec *avcodec = avcodec_find_decoder_by_name(codec);
  289|     13|            if (avcodec)
  ------------------
  |  Branch (289:17): [True: 0, False: 13]
  ------------------
  290|      0|                id = avcodec->id;
  291|     13|        }
  292|  17.0k|    }
  293|  17.0k|    return id;
  294|  17.0k|}
mp_codec_from_av_codec_id:
  297|  2.60M|{
  298|  2.60M|    const char *name = NULL;
  299|  2.60M|    const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
  300|  2.60M|    if (desc)
  ------------------
  |  Branch (300:9): [True: 2.60M, False: 28]
  ------------------
  301|  2.60M|        name = desc->name;
  302|  2.60M|    if (!name) {
  ------------------
  |  Branch (302:9): [True: 28, False: 2.60M]
  ------------------
  303|     28|        const AVCodec *avcodec = avcodec_find_decoder(codec_id);
  304|     28|        if (avcodec)
  ------------------
  |  Branch (304:13): [True: 0, False: 28]
  ------------------
  305|      0|            name = avcodec->name;
  306|     28|    }
  307|  2.60M|    return name;
  308|  2.60M|}
mp_codec_is_lossless:
  311|  16.8k|{
  312|  16.8k|    const AVCodecDescriptor *desc =
  313|  16.8k|        avcodec_descriptor_get(mp_codec_to_av_codec_id(codec));
  314|  16.8k|    return desc && (desc->props & AV_CODEC_PROP_LOSSLESS);
  ------------------
  |  Branch (314:12): [True: 16.8k, False: 13]
  |  Branch (314:20): [True: 15.9k, False: 886]
  ------------------
  315|  16.8k|}
mp_set_avdict:
  320|  21.0k|{
  321|  21.0k|    for (int n = 0; kv && kv[n * 2]; n++)
  ------------------
  |  Branch (321:21): [True: 0, False: 21.0k]
  |  Branch (321:27): [True: 0, False: 0]
  ------------------
  322|      0|        av_dict_set(dict, kv[n * 2 + 0], kv[n * 2 + 1], 0);
  323|  21.0k|}
mp_avdict_print_unset:
  328|  20.1k|{
  329|  20.1k|    AVDictionaryEntry *t = NULL;
  330|  20.1k|    while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX)))
  ------------------
  |  Branch (330:12): [True: 0, False: 20.1k]
  ------------------
  331|      0|        mp_msg(log, msgl, "Could not set AVOption %s='%s'\n", t->key, t->value);
  332|  20.1k|}
mp_set_avopts:
  369|  9.53k|{
  370|  9.53k|    return mp_set_avopts_pos(log, avobj, avobj, kv);
  371|  9.53k|}
mp_set_avopts_pos:
  376|  9.53k|{
  377|  9.53k|    int success = 0;
  378|  9.53k|    for (int n = 0; kv && kv[n * 2]; n++) {
  ------------------
  |  Branch (378:21): [True: 0, False: 9.53k]
  |  Branch (378:27): [True: 0, False: 0]
  ------------------
  379|      0|        char *k = kv[n * 2 + 0];
  380|      0|        char *v = kv[n * 2 + 1];
  381|      0|        resolve_positional_arg(posargs, &k);
  382|      0|        int r = av_opt_set(avobj, k, v, AV_OPT_SEARCH_CHILDREN);
  383|      0|        if (r == AVERROR_OPTION_NOT_FOUND) {
  ------------------
  |  Branch (383:13): [True: 0, False: 0]
  ------------------
  384|      0|            mp_err(log, "AVOption '%s' not found.\n", k);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  385|      0|            success = -1;
  386|      0|        } else if (r < 0) {
  ------------------
  |  Branch (386:20): [True: 0, False: 0]
  ------------------
  387|      0|            char errstr[80];
  388|      0|            av_strerror(r, errstr, sizeof(errstr));
  389|      0|            mp_err(log, "Could not set AVOption %s='%s' (%s)\n", k, v, errstr);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  390|      0|            success = -1;
  391|      0|        }
  392|      0|    }
  393|  9.53k|    return success;
  394|  9.53k|}
mp_free_av_packet:
  405|  17.1k|{
  406|  17.1k|    if (*pkt) {
  ------------------
  |  Branch (406:9): [True: 9.53k, False: 7.61k]
  ------------------
  407|  9.53k|        (*pkt)->side_data = NULL;
  408|  9.53k|        (*pkt)->side_data_elems = 0;
  409|  9.53k|        (*pkt)->buf = NULL;
  410|  9.53k|    }
  411|  17.1k|    av_packet_free(pkt);
  412|  17.1k|}
mp_codec_info_from_av:
  415|   445k|{
  416|   445k|    c->codec_profile = av_get_profile_name(avctx->codec, avctx->profile);
  417|   445k|    if (!c->codec_profile)
  ------------------
  |  Branch (417:9): [True: 445k, False: 7]
  ------------------
  418|   445k|        c->codec_profile = avcodec_profile_name(avctx->codec_id, avctx->profile);
  419|   445k|    c->codec = avctx->codec_descriptor->name;
  420|   445k|    c->codec_desc = avctx->codec_descriptor->long_name;
  421|   445k|    c->decoder = avctx->codec->name;
  422|   445k|    c->decoder_desc = avctx->codec->long_name;
  423|   445k|}
av_common.c:get_def_tb:
  156|  6.27M|{
  157|  6.27M|    return tb && tb->num > 0 && tb->den > 0 ? *tb : AV_TIME_BASE_Q;
  ------------------
  |  Branch (157:12): [True: 6.27M, False: 18.4E]
  |  Branch (157:18): [True: 6.27M, False: 18.4E]
  |  Branch (157:33): [True: 6.27M, False: 18.4E]
  ------------------
  158|  6.27M|}
av_common.c:add_codecs:
  227|  10.4k|{
  228|  10.4k|    void *iter = NULL;
  229|  5.07M|    for (;;) {
  230|  5.07M|        const AVCodec *cur = av_codec_iterate(&iter);
  231|  5.07M|        if (!cur)
  ------------------
  |  Branch (231:13): [True: 10.4k, False: 5.06M]
  ------------------
  232|  10.4k|            break;
  233|  5.06M|        if (av_codec_is_decoder(cur) == decoders &&
  ------------------
  |  Branch (233:13): [True: 5.06M, False: 0]
  ------------------
  234|  5.06M|            (type == AVMEDIA_TYPE_UNKNOWN || cur->type == type))
  ------------------
  |  Branch (234:14): [True: 0, False: 5.06M]
  |  Branch (234:46): [True: 2.56M, False: 2.49M]
  ------------------
  235|  2.56M|        {
  236|  2.56M|            mp_add_decoder(list, mp_codec_from_av_codec_id(cur->id),
  237|  2.56M|                           cur->name, cur->long_name);
  238|  2.56M|        }
  239|  5.06M|    }
  240|  10.4k|}

init_libav:
  154|  5.81k|{
  155|  5.81k|    mp_mutex_lock(&log_lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  156|  5.81k|    if (!log_mpv_instance) {
  ------------------
  |  Branch (156:9): [True: 5.81k, False: 0]
  ------------------
  157|  5.81k|        log_mpv_instance = global;
  158|  5.81k|        log_root = mp_log_new(NULL, global->log, "ffmpeg");
  159|  5.81k|        log_decaudio = mp_log_new(log_root, log_root, "audio");
  160|  5.81k|        log_decvideo = mp_log_new(log_root, log_root, "video");
  161|  5.81k|        log_demuxer = mp_log_new(log_root, log_root, "demuxer");
  162|  5.81k|        log_buffer = (bstr){0};
  163|  5.81k|        av_log_set_callback(mp_msg_av_log_callback);
  164|  5.81k|    }
  165|  5.81k|    mp_mutex_unlock(&log_lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  166|       |
  167|  5.81k|    avformat_network_init();
  168|       |
  169|  5.81k|#if HAVE_LIBAVDEVICE
  170|  5.81k|    avdevice_register_all();
  171|  5.81k|#endif
  172|  5.81k|}
uninit_libav:
  175|  5.81k|{
  176|  5.81k|    mp_mutex_lock(&log_lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  177|  5.81k|    if (log_mpv_instance == global) {
  ------------------
  |  Branch (177:9): [True: 5.81k, False: 0]
  ------------------
  178|  5.81k|        av_log_set_callback(av_log_default_callback);
  179|  5.81k|        log_mpv_instance = NULL;
  180|  5.81k|        talloc_free(log_root);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  181|  5.81k|    }
  182|  5.81k|    mp_mutex_unlock(&log_lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  183|  5.81k|}
check_library_versions:
  196|  11.6k|{
  197|  11.6k|    const struct lib libs[] = {
  198|  11.6k|        {"libavcodec",    LIBAVCODEC_VERSION_INT,    avcodec_version()},
  199|  11.6k|#if HAVE_LIBAVDEVICE
  200|  11.6k|        {"libavdevice",   LIBAVDEVICE_VERSION_INT,   avdevice_version()},
  201|  11.6k|#endif
  202|  11.6k|        {"libavfilter",   LIBAVFILTER_VERSION_INT,   avfilter_version()},
  203|  11.6k|        {"libavformat",   LIBAVFORMAT_VERSION_INT,   avformat_version()},
  204|  11.6k|        {"libavutil",     LIBAVUTIL_VERSION_INT,     avutil_version()},
  205|  11.6k|        {"libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()},
  206|  11.6k|        {"libswscale",    LIBSWSCALE_VERSION_INT,    swscale_version()},
  207|  11.6k|    };
  208|       |
  209|  11.6k|    const char *runtime_version = av_version_info();
  210|  11.6k|    mp_msg(log, v, "FFmpeg version: %s", FFMPEG_VERSION);
  211|  11.6k|    if (strcmp(runtime_version, FFMPEG_VERSION))
  ------------------
  |  Branch (211:9): [True: 0, False: 11.6k]
  ------------------
  212|      0|        mp_msg(log, v, " (runtime %s)", runtime_version);
  213|  11.6k|    mp_msg(log, v, "\n");
  214|  11.6k|    mp_msg(log, v, "FFmpeg library versions:\n");
  215|       |
  216|  92.9k|    for (int n = 0; n < MP_ARRAY_SIZE(libs); n++) {
  ------------------
  |  |   48|  92.9k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (216:21): [True: 81.3k, False: 11.6k]
  ------------------
  217|  81.3k|        const struct lib *l = &libs[n];
  218|  81.3k|        mp_msg(log, v, "   %-15s %d.%d.%d", l->name, V(l->buildv));
  ------------------
  |  |  185|  81.3k|#define V(x) AV_VERSION_MAJOR(x), \
  |  |  186|  81.3k|             AV_VERSION_MINOR(x), \
  |  |  187|  81.3k|             AV_VERSION_MICRO(x)
  ------------------
  219|  81.3k|        if (l->buildv != l->runv)
  ------------------
  |  Branch (219:13): [True: 0, False: 81.3k]
  ------------------
  220|      0|            mp_msg(log, v, " (runtime %d.%d.%d)", V(l->runv));
  ------------------
  |  |  185|      0|#define V(x) AV_VERSION_MAJOR(x), \
  |  |  186|      0|             AV_VERSION_MINOR(x), \
  |  |  187|      0|             AV_VERSION_MICRO(x)
  ------------------
  221|  81.3k|        mp_msg(log, v, "\n");
  222|  81.3k|        if (l->buildv > l->runv ||
  ------------------
  |  Branch (222:13): [True: 0, False: 81.3k]
  ------------------
  223|  81.3k|            AV_VERSION_MAJOR(l->buildv) != AV_VERSION_MAJOR(l->runv))
  ------------------
  |  Branch (223:13): [True: 0, False: 81.3k]
  ------------------
  224|      0|        {
  225|      0|            mp_fatal(log, "%s: build version %d.%d.%d incompatible with runtime version %d.%d.%d\n",
  ------------------
  |  |   71|      0|#define mp_fatal(log, ...)      mp_msg(log, MSGL_FATAL, __VA_ARGS__)
  ------------------
  226|      0|                     l->name, V(l->buildv), V(l->runv));
  227|      0|            exit(1);
  228|      0|        }
  229|  81.3k|    }
  230|  11.6k|}
av_log.c:mp_msg_av_log_callback:
  119|  2.09M|{
  120|  2.09M|    AVClass *avc = ptr ? *(AVClass **)ptr : NULL;
  ------------------
  |  Branch (120:20): [True: 2.01M, False: 84.0k]
  ------------------
  121|  2.09M|    int mp_level = av_log_level_to_mp_level(level);
  122|       |
  123|       |    // Note: mp_log is thread-safe, but destruction of the log instances is not.
  124|  2.09M|    mp_mutex_lock(&log_lock);
  ------------------
  |  |  131|  2.09M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  125|       |
  126|  2.09M|    if (!log_mpv_instance) {
  ------------------
  |  Branch (126:9): [True: 0, False: 2.09M]
  ------------------
  127|      0|        mp_mutex_unlock(&log_lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  128|       |        // Fallback to stderr
  129|      0|        vfprintf(stderr, fmt, vl);
  130|      0|        return;
  131|      0|    }
  132|       |
  133|  2.09M|    struct mp_log *log = get_av_log(ptr);
  134|       |
  135|  2.09M|    if (mp_msg_test(log, mp_level)) {
  ------------------
  |  Branch (135:9): [True: 2.09M, False: 18.4E]
  ------------------
  136|  2.09M|        log_buffer.len = 0;
  137|  2.09M|        bstr_xappend_vasprintf(log_root, &log_buffer, fmt, vl);
  138|  2.09M|        if (!log_buffer.len)
  ------------------
  |  Branch (138:13): [True: 0, False: 2.09M]
  ------------------
  139|      0|            goto done;
  140|  2.09M|        const char *prefix = avc ? avclass_item_name(ptr, avc) : NULL;
  ------------------
  |  Branch (140:30): [True: 2.01M, False: 84.0k]
  ------------------
  141|  2.09M|        if (log_print_prefix && prefix) {
  ------------------
  |  Branch (141:13): [True: 2.07M, False: 21.1k]
  |  Branch (141:33): [True: 1.99M, False: 84.0k]
  ------------------
  142|  1.99M|            mp_msg(log, mp_level, "%s: %.*s", prefix, BSTR_P(log_buffer));
  ------------------
  |  |  283|  1.99M|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 1.99M, False: 0]
  |  |  ------------------
  ------------------
  143|  1.99M|        } else {
  144|   105k|            mp_msg(log, mp_level, "%.*s", BSTR_P(log_buffer));
  ------------------
  |  |  283|   105k|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 105k, False: 0]
  |  |  ------------------
  ------------------
  145|   105k|        }
  146|  2.09M|        log_print_prefix = log_buffer.start[log_buffer.len - 1] == '\n';
  147|  2.09M|    }
  148|       |
  149|  2.09M|done:
  150|  2.09M|    mp_mutex_unlock(&log_lock);
  ------------------
  |  |  133|  2.09M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  151|  2.09M|}
av_log.c:av_log_level_to_mp_level:
   63|  2.09M|{
   64|  2.09M|    if (av_level > AV_LOG_VERBOSE)
  ------------------
  |  Branch (64:9): [True: 647k, False: 1.45M]
  ------------------
   65|   647k|        return MSGL_TRACE;
   66|  1.45M|    if (av_level > AV_LOG_INFO)
  ------------------
  |  Branch (66:9): [True: 11.3k, False: 1.43M]
  ------------------
   67|  11.3k|        return MSGL_DEBUG;
   68|  1.43M|    if (av_level > AV_LOG_WARNING)
  ------------------
  |  Branch (68:9): [True: 18.2k, False: 1.42M]
  ------------------
   69|  18.2k|        return MSGL_V;
   70|  1.42M|    if (av_level > AV_LOG_ERROR)
  ------------------
  |  Branch (70:9): [True: 133k, False: 1.28M]
  ------------------
   71|   133k|        return MSGL_WARN;
   72|  1.28M|    if (av_level > AV_LOG_FATAL)
  ------------------
  |  Branch (72:9): [True: 1.28M, False: 95]
  ------------------
   73|  1.28M|        return MSGL_ERR;
   74|     95|    return MSGL_FATAL;
   75|  1.28M|}
av_log.c:get_av_log:
   78|  2.09M|{
   79|  2.09M|    if (!ptr)
  ------------------
  |  Branch (79:9): [True: 84.0k, False: 2.01M]
  ------------------
   80|  84.0k|        return log_root;
   81|       |
   82|  2.01M|    AVClass *avc = *(AVClass **)ptr;
   83|  2.01M|    if (!avc) {
  ------------------
  |  Branch (83:9): [True: 0, False: 2.01M]
  ------------------
   84|      0|        mp_warn(log_root,
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
   85|      0|               "av_log callback called with bad parameters (NULL AVClass).\n"
   86|      0|               "This is a bug in one of FFmpeg libraries used.\n");
   87|      0|        return log_root;
   88|      0|    }
   89|       |
   90|  2.01M|    if (!strcmp(avc->class_name, "AVCodecContext")) {
  ------------------
  |  Branch (90:9): [True: 1.46M, False: 554k]
  ------------------
   91|  1.46M|        AVCodecContext *s = ptr;
   92|  1.46M|        if (s->codec) {
  ------------------
  |  Branch (92:13): [True: 1.39M, False: 62.7k]
  ------------------
   93|  1.39M|            if (s->codec->type == AVMEDIA_TYPE_AUDIO) {
  ------------------
  |  Branch (93:17): [True: 1.14M, False: 252k]
  ------------------
   94|  1.14M|                if (av_codec_is_decoder(s->codec))
  ------------------
  |  Branch (94:21): [True: 1.14M, False: 0]
  ------------------
   95|  1.14M|                    return log_decaudio;
   96|  1.14M|            } else if (s->codec->type == AVMEDIA_TYPE_VIDEO) {
  ------------------
  |  Branch (96:24): [True: 252k, False: 0]
  ------------------
   97|   252k|                if (av_codec_is_decoder(s->codec))
  ------------------
  |  Branch (97:21): [True: 252k, False: 0]
  ------------------
   98|   252k|                    return log_decvideo;
   99|   252k|            }
  100|  1.39M|        }
  101|  1.46M|    }
  102|       |
  103|   617k|    if (!strcmp(avc->class_name, "AVFormatContext")) {
  ------------------
  |  Branch (103:9): [True: 474k, False: 142k]
  ------------------
  104|   474k|        AVFormatContext *s = ptr;
  105|   474k|        if (s->iformat)
  ------------------
  |  Branch (105:13): [True: 474k, False: 0]
  ------------------
  106|   474k|            return log_demuxer;
  107|   474k|    }
  108|       |
  109|   142k|    return log_root;
  110|   617k|}
av_log.c:avclass_item_name:
  113|  2.01M|{
  114|  2.01M|    return (avc->item_name ? avc->item_name : av_default_item_name)(obj);
  ------------------
  |  Branch (114:13): [True: 2.01M, False: 0]
  ------------------
  115|  2.01M|}

mp_add_decoder:
   26|  2.58M|{
   27|  2.58M|    struct mp_decoder_entry entry = {
   28|  2.58M|        .codec = talloc_strdup(list, codec),
  ------------------
  |  |   50|  2.58M|#define talloc_strdup                   ta_xstrdup
  ------------------
   29|  2.58M|        .decoder = talloc_strdup(list, decoder),
  ------------------
  |  |   50|  2.58M|#define talloc_strdup                   ta_xstrdup
  ------------------
   30|  2.58M|        .desc = talloc_strdup(list, desc),
  ------------------
  |  |   50|  2.58M|#define talloc_strdup                   ta_xstrdup
  ------------------
   31|  2.58M|    };
   32|  2.58M|    MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry);
  ------------------
  |  |  105|  2.58M|    do {                                            \
  |  |  106|  2.58M|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  2.58M|    do {                                            \
  |  |  |  |   97|  2.58M|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  2.58M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  2.58M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  2.58M|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 90.9k, False: 2.49M]
  |  |  |  |  ------------------
  |  |  |  |   99|  2.58M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  90.9k|    do {                                                        \
  |  |  |  |  |  |   89|  90.9k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  90.9k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  90.9k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  90.9k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  90.9k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  90.9k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  90.9k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  2.58M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  2.58M|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  2.58M|        (idxvar)++;                                 \
  |  |  109|  2.58M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   33|  2.58M|}
mp_select_decoders:
   60|  10.4k|{
   61|  10.4k|    struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
  ------------------
  |  |   27|  10.4k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  10.4k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  10.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   62|  10.4k|    if (!codec)
  ------------------
  |  Branch (62:9): [True: 0, False: 10.4k]
  ------------------
   63|      0|        codec = "unknown";
   64|  10.4k|    bool stop = false;
   65|  10.4k|    bstr sel = bstr0(selection);
   66|  10.4k|    while (sel.len) {
  ------------------
  |  Branch (66:12): [True: 0, False: 10.4k]
  ------------------
   67|      0|        bstr entry;
   68|      0|        bstr_split_tok(sel, ",", &entry, &sel);
   69|      0|        if (bstr_equals0(entry, "-")) {
  ------------------
  |  Branch (69:13): [True: 0, False: 0]
  ------------------
   70|      0|            mp_warn(log, "Excluding codecs is deprecated.\n");
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
   71|      0|            stop = true;
   72|      0|            break;
   73|      0|        }
   74|      0|        for (int n = 0; n < all->num_entries; n++) {
  ------------------
  |  Branch (74:25): [True: 0, False: 0]
  ------------------
   75|      0|            struct mp_decoder_entry *cur = &all->entries[n];
   76|      0|            if (bstr_equals0(entry, cur->decoder))
  ------------------
  |  Branch (76:17): [True: 0, False: 0]
  ------------------
   77|      0|                add_new(list, cur, codec);
   78|      0|        }
   79|      0|    }
   80|  10.4k|    if (!stop) {
  ------------------
  |  Branch (80:9): [True: 10.4k, False: 0]
  ------------------
   81|       |        // Add the remaining codecs which haven't been added yet
   82|  2.57M|        for (int n = 0; n < all->num_entries; n++)
  ------------------
  |  Branch (82:25): [True: 2.56M, False: 10.4k]
  ------------------
   83|  2.56M|            add_new(list, &all->entries[n], codec);
   84|  10.4k|    }
   85|  10.4k|    return list;
   86|  10.4k|}
mp_print_decoders:
   96|  10.4k|{
   97|  10.4k|    mp_msg(log, msgl, "%s\n", header);
   98|  24.4k|    for (int n = 0; n < list->num_entries; n++) {
  ------------------
  |  Branch (98:21): [True: 14.0k, False: 10.4k]
  ------------------
   99|  14.0k|        struct mp_decoder_entry *entry = &list->entries[n];
  100|  14.0k|        mp_msg(log, msgl, "    %s", entry->decoder);
  101|  14.0k|        if (strcmp(entry->decoder, entry->codec) != 0)
  ------------------
  |  Branch (101:13): [True: 4.71k, False: 9.29k]
  ------------------
  102|  4.71k|            mp_msg(log, msgl, " (%s)", entry->codec);
  103|  14.0k|        mp_msg(log, msgl, " - %s\n", entry->desc);
  104|  14.0k|    }
  105|  10.4k|    if (list->num_entries == 0)
  ------------------
  |  Branch (105:9): [True: 891, False: 9.53k]
  ------------------
  106|    891|        mp_msg(log, msgl, "    (no decoders)\n");
  107|  10.4k|}
codecs.c:add_new:
   39|  2.56M|{
   40|  2.56M|    if (!entry || (codec && strcmp(entry->codec, codec) != 0))
  ------------------
  |  Branch (40:9): [True: 0, False: 2.56M]
  |  Branch (40:20): [True: 2.56M, False: 0]
  |  Branch (40:29): [True: 2.55M, False: 14.0k]
  ------------------
   41|  2.55M|        return;
   42|  14.0k|    mp_add_decoder(to, entry->codec, entry->decoder, entry->desc);
   43|  14.0k|}

mp_format_double:
   99|    255|{
  100|    255|    bstr str = {0};
  101|    255|    const char *fmt = plus_sign ? "%+.*f" : "%.*f";
  ------------------
  |  Branch (101:23): [True: 0, False: 255]
  ------------------
  102|    255|    bstr_xappend_asprintf(talloc_ctx, &str, fmt, precision, val);
  103|    255|    size_t pos = str.len;
  104|    255|    if (trim) {
  ------------------
  |  Branch (104:9): [True: 255, False: 0]
  ------------------
  105|  1.20k|        while (--pos && str.start[pos] == '0')
  ------------------
  |  Branch (105:16): [True: 1.20k, False: 0]
  |  Branch (105:25): [True: 951, False: 255]
  ------------------
  106|    951|            str.len--;
  107|    255|        if (str.start[pos] == '.')
  ------------------
  |  Branch (107:13): [True: 236, False: 19]
  ------------------
  108|    236|            str.len--;
  109|    255|    }
  110|    255|    if (percent_sign)
  ------------------
  |  Branch (110:9): [True: 0, False: 255]
  ------------------
  111|      0|        bstr_xappend(talloc_ctx, &str, bstr0("%"));
  112|    255|    str.start[str.len] = '\0';
  113|    255|    return str.start;
  114|    255|}
mp_rect_equals:
  144|   511k|{
  145|   511k|    return rc1->x0 == rc2->x0 && rc1->y0 == rc2->y0 &&
  ------------------
  |  Branch (145:12): [True: 511k, False: 0]
  |  Branch (145:34): [True: 511k, False: 0]
  ------------------
  146|   511k|           rc1->x1 == rc2->x1 && rc1->y1 == rc2->y1;
  ------------------
  |  Branch (146:12): [True: 511k, False: 0]
  |  Branch (146:34): [True: 511k, False: 0]
  ------------------
  147|   511k|}
mp_snprintf_cat:
  214|   485k|{
  215|   485k|    size_t len = strnlen(str, size);
  216|   485k|    mp_assert(!size || len < size); // str with no 0-termination is not allowed
  ------------------
  |  |   41|   485k|#define mp_assert assert
  ------------------
  217|   485k|    int r;
  218|   485k|    va_list ap;
  219|   485k|    va_start(ap, format);
  220|   485k|    r = vsnprintf(str + len, size - len, format, ap);
  221|   485k|    va_end(ap);
  222|   485k|    return r;
  223|   485k|}
mp_append_utf8_bstr:
  229|  4.55M|{
  230|  4.55M|    char data[8];
  231|  4.55M|    uint8_t tmp;
  232|  4.55M|    char *output = data;
  233|  4.55M|    PUT_UTF8(codepoint, tmp, *output++ = tmp;);
  234|  4.55M|    bstr_xappend(talloc_ctx, buf, (bstr){data, output - data});
  235|  4.55M|}
mp_append_escaped_string_noalloc:
  300|  58.1k|{
  301|  58.1k|    bstr t = *src;
  302|  58.1k|    int cur = 0;
  303|   267k|    while (1) {
  ------------------
  |  Branch (303:12): [Folded - Ignored]
  ------------------
  304|   267k|        if (cur >= t.len || t.start[cur] == '"') {
  ------------------
  |  Branch (304:13): [True: 0, False: 267k]
  |  Branch (304:29): [True: 58.1k, False: 209k]
  ------------------
  305|  58.1k|            *src = bstr_cut(t, cur);
  306|  58.1k|            t = bstr_splice(t, 0, cur);
  307|  58.1k|            if (dst->start == NULL) {
  ------------------
  |  Branch (307:17): [True: 58.1k, False: 0]
  ------------------
  308|  58.1k|                *dst = t;
  309|  58.1k|            } else {
  310|      0|                bstr_xappend(talloc_ctx, dst, t);
  311|      0|            }
  312|  58.1k|            return true;
  313|   209k|        } else if (t.start[cur] == '\\') {
  ------------------
  |  Branch (313:20): [True: 0, False: 209k]
  ------------------
  314|      0|            bstr_xappend(talloc_ctx, dst, bstr_splice(t, 0, cur));
  315|      0|            t = bstr_cut(t, cur + 1);
  316|      0|            cur = 0;
  317|      0|            if (!mp_parse_escape(talloc_ctx, dst, &t))
  ------------------
  |  Branch (317:17): [True: 0, False: 0]
  ------------------
  318|      0|                goto error;
  319|   209k|        } else {
  320|   209k|            cur++;
  321|   209k|        }
  322|   267k|    }
  323|      0|error:
  324|      0|    return false;
  325|  58.1k|}
mp_strerror_buf:
  353|    663|{
  354|       |    // This handles the nasty details of calling the right function for us.
  355|    663|    av_strerror(AVERROR(errnum), buf, buf_size);
  356|    663|    return buf;
  357|    663|}
mp_dup_str_array:
  385|  18.1k|{
  386|  18.1k|    char **r = NULL;
  387|  18.1k|    int num_r = 0;
  388|  18.1k|    for (int n = 0; s && s[n]; n++)
  ------------------
  |  Branch (388:21): [True: 0, False: 18.1k]
  |  Branch (388:26): [True: 0, False: 0]
  ------------------
  389|      0|        MP_TARRAY_APPEND(tctx, r, num_r, talloc_strdup(tctx, s[n]));
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  390|  18.1k|    if (r)
  ------------------
  |  Branch (390:9): [True: 0, False: 18.1k]
  ------------------
  391|      0|        MP_TARRAY_APPEND(tctx, r, num_r, NULL);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  392|  18.1k|    return r;
  393|  18.1k|}
mp_log2:
  401|  6.73M|{
  402|  6.73M|#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
  403|  6.73M|    return v ? 31 - __builtin_clz(v) : 0;
  ------------------
  |  Branch (403:12): [True: 5.97M, False: 761k]
  ------------------
  404|       |#else
  405|       |    for (int x = 31; x >= 0; x--) {
  406|       |        if (v & (((uint32_t)1) << x))
  407|       |            return x;
  408|       |    }
  409|       |    return 0;
  410|       |#endif
  411|  6.73M|}
mp_round_next_power_of_2:
  419|   692k|{
  420|   692k|    if (!v)
  ------------------
  |  Branch (420:9): [True: 0, False: 692k]
  ------------------
  421|      0|        return 1;
  422|   692k|    if (!(v & (v - 1)))
  ------------------
  |  Branch (422:9): [True: 691k, False: 498]
  ------------------
  423|   691k|        return v;
  424|    498|    int l = mp_log2(v) + 1;
  425|    498|    return l == 32 ? 0 : (uint32_t)1 << l;
  ------------------
  |  Branch (425:12): [True: 0, False: 498]
  ------------------
  426|   692k|}
mp_lcm:
  429|   104k|{
  430|   104k|    mp_assert(x && y);
  ------------------
  |  |   41|   104k|#define mp_assert assert
  ------------------
  431|   104k|    return x * (y / av_gcd(x, y));
  432|   104k|}

encode_lavc_free:
  188|  5.81k|{
  189|  5.81k|    bool res = true;
  190|  5.81k|    if (!ctx)
  ------------------
  |  Branch (190:9): [True: 5.81k, False: 0]
  ------------------
  191|  5.81k|        return res;
  192|       |
  193|      0|    struct encode_priv *p = ctx->priv;
  194|       |
  195|      0|    if (!p->failed && !p->header_written) {
  ------------------
  |  Branch (195:9): [True: 0, False: 0]
  |  Branch (195:23): [True: 0, False: 0]
  ------------------
  196|      0|        MP_FATAL(p, "no data written to target file\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  197|      0|        p->failed = true;
  198|      0|    }
  199|       |
  200|      0|    if (!p->failed && p->header_written) {
  ------------------
  |  Branch (200:9): [True: 0, False: 0]
  |  Branch (200:23): [True: 0, False: 0]
  ------------------
  201|      0|        if (av_write_trailer(p->muxer) < 0)
  ------------------
  |  Branch (201:13): [True: 0, False: 0]
  ------------------
  202|      0|            MP_ERR(p, "error writing trailer\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  203|       |
  204|      0|        MP_INFO(p, "video: encoded %lld bytes\n", p->vbytes);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  205|      0|        MP_INFO(p, "audio: encoded %lld bytes\n", p->abytes);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  206|       |
  207|      0|        MP_INFO(p, "muxing overhead %lld bytes\n",
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  208|      0|                (long long)(avio_size(p->muxer->pb) - p->vbytes - p->abytes));
  209|      0|    }
  210|       |
  211|      0|    if (avio_closep(&p->muxer->pb) < 0 && !p->failed) {
  ------------------
  |  Branch (211:9): [True: 0, False: 0]
  |  Branch (211:43): [True: 0, False: 0]
  ------------------
  212|      0|        MP_ERR(p, "Closing file failed\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  213|      0|        p->failed = true;
  214|      0|    }
  215|       |
  216|      0|    avformat_free_context(p->muxer);
  217|       |
  218|      0|    res = !p->failed;
  219|       |
  220|      0|    mp_mutex_destroy(&ctx->lock);
  ------------------
  |  |  130|      0|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  221|      0|    talloc_free(ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  222|       |
  223|      0|    return res;
  224|  5.81k|}
encode_lavc_discontinuity:
  446|  94.7k|{
  447|  94.7k|    if (!ctx)
  ------------------
  |  Branch (447:9): [True: 94.7k, False: 0]
  ------------------
  448|  94.7k|        return;
  449|       |
  450|      0|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  451|      0|    ctx->discontinuity_pts_offset = MP_NOPTS_VALUE;
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  452|      0|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  453|      0|}
encode_lavc_showhelp:
  530|  5.81k|{
  531|  5.81k|    bool help_output = false;
  532|  5.81k|#define CHECKS(str) ((str) && \
  533|  5.81k|                     strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
  534|  5.81k|#define CHECKV(strv) ((strv) && (strv)[0] && \
  535|  5.81k|                      strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
  536|  5.81k|    if (CHECKS(opts->format)) {
  ------------------
  |  |  532|  5.81k|#define CHECKS(str) ((str) && \
  |  |  ------------------
  |  |  |  Branch (532:21): [True: 0, False: 5.81k]
  |  |  |  Branch (532:22): [True: 0, False: 5.81k]
  |  |  ------------------
  |  |  533|  5.81k|                     strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (533:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  537|      0|        const AVOutputFormat *c = NULL;
  538|      0|        void *iter = NULL;
  539|      0|        mp_info(log, "Available output formats:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  540|      0|        while ((c = av_muxer_iterate(&iter))) {
  ------------------
  |  Branch (540:16): [True: 0, False: 0]
  ------------------
  541|      0|            mp_info(log, "  --of=%-13s %s\n", c->name,
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (74:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  542|      0|                   c->long_name ? c->long_name : "");
  543|      0|        }
  544|      0|    }
  545|  5.81k|    if (CHECKV(opts->fopts)) {
  ------------------
  |  |  534|  5.81k|#define CHECKV(strv) ((strv) && (strv)[0] && \
  |  |  ------------------
  |  |  |  Branch (534:22): [True: 0, False: 5.81k]
  |  |  |  Branch (534:23): [True: 0, False: 5.81k]
  |  |  |  Branch (534:33): [True: 0, False: 0]
  |  |  ------------------
  |  |  535|  5.81k|                      strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (535:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  546|      0|        AVFormatContext *c = avformat_alloc_context();
  547|      0|        const AVOutputFormat *format = NULL;
  548|      0|        mp_info(log, "Available output format ctx->options:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  549|      0|        encode_lavc_printoptions(log, c, "  --ofopts=", "           ", NULL,
  550|      0|                                 AV_OPT_FLAG_ENCODING_PARAM,
  551|      0|                                 AV_OPT_FLAG_ENCODING_PARAM);
  552|      0|        avformat_free_context(c);
  553|      0|        void *iter = NULL;
  554|      0|        while ((format = av_muxer_iterate(&iter))) {
  ------------------
  |  Branch (554:16): [True: 0, False: 0]
  ------------------
  555|      0|            if (format->priv_class) {
  ------------------
  |  Branch (555:17): [True: 0, False: 0]
  ------------------
  556|      0|                mp_info(log, "Additionally, for --of=%s:\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  557|      0|                       format->name);
  558|      0|                encode_lavc_printoptions(log, &format->priv_class, "  --ofopts=",
  559|      0|                                         "           ", NULL,
  560|      0|                                         AV_OPT_FLAG_ENCODING_PARAM,
  561|      0|                                         AV_OPT_FLAG_ENCODING_PARAM);
  562|      0|            }
  563|      0|        }
  564|      0|    }
  565|  5.81k|    if (CHECKV(opts->vopts)) {
  ------------------
  |  |  534|  5.81k|#define CHECKV(strv) ((strv) && (strv)[0] && \
  |  |  ------------------
  |  |  |  Branch (534:22): [True: 0, False: 5.81k]
  |  |  |  Branch (534:23): [True: 0, False: 5.81k]
  |  |  |  Branch (534:33): [True: 0, False: 0]
  |  |  ------------------
  |  |  535|  5.81k|                      strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (535:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  566|      0|        AVCodecContext *c = avcodec_alloc_context3(NULL);
  567|      0|        const AVCodec *codec = NULL;
  568|      0|        mp_info(log, "Available output video codec ctx->options:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  569|      0|        encode_lavc_printoptions(log,
  570|      0|            c, "  --ovcopts=", "            ", NULL,
  571|      0|            AV_OPT_FLAG_ENCODING_PARAM |
  572|      0|            AV_OPT_FLAG_VIDEO_PARAM,
  573|      0|            AV_OPT_FLAG_ENCODING_PARAM |
  574|      0|            AV_OPT_FLAG_VIDEO_PARAM);
  575|      0|        av_free(c);
  576|      0|        void *iter = NULL;
  577|      0|        while ((codec = av_codec_iterate(&iter))) {
  ------------------
  |  Branch (577:16): [True: 0, False: 0]
  ------------------
  578|      0|            if (!av_codec_is_encoder(codec))
  ------------------
  |  Branch (578:17): [True: 0, False: 0]
  ------------------
  579|      0|                continue;
  580|      0|            if (codec->type != AVMEDIA_TYPE_VIDEO)
  ------------------
  |  Branch (580:17): [True: 0, False: 0]
  ------------------
  581|      0|                continue;
  582|      0|            if (opts->vcodec && opts->vcodec[0] &&
  ------------------
  |  Branch (582:17): [True: 0, False: 0]
  |  Branch (582:33): [True: 0, False: 0]
  ------------------
  583|      0|                strcmp(opts->vcodec, codec->name) != 0)
  ------------------
  |  Branch (583:17): [True: 0, False: 0]
  ------------------
  584|      0|                continue;
  585|      0|            if (codec->priv_class) {
  ------------------
  |  Branch (585:17): [True: 0, False: 0]
  ------------------
  586|      0|                mp_info(log, "Additionally, for --ovc=%s:\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  587|      0|                       codec->name);
  588|      0|                encode_lavc_printoptions(log,
  589|      0|                    &codec->priv_class, "  --ovcopts=",
  590|      0|                    "            ", NULL,
  591|      0|                    AV_OPT_FLAG_ENCODING_PARAM |
  592|      0|                    AV_OPT_FLAG_VIDEO_PARAM,
  593|      0|                    AV_OPT_FLAG_ENCODING_PARAM |
  594|      0|                    AV_OPT_FLAG_VIDEO_PARAM);
  595|      0|            }
  596|      0|        }
  597|      0|    }
  598|  5.81k|    if (CHECKV(opts->aopts)) {
  ------------------
  |  |  534|  5.81k|#define CHECKV(strv) ((strv) && (strv)[0] && \
  |  |  ------------------
  |  |  |  Branch (534:22): [True: 0, False: 5.81k]
  |  |  |  Branch (534:23): [True: 0, False: 5.81k]
  |  |  |  Branch (534:33): [True: 0, False: 0]
  |  |  ------------------
  |  |  535|  5.81k|                      strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (535:23): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  599|      0|        AVCodecContext *c = avcodec_alloc_context3(NULL);
  600|      0|        const AVCodec *codec = NULL;
  601|      0|        mp_info(log, "Available output audio codec ctx->options:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  602|      0|        encode_lavc_printoptions(log,
  603|      0|            c, "  --oacopts=", "            ", NULL,
  604|      0|            AV_OPT_FLAG_ENCODING_PARAM |
  605|      0|            AV_OPT_FLAG_AUDIO_PARAM,
  606|      0|            AV_OPT_FLAG_ENCODING_PARAM |
  607|      0|            AV_OPT_FLAG_AUDIO_PARAM);
  608|      0|        av_free(c);
  609|      0|        void *iter = NULL;
  610|      0|        while ((codec = av_codec_iterate(&iter))) {
  ------------------
  |  Branch (610:16): [True: 0, False: 0]
  ------------------
  611|      0|            if (!av_codec_is_encoder(codec))
  ------------------
  |  Branch (611:17): [True: 0, False: 0]
  ------------------
  612|      0|                continue;
  613|      0|            if (codec->type != AVMEDIA_TYPE_AUDIO)
  ------------------
  |  Branch (613:17): [True: 0, False: 0]
  ------------------
  614|      0|                continue;
  615|      0|            if (opts->acodec && opts->acodec[0] &&
  ------------------
  |  Branch (615:17): [True: 0, False: 0]
  |  Branch (615:33): [True: 0, False: 0]
  ------------------
  616|      0|                strcmp(opts->acodec, codec->name) != 0)
  ------------------
  |  Branch (616:17): [True: 0, False: 0]
  ------------------
  617|      0|                continue;
  618|      0|            if (codec->priv_class) {
  ------------------
  |  Branch (618:17): [True: 0, False: 0]
  ------------------
  619|      0|                mp_info(log, "Additionally, for --oac=%s:\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  620|      0|                       codec->name);
  621|      0|                encode_lavc_printoptions(log,
  622|      0|                    &codec->priv_class, "  --oacopts=",
  623|      0|                    "           ", NULL,
  624|      0|                    AV_OPT_FLAG_ENCODING_PARAM |
  625|      0|                    AV_OPT_FLAG_AUDIO_PARAM,
  626|      0|                    AV_OPT_FLAG_ENCODING_PARAM |
  627|      0|                    AV_OPT_FLAG_AUDIO_PARAM);
  628|      0|            }
  629|      0|        }
  630|      0|    }
  631|  5.81k|    if (CHECKS(opts->vcodec)) {
  ------------------
  |  |  532|  5.81k|#define CHECKS(str) ((str) && \
  |  |  ------------------
  |  |  |  Branch (532:21): [True: 0, False: 5.81k]
  |  |  |  Branch (532:22): [True: 0, False: 5.81k]
  |  |  ------------------
  |  |  533|  5.81k|                     strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (533:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  632|      0|        const AVCodec *c = NULL;
  633|      0|        void *iter = NULL;
  634|      0|        mp_info(log, "Available output video codecs:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  635|      0|        while ((c = av_codec_iterate(&iter))) {
  ------------------
  |  Branch (635:16): [True: 0, False: 0]
  ------------------
  636|      0|            if (!av_codec_is_encoder(c))
  ------------------
  |  Branch (636:17): [True: 0, False: 0]
  ------------------
  637|      0|                continue;
  638|      0|            if (c->type != AVMEDIA_TYPE_VIDEO)
  ------------------
  |  Branch (638:17): [True: 0, False: 0]
  ------------------
  639|      0|                continue;
  640|      0|            mp_info(log, "  --ovc=%-12s %s\n", c->name,
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (74:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  641|      0|                   c->long_name ? c->long_name : "");
  642|      0|        }
  643|      0|    }
  644|  5.81k|    if (CHECKS(opts->acodec)) {
  ------------------
  |  |  532|  5.81k|#define CHECKS(str) ((str) && \
  |  |  ------------------
  |  |  |  Branch (532:21): [True: 0, False: 5.81k]
  |  |  |  Branch (532:22): [True: 0, False: 5.81k]
  |  |  ------------------
  |  |  533|  5.81k|                     strcmp((str), "help") == 0 ? (help_output |= 1) : 0)
  |  |  ------------------
  |  |  |  Branch (533:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  645|      0|        const AVCodec *c = NULL;
  646|      0|        void *iter = NULL;
  647|      0|        mp_info(log, "Available output audio codecs:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  648|      0|        while ((c = av_codec_iterate(&iter))) {
  ------------------
  |  Branch (648:16): [True: 0, False: 0]
  ------------------
  649|      0|            if (!av_codec_is_encoder(c))
  ------------------
  |  Branch (649:17): [True: 0, False: 0]
  ------------------
  650|      0|                continue;
  651|      0|            if (c->type != AVMEDIA_TYPE_AUDIO)
  ------------------
  |  Branch (651:17): [True: 0, False: 0]
  ------------------
  652|      0|                continue;
  653|      0|            mp_info(log, "  --oac=%-12s %s\n", c->name,
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (74:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  654|      0|                   c->long_name ? c->long_name : "");
  655|      0|        }
  656|      0|    }
  657|  5.81k|    return help_output;
  658|  5.81k|}
encode_lavc_didfail:
  702|   188k|{
  703|   188k|    if (!ctx)
  ------------------
  |  Branch (703:9): [True: 188k, False: 0]
  ------------------
  704|   188k|        return false;
  705|      0|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  706|      0|    bool fail = ctx->priv->failed;
  707|      0|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  708|      0|    return fail;
  709|   188k|}

mp_msg_level:
  182|  18.5M|{
  183|  18.5M|    struct mp_log_root *root = log->root;
  184|  18.5M|    if (!root)
  ------------------
  |  Branch (184:9): [True: 273k, False: 18.2M]
  ------------------
  185|   273k|        return -1;
  186|  18.2M|    if (atomic_load_explicit(&log->reload_counter, memory_order_relaxed) !=
  ------------------
  |  Branch (186:9): [True: 169k, False: 18.1M]
  ------------------
  187|  18.2M|        atomic_load_explicit(&root->reload_counter, memory_order_relaxed))
  188|   169k|    {
  189|   169k|        update_loglevel(log);
  190|   169k|    }
  191|  18.2M|    return log->level;
  192|  18.5M|}
mp_msg_flush_status_line:
  289|   100k|{
  290|   100k|    if (!log->root)
  ------------------
  |  Branch (290:9): [True: 0, False: 100k]
  ------------------
  291|      0|        return;
  292|       |
  293|   100k|    mp_mutex_lock(&log->root->lock);
  ------------------
  |  |  131|   100k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  294|   100k|    msg_flush_status_line(log->root, clear);
  295|   100k|    mp_mutex_unlock(&log->root->lock);
  ------------------
  |  |  133|   100k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  296|   100k|}
mp_msg_va:
  563|  15.2M|{
  564|  15.2M|    if (!mp_msg_test(log, lev))
  ------------------
  |  Branch (564:9): [True: 2.71M, False: 12.5M]
  ------------------
  565|  2.71M|        return; // do not display
  566|       |
  567|  12.5M|    struct mp_log_root *root = log->root;
  568|       |
  569|  12.5M|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  12.5M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  570|       |
  571|  12.5M|    root->buffer.len = 0;
  572|       |
  573|  12.5M|    if (log->partial[lev].len)
  ------------------
  |  Branch (573:9): [True: 316k, False: 12.2M]
  ------------------
  574|   316k|        bstr_xappend(root, &root->buffer, log->partial[lev]);
  575|  12.5M|    log->partial[lev].len = 0;
  576|       |
  577|  12.5M|    if (bstr_xappend_vasprintf(root, &root->buffer, format, va) < 0) {
  ------------------
  |  Branch (577:9): [True: 0, False: 12.5M]
  ------------------
  578|      0|        bstr_xappend(root, &root->buffer, bstr0("format error: "));
  579|      0|        bstr_xappend(root, &root->buffer, bstr0(format));
  580|      0|    }
  581|       |
  582|       |    // Remember last status message and restore it to ensure that it is
  583|       |    // always displayed
  584|  12.5M|    if (lev == MSGL_STATUS) {
  ------------------
  |  Branch (584:9): [True: 0, False: 12.5M]
  ------------------
  585|      0|        root->status_log = log;
  586|      0|        root->status_line.len = 0;
  587|       |        // Use bstr_xappend instead bstrdup to reuse allocated memory
  588|      0|        if (root->buffer.len)
  ------------------
  |  Branch (588:13): [True: 0, False: 0]
  ------------------
  589|      0|            bstr_xappend(root, &root->status_line, root->buffer);
  590|      0|    }
  591|       |
  592|  12.5M|    if (lev == MSGL_STATS) {
  ------------------
  |  Branch (592:9): [True: 0, False: 12.5M]
  ------------------
  593|      0|        dump_stats(log, lev, root->buffer);
  594|  12.5M|    } else if (lev == MSGL_STATUS && !test_terminal_level(log, lev)) {
  ------------------
  |  Branch (594:16): [True: 0, False: 12.5M]
  |  Branch (594:38): [True: 0, False: 0]
  ------------------
  595|       |        /* discard */
  596|  12.5M|    } else {
  597|  12.5M|        write_term_msg(log, lev, root->buffer, &root->term_msg);
  598|       |
  599|  12.5M|        FILE *stream = term_msg_fp(root, lev);
  600|  12.5M|        if (root->term_msg.len) {
  ------------------
  |  Branch (600:13): [True: 0, False: 12.5M]
  ------------------
  601|      0|            root->term_status_msg.len = 0;
  602|      0|            if (lev != MSGL_STATUS && root->status_line.len && root->status_log &&
  ------------------
  |  Branch (602:17): [True: 0, False: 0]
  |  Branch (602:39): [True: 0, False: 0]
  |  Branch (602:64): [True: 0, False: 0]
  ------------------
  603|      0|                is_status_output(root, lev) && test_terminal_level(root->status_log, MSGL_STATUS))
  ------------------
  |  Branch (603:17): [True: 0, False: 0]
  |  Branch (603:48): [True: 0, False: 0]
  ------------------
  604|      0|            {
  605|      0|                write_term_msg(root->status_log, MSGL_STATUS, root->status_line,
  606|      0|                               &root->term_status_msg);
  607|      0|            }
  608|      0|            fwrite(root->term_msg.start, root->term_msg.len, 1, stream);
  609|      0|            if (root->term_status_msg.len)
  ------------------
  |  Branch (609:17): [True: 0, False: 0]
  ------------------
  610|      0|                fwrite(root->term_status_msg.start, root->term_status_msg.len, 1, stream);
  611|      0|            fflush(stream);
  612|      0|        }
  613|  12.5M|    }
  614|       |
  615|  12.5M|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  12.5M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  616|  12.5M|}
mp_log_new:
  638|   559k|{
  639|   559k|    mp_assert(parent);
  ------------------
  |  |   41|   559k|#define mp_assert assert
  ------------------
  640|   559k|    struct mp_log *log = talloc_zero(talloc_ctx, struct mp_log);
  ------------------
  |  |   27|   559k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   559k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   559k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  641|   559k|    if (!parent->root)
  ------------------
  |  Branch (641:9): [True: 0, False: 559k]
  ------------------
  642|      0|        return log; // same as null_log
  643|   559k|    talloc_set_destructor(log, destroy_log);
  ------------------
  |  |   41|   559k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  644|   559k|    log->root = parent->root;
  645|   559k|    log->max_level = MSGL_MAX;
  646|   559k|    if (name) {
  ------------------
  |  Branch (646:9): [True: 549k, False: 9.53k]
  ------------------
  647|   549k|        if (name[0] == '!') {
  ------------------
  |  Branch (647:13): [True: 142k, False: 407k]
  ------------------
  648|   142k|            name = &name[1];
  649|   407k|        } else if (name[0] == '/') {
  ------------------
  |  Branch (649:20): [True: 0, False: 407k]
  ------------------
  650|      0|            name = &name[1];
  651|      0|            log->prefix = talloc_strdup(log, name);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  652|   407k|        } else {
  653|   407k|            log->prefix = parent->prefix
  ------------------
  |  Branch (653:27): [True: 27.3k, False: 380k]
  ------------------
  654|   407k|                    ? talloc_asprintf(log, "%s/%s", parent->prefix, name)
  ------------------
  |  |   52|  27.3k|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|  27.3k|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  655|   407k|                    : talloc_strdup(log, name);
  ------------------
  |  |   50|   380k|#define talloc_strdup                   ta_xstrdup
  ------------------
  656|   407k|        }
  657|   549k|        log->verbose_prefix = parent->prefix
  ------------------
  |  Branch (657:31): [True: 27.3k, False: 522k]
  ------------------
  658|   549k|                ? talloc_asprintf(log, "%s/%s", parent->prefix, name)
  ------------------
  |  |   52|  27.3k|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|  27.3k|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  659|   549k|                : talloc_strdup(log, name);
  ------------------
  |  |   50|   522k|#define talloc_strdup                   ta_xstrdup
  ------------------
  660|   549k|        if (log->prefix && !log->prefix[0])
  ------------------
  |  Branch (660:13): [True: 407k, False: 142k]
  |  Branch (660:28): [True: 5.81k, False: 401k]
  ------------------
  661|  5.81k|            log->prefix = NULL;
  662|   549k|        if (!log->verbose_prefix[0])
  ------------------
  |  Branch (662:13): [True: 5.81k, False: 544k]
  ------------------
  663|  5.81k|            log->verbose_prefix = "global";
  664|   549k|    } else {
  665|  9.53k|        log->prefix = talloc_strdup(log, parent->prefix);
  ------------------
  |  |   50|  9.53k|#define talloc_strdup                   ta_xstrdup
  ------------------
  666|  9.53k|        log->verbose_prefix = talloc_strdup(log, parent->verbose_prefix);
  ------------------
  |  |   50|  9.53k|#define talloc_strdup                   ta_xstrdup
  ------------------
  667|  9.53k|    }
  668|   559k|    return log;
  669|   559k|}
mp_msg_init:
  672|  5.81k|{
  673|  5.81k|    mp_assert(!global->log);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  674|       |
  675|  5.81k|    struct mp_log_root *root = talloc_zero(NULL, struct mp_log_root);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  676|  5.81k|    *root = (struct mp_log_root){
  677|  5.81k|        .global = global,
  678|  5.81k|        .reload_counter = 1,
  679|  5.81k|    };
  680|       |
  681|  5.81k|    mp_mutex_init(&root->lock);
  682|  5.81k|    mp_mutex_init(&root->log_file_lock);
  683|  5.81k|    mp_cond_init(&root->log_file_wakeup);
  684|       |
  685|  5.81k|    struct mp_log dummy = { .root = root };
  686|  5.81k|    struct mp_log *log = mp_log_new(root, &dummy, "");
  687|       |
  688|  5.81k|    global->log = log;
  689|  5.81k|}
mp_msg_update_msglevels:
  782|  11.6k|{
  783|  11.6k|    struct mp_log_root *root = global->log->root;
  784|       |
  785|  11.6k|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  11.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  786|       |
  787|  11.6k|    root->verbose = opts->verbose;
  788|  11.6k|    root->really_quiet = opts->msg_really_quiet;
  789|  11.6k|    root->module = opts->msg_module;
  790|  11.6k|    root->use_terminal = opts->use_terminal;
  791|  11.6k|    root->show_time = opts->msg_time;
  792|       |
  793|  11.6k|    if (root->really_quiet)
  ------------------
  |  Branch (793:9): [True: 0, False: 11.6k]
  ------------------
  794|      0|        root->status_lines = 0;
  795|       |
  796|  11.6k|    for (int i = STDOUT_FILENO; i <= STDERR_FILENO && root->use_terminal; ++i) {
  ------------------
  |  Branch (796:33): [True: 11.6k, False: 0]
  |  Branch (796:55): [True: 0, False: 11.6k]
  ------------------
  797|      0|        root->isatty[i] = isatty(i);
  798|      0|        root->color[i] = opts->msg_color && root->isatty[i];
  ------------------
  |  Branch (798:26): [True: 0, False: 0]
  |  Branch (798:45): [True: 0, False: 0]
  ------------------
  799|      0|    }
  800|       |
  801|  11.6k|    m_option_type_msglevels.free(&root->msg_levels);
  802|  11.6k|    m_option_type_msglevels.copy(NULL, &root->msg_levels, &opts->msg_levels);
  803|       |
  804|  11.6k|    atomic_fetch_add(&root->reload_counter, 1);
  805|  11.6k|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  806|       |
  807|  11.6k|    if (check_new_path(global, opts->log_file, &root->log_path)) {
  ------------------
  |  Branch (807:9): [True: 0, False: 11.6k]
  ------------------
  808|      0|        terminate_log_file_thread(root);
  809|      0|        if (root->log_path) {
  ------------------
  |  Branch (809:13): [True: 0, False: 0]
  ------------------
  810|      0|            root->log_file = fopen(root->log_path, "wb");
  811|      0|            if (root->log_file) {
  ------------------
  |  Branch (811:17): [True: 0, False: 0]
  ------------------
  812|       |
  813|       |                // if a logfile is created and the early filebuf still exists,
  814|       |                // flush and destroy the early buffer
  815|      0|                mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  816|      0|                struct mp_log_buffer *earlybuf = root->early_filebuffer;
  817|      0|                if (earlybuf)
  ------------------
  |  Branch (817:21): [True: 0, False: 0]
  ------------------
  818|      0|                    root->early_filebuffer = NULL;  // but it still logs msgs
  819|      0|                mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  820|       |
  821|      0|                if (earlybuf) {
  ------------------
  |  Branch (821:21): [True: 0, False: 0]
  ------------------
  822|       |                    // flush, destroy before creating the normal logfile buf,
  823|       |                    // as once the new one is created (specifically, its write
  824|       |                    // thread), then MSGL_LOGFILE messages become blocking, but
  825|       |                    // the early logfile buf is without dequeue - can deadlock.
  826|       |                    // note: timestamp is unknown, we use 0.000 as indication.
  827|       |                    // note: new messages while iterating are still flushed.
  828|      0|                    struct mp_log_buffer_entry *e;
  829|      0|                    while ((e = mp_msg_log_buffer_read(earlybuf))) {
  ------------------
  |  Branch (829:28): [True: 0, False: 0]
  ------------------
  830|      0|                        fprintf(root->log_file, "[%8.3f][%c][%s] %s", 0.0,
  831|      0|                                mp_log_levels[e->level][0], e->prefix, e->text);
  832|      0|                        talloc_free(e);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  833|      0|                    }
  834|      0|                    mp_msg_log_buffer_destroy(earlybuf);  // + remove from root
  835|      0|                }
  836|       |
  837|      0|                root->log_file_buffer =
  838|      0|                    mp_msg_log_buffer_new(global, FILE_BUF, MP_LOG_BUFFER_MSGL_LOGFILE,
  ------------------
  |  |   44|      0|#define FILE_BUF 100
  ------------------
                                  mp_msg_log_buffer_new(global, FILE_BUF, MP_LOG_BUFFER_MSGL_LOGFILE,
  ------------------
  |  |   29|      0|#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
  ------------------
  839|      0|                                          wakeup_log_file, root);
  840|      0|                root->log_file_thread_active = true;
  841|      0|                if (mp_thread_create(&root->log_file_thread, log_file_thread,
  ------------------
  |  |  211|      0|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  842|      0|                                   root))
  843|      0|                {
  844|      0|                    root->log_file_thread_active = false;
  845|      0|                    terminate_log_file_thread(root);
  846|      0|                }
  847|      0|            } else {
  848|      0|                mp_err(global->log, "Failed to open log file '%s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  849|      0|                       root->log_path);
  850|      0|            }
  851|      0|        }
  852|      0|    }
  853|       |
  854|  11.6k|    if (check_new_path(global, opts->dump_stats, &root->stats_path)) {
  ------------------
  |  Branch (854:9): [True: 0, False: 11.6k]
  ------------------
  855|      0|        bool open_error = false;
  856|       |
  857|      0|        mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  858|      0|        if (root->stats_file)
  ------------------
  |  Branch (858:13): [True: 0, False: 0]
  ------------------
  859|      0|            fclose(root->stats_file);
  860|      0|        root->stats_file = NULL;
  861|      0|        if (root->stats_path) {
  ------------------
  |  Branch (861:13): [True: 0, False: 0]
  ------------------
  862|      0|            root->stats_file = fopen(root->stats_path, "wb");
  863|      0|            open_error = !root->stats_file;
  864|      0|        }
  865|      0|        mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  866|       |
  867|      0|        if (open_error) {
  ------------------
  |  Branch (867:13): [True: 0, False: 0]
  ------------------
  868|      0|            mp_err(global->log, "Failed to open stats file '%s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  869|      0|                   root->stats_path);
  870|      0|        }
  871|      0|    }
  872|  11.6k|}
mp_msg_has_log_file:
  885|  23.2k|{
  886|  23.2k|    struct mp_log_root *root = global->log->root;
  887|       |
  888|  23.2k|    return !!root->log_file;
  889|  23.2k|}
mp_msg_uninit:
  892|  5.81k|{
  893|  5.81k|    struct mp_log_root *root = global->log->root;
  894|  5.81k|    mp_msg_flush_status_line(global->log, true);
  895|  5.81k|    if (root->really_quiet && root->isatty[term_msg_fileno(root, MSGL_STATUS)])
  ------------------
  |  Branch (895:9): [True: 0, False: 5.81k]
  |  Branch (895:31): [True: 0, False: 0]
  ------------------
  896|      0|        fprintf(term_msg_fp(root, MSGL_STATUS), TERM_ESC_RESTORE_CURSOR);
  ------------------
  |  |   30|      0|#define TERM_ESC_RESTORE_CURSOR     "\033[?25h"
  ------------------
  897|  5.81k|    terminate_log_file_thread(root);
  898|  5.81k|    mp_msg_log_buffer_destroy(root->early_buffer);
  899|  5.81k|    mp_msg_log_buffer_destroy(root->early_filebuffer);
  900|  5.81k|    mp_assert(root->num_buffers == 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  901|  5.81k|    if (root->stats_file)
  ------------------
  |  Branch (901:9): [True: 0, False: 5.81k]
  ------------------
  902|      0|        fclose(root->stats_file);
  903|  5.81k|    talloc_free(root->stats_path);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  904|  5.81k|    talloc_free(root->log_path);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  905|  5.81k|    m_option_type_msglevels.free(&root->msg_levels);
  906|  5.81k|    mp_mutex_destroy(&root->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  907|  5.81k|    mp_mutex_destroy(&root->log_file_lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  908|  5.81k|    mp_cond_destroy(&root->log_file_wakeup);
  909|  5.81k|    talloc_free(root);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  910|  5.81k|    global->log = NULL;
  911|  5.81k|}
mp_msg_set_early_logging:
  959|  11.6k|{
  960|  11.6k|    struct mp_log_root *root = global->log->root;
  961|       |
  962|  11.6k|    mp_msg_set_early_logging_raw(global, enable, &root->early_buffer,
  963|  11.6k|                                 EARLY_TERM_BUF, MP_LOG_BUFFER_MSGL_TERM);
  ------------------
  |  |   47|  11.6k|#define EARLY_TERM_BUF 100
  ------------------
                                               EARLY_TERM_BUF, MP_LOG_BUFFER_MSGL_TERM);
  ------------------
  |  |   27|  11.6k|#define MP_LOG_BUFFER_MSGL_TERM (MSGL_MAX + 1)
  ------------------
  964|       |
  965|       |    // normally MSGL_LOGFILE buffer gets a write thread, but not the early buf
  966|  11.6k|    mp_msg_set_early_logging_raw(global, enable, &root->early_filebuffer,
  967|  11.6k|                                 EARLY_FILE_BUF, MP_LOG_BUFFER_MSGL_LOGFILE);
  ------------------
  |  |   53|  11.6k|#define EARLY_FILE_BUF 5000
  ------------------
                                               EARLY_FILE_BUF, MP_LOG_BUFFER_MSGL_LOGFILE);
  ------------------
  |  |   29|  11.6k|#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
  ------------------
  968|  11.6k|}
mp_msg_log_buffer_new:
  974|  11.6k|{
  975|  11.6k|    struct mp_log_root *root = global->log->root;
  976|       |
  977|  11.6k|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  11.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  978|       |
  979|  11.6k|    if (level == MP_LOG_BUFFER_MSGL_TERM) {
  ------------------
  |  |   27|  11.6k|#define MP_LOG_BUFFER_MSGL_TERM (MSGL_MAX + 1)
  ------------------
  |  Branch (979:9): [True: 5.81k, False: 5.81k]
  ------------------
  980|       |        // The first thing which creates a terminal-level log buffer gets the
  981|       |        // early log buffer, if it exists. This is supposed to enable a script
  982|       |        // to grab log messages from before it was initialized. It's OK that
  983|       |        // this works only for 1 script and only once.
  984|  5.81k|        if (root->early_buffer) {
  ------------------
  |  Branch (984:13): [True: 0, False: 5.81k]
  ------------------
  985|      0|            struct mp_log_buffer *buffer = root->early_buffer;
  986|      0|            root->early_buffer = NULL;
  987|      0|            mp_msg_log_buffer_resize(buffer, size);
  988|      0|            buffer->wakeup_cb = wakeup_cb;
  989|      0|            buffer->wakeup_cb_ctx = wakeup_cb_ctx;
  990|      0|            mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  991|      0|            return buffer;
  992|      0|        }
  993|  5.81k|    }
  994|       |
  995|  11.6k|    mp_assert(size > 0);
  ------------------
  |  |   41|  11.6k|#define mp_assert assert
  ------------------
  996|       |
  997|  11.6k|    struct mp_log_buffer *buffer = talloc_ptrtype(NULL, buffer);
  ------------------
  |  |   34|  11.6k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  11.6k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  998|  11.6k|    *buffer = (struct mp_log_buffer) {
  999|  11.6k|        .root = root,
 1000|  11.6k|        .level = level,
 1001|  11.6k|        .entries = talloc_array(buffer, struct mp_log_buffer_entry *, size),
  ------------------
  |  |   29|  11.6k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  11.6k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1002|  11.6k|        .capacity = size,
 1003|  11.6k|        .wakeup_cb = wakeup_cb,
 1004|  11.6k|        .wakeup_cb_ctx = wakeup_cb_ctx,
 1005|  11.6k|    };
 1006|       |
 1007|  11.6k|    mp_mutex_init(&buffer->lock);
 1008|       |
 1009|  11.6k|    MP_TARRAY_APPEND(root, root->buffers, root->num_buffers, buffer);
  ------------------
  |  |  105|  11.6k|    do {                                            \
  |  |  106|  11.6k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  11.6k|    do {                                            \
  |  |  |  |   97|  11.6k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  11.6k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  11.6k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  11.6k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 5.81k]
  |  |  |  |  ------------------
  |  |  |  |   99|  11.6k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  11.6k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  11.6k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  11.6k|        (idxvar)++;                                 \
  |  |  109|  11.6k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1010|       |
 1011|  11.6k|    atomic_fetch_add(&root->reload_counter, 1);
 1012|  11.6k|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1013|       |
 1014|  11.6k|    return buffer;
 1015|  11.6k|}
mp_msg_log_buffer_destroy:
 1059|  34.8k|{
 1060|  34.8k|    if (!buffer)
  ------------------
  |  Branch (1060:9): [True: 23.2k, False: 11.6k]
  ------------------
 1061|  23.2k|        return;
 1062|       |
 1063|  11.6k|    struct mp_log_root *root = buffer->root;
 1064|       |
 1065|  11.6k|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  11.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1066|       |
 1067|  11.6k|    for (int n = 0; n < root->num_buffers; n++) {
  ------------------
  |  Branch (1067:21): [True: 11.6k, False: 0]
  ------------------
 1068|  11.6k|        if (root->buffers[n] == buffer) {
  ------------------
  |  Branch (1068:13): [True: 11.6k, False: 0]
  ------------------
 1069|  11.6k|            MP_TARRAY_REMOVE_AT(root->buffers, root->num_buffers, n);
  ------------------
  |  |  143|  11.6k|    do {                                            \
  |  |  144|  11.6k|        size_t at_ = (at);                          \
  |  |  145|  11.6k|        assert(at_ <= (idxvar));                    \
  |  |  146|  11.6k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  11.6k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  11.6k|        (idxvar)--;                                 \
  |  |  149|  11.6k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1070|  11.6k|            goto found;
 1071|  11.6k|        }
 1072|  11.6k|    }
 1073|       |
 1074|      0|    MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
 1075|       |
 1076|  11.6k|found:
 1077|       |
 1078|  1.81M|    while (buffer->num_entries)
  ------------------
  |  Branch (1078:12): [True: 1.80M, False: 11.6k]
  ------------------
 1079|  1.80M|        talloc_free(log_buffer_read(buffer));
  ------------------
  |  |   47|  1.80M|#define talloc_free                     ta_free
  ------------------
 1080|       |
 1081|  11.6k|    mp_mutex_destroy(&buffer->lock);
  ------------------
  |  |  130|  11.6k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
 1082|  11.6k|    talloc_free(buffer);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
 1083|       |
 1084|  11.6k|    atomic_fetch_add(&root->reload_counter, 1);
 1085|  11.6k|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1086|  11.6k|}
mp_msg:
 1121|  15.2M|{
 1122|  15.2M|    va_list va;
 1123|  15.2M|    va_start(va, format);
 1124|  15.2M|    mp_msg_va(log, lev, format, va);
 1125|  15.2M|    va_end(va);
 1126|  15.2M|}
mp_msg_find_level:
 1153|   163k|{
 1154|  1.31M|    for (int n = 0; n < MP_ARRAY_SIZE(mp_log_levels); n++) {
  ------------------
  |  |   48|  1.31M|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (1154:21): [True: 1.31M, False: 0]
  ------------------
 1155|  1.31M|        if (mp_log_levels[n] && !strcasecmp(s, mp_log_levels[n]))
  ------------------
  |  Branch (1155:13): [True: 1.31M, False: 0]
  |  Branch (1155:33): [True: 163k, False: 1.14M]
  ------------------
 1156|   163k|            return n;
 1157|  1.31M|    }
 1158|      0|    return -1;
 1159|   163k|}
msg.c:update_loglevel:
  140|   169k|{
  141|   169k|    struct mp_log_root *root = log->root;
  142|   169k|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|   169k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  143|   169k|    log->level = MSGL_STATUS + root->verbose; // default log level
  144|   169k|    if (root->really_quiet)
  ------------------
  |  Branch (144:9): [True: 0, False: 169k]
  ------------------
  145|      0|        log->level = -1;
  146|   327k|    for (int n = 0; root->msg_levels && root->msg_levels[n * 2 + 0]; n++) {
  ------------------
  |  Branch (146:21): [True: 315k, False: 11.6k]
  |  Branch (146:41): [True: 157k, False: 157k]
  ------------------
  147|   157k|        if (match_mod(log->verbose_prefix, root->msg_levels[n * 2 + 0]))
  ------------------
  |  Branch (147:13): [True: 157k, False: 0]
  ------------------
  148|   157k|            log->level = mp_msg_find_level(root->msg_levels[n * 2 + 1]);
  149|   157k|    }
  150|   169k|    log->terminal_level = log->level;
  151|   227k|    for (int n = 0; n < log->root->num_buffers; n++) {
  ------------------
  |  Branch (151:21): [True: 58.1k, False: 169k]
  ------------------
  152|  58.1k|        int buffer_level = log->root->buffers[n]->level;
  153|  58.1k|        if (buffer_level == MP_LOG_BUFFER_MSGL_LOGFILE)
  ------------------
  |  |   29|  58.1k|#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
  ------------------
  |  Branch (153:13): [True: 29.0k, False: 29.0k]
  ------------------
  154|  29.0k|            buffer_level = MSGL_DEBUG;
  155|  58.1k|        if (buffer_level != MP_LOG_BUFFER_MSGL_TERM)
  ------------------
  |  |   27|  58.1k|#define MP_LOG_BUFFER_MSGL_TERM (MSGL_MAX + 1)
  ------------------
  |  Branch (155:13): [True: 29.0k, False: 29.0k]
  ------------------
  156|  29.0k|            log->level = MPMAX(log->level, buffer_level);
  ------------------
  |  |   43|  29.0k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 29.0k, False: 0]
  |  |  ------------------
  ------------------
  157|  58.1k|    }
  158|   169k|    if (log->root->log_file)
  ------------------
  |  Branch (158:9): [True: 0, False: 169k]
  ------------------
  159|      0|        log->level = MPMAX(log->level, MSGL_DEBUG);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  160|   169k|    if (log->root->stats_file)
  ------------------
  |  Branch (160:9): [True: 0, False: 169k]
  ------------------
  161|      0|        log->level = MPMAX(log->level, MSGL_STATS);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  162|   169k|    log->level = MPMIN(log->level, log->max_level);
  ------------------
  |  |   44|   169k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 169k]
  |  |  ------------------
  ------------------
  163|   169k|    atomic_store(&log->reload_counter, atomic_load(&log->root->reload_counter));
  164|   169k|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|   169k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  165|   169k|}
msg.c:match_mod:
  131|   157k|{
  132|   157k|    if (!strcmp(mod, "all"))
  ------------------
  |  Branch (132:9): [True: 157k, False: 0]
  ------------------
  133|   157k|        return true;
  134|       |    // Path prefix matches
  135|      0|    bstr b = bstr0(name);
  136|      0|    return bstr_eatstart0(&b, mod) && (bstr_eatstart0(&b, "/") || !b.len);
  ------------------
  |  Branch (136:12): [True: 0, False: 0]
  |  Branch (136:40): [True: 0, False: 0]
  |  Branch (136:67): [True: 0, False: 0]
  ------------------
  137|   157k|}
msg.c:msg_flush_status_line:
  263|   100k|{
  264|   100k|    if (!root->status_lines)
  ------------------
  |  Branch (264:9): [True: 100k, False: 0]
  ------------------
  265|   100k|        goto done;
  266|       |
  267|      0|    FILE *fp = term_msg_fp(root, MSGL_STATUS);
  268|      0|    if (!clear) {
  ------------------
  |  Branch (268:9): [True: 0, False: 0]
  ------------------
  269|      0|        if (root->isatty[term_msg_fileno(root, MSGL_STATUS)])
  ------------------
  |  Branch (269:13): [True: 0, False: 0]
  ------------------
  270|      0|            fprintf(fp, TERM_ESC_RESTORE_CURSOR);
  ------------------
  |  |   30|      0|#define TERM_ESC_RESTORE_CURSOR     "\033[?25h"
  ------------------
  271|      0|        fprintf(fp, "\n");
  272|      0|        root->blank_lines = 0;
  273|      0|        root->status_lines = 0;
  274|      0|        goto done;
  275|      0|    }
  276|       |
  277|      0|    bstr term_msg = {0};
  278|      0|    prepare_prefix(root, &term_msg, MSGL_STATUS, 0);
  279|      0|    if (term_msg.len) {
  ------------------
  |  Branch (279:9): [True: 0, False: 0]
  ------------------
  280|      0|        fprintf(fp, "%.*s", BSTR_P(term_msg));
  ------------------
  |  |  283|      0|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  281|      0|        talloc_free(term_msg.start);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  282|      0|    }
  283|       |
  284|   100k|done:
  285|   100k|    root->status_line.len = 0;
  286|   100k|}
msg.c:term_msg_fp:
  200|  12.5M|{
  201|  12.5M|    return term_msg_fileno(root, lev) == STDERR_FILENO ? stderr : stdout;
  ------------------
  |  Branch (201:12): [True: 0, False: 12.5M]
  ------------------
  202|  12.5M|}
msg.c:test_terminal_level:
  371|  12.5M|{
  372|  12.5M|    return lev <= log->terminal_level && log->root->use_terminal &&
  ------------------
  |  Branch (372:12): [True: 12.5M, False: 0]
  |  Branch (372:42): [True: 0, False: 12.5M]
  ------------------
  373|  12.5M|           !(lev == MSGL_STATUS && terminal_in_background());
  ------------------
  |  Branch (373:14): [True: 0, False: 0]
  |  Branch (373:36): [True: 0, False: 0]
  ------------------
  374|  12.5M|}
msg.c:write_term_msg:
  505|  12.5M|{
  506|  12.5M|    struct mp_log_root *root = log->root;
  507|  12.5M|    bool print_term = test_terminal_level(log, lev);
  508|  12.5M|    int fileno = term_msg_fileno(root, lev);
  509|  12.5M|    int term_w = 0, term_h = 0;
  510|  12.5M|    if (print_term && root->isatty[fileno])
  ------------------
  |  Branch (510:9): [True: 0, False: 12.5M]
  |  Branch (510:23): [True: 0, False: 0]
  ------------------
  511|      0|        terminal_get_size(&term_w, &term_h);
  512|       |
  513|  12.5M|    out->len = 0;
  514|       |
  515|       |    // Split away each line. Normally we require full lines; buffer partial
  516|       |    // lines if they happen.
  517|  12.5M|    root->term_msg_tmp.len = 0;
  518|  12.5M|    int term_msg_lines = 0;
  519|       |
  520|  12.5M|    bstr str = text;
  521|  32.9M|    while (str.len) {
  ------------------
  |  Branch (521:12): [True: 20.6M, False: 12.2M]
  ------------------
  522|  20.6M|        bstr line = bstr_getline(str, &str);
  523|  20.6M|        if (line.start[line.len - 1] != '\n') {
  ------------------
  |  Branch (523:13): [True: 316k, False: 20.3M]
  ------------------
  524|   316k|            mp_assert(str.len == 0);
  ------------------
  |  |   41|   316k|#define mp_assert assert
  ------------------
  525|   316k|            str = line;
  526|   316k|            break;
  527|   316k|        }
  528|       |
  529|  20.3M|        bool clip = bstr_eatstart0(&line, TERM_MSG_0);
  ------------------
  |  |   30|  20.3M|#define TERM_MSG_0 TERM_MSG_ESCAPE "0"
  |  |  ------------------
  |  |  |  |   29|  20.3M|#define TERM_MSG_ESCAPE "\xC2\x92" "t"
  |  |  ------------------
  ------------------
  530|  20.3M|        if (print_term) {
  ------------------
  |  Branch (530:13): [True: 0, False: 20.3M]
  ------------------
  531|      0|            int line_w;
  532|      0|            append_terminal_line(log, lev, line, &root->term_msg_tmp, &line_w,
  533|      0|                                 clip && term_w ? term_w : INT_MAX);
  ------------------
  |  Branch (533:34): [True: 0, False: 0]
  |  Branch (533:42): [True: 0, False: 0]
  ------------------
  534|      0|            term_msg_lines += (!line_w || !term_w)
  ------------------
  |  Branch (534:32): [True: 0, False: 0]
  |  Branch (534:43): [True: 0, False: 0]
  ------------------
  535|      0|                                ? 1 : (line_w + term_w - 1) / term_w;
  536|      0|        }
  537|  20.3M|        write_msg_to_buffers(log, lev, line);
  538|  20.3M|    }
  539|       |
  540|  12.5M|    if (lev == MSGL_STATUS) {
  ------------------
  |  Branch (540:9): [True: 0, False: 12.5M]
  ------------------
  541|      0|        int line_w = 0;
  542|      0|        bool clip = bstr_eatstart0(&str, TERM_MSG_0);
  ------------------
  |  |   30|      0|#define TERM_MSG_0 TERM_MSG_ESCAPE "0"
  |  |  ------------------
  |  |  |  |   29|      0|#define TERM_MSG_ESCAPE "\xC2\x92" "t"
  |  |  ------------------
  ------------------
  543|      0|        if (str.len && print_term)
  ------------------
  |  Branch (543:13): [True: 0, False: 0]
  |  Branch (543:24): [True: 0, False: 0]
  ------------------
  544|      0|            append_terminal_line(log, lev, str, &root->term_msg_tmp, &line_w,
  545|      0|                                 clip && term_w ? term_w : INT_MAX);
  ------------------
  |  Branch (545:34): [True: 0, False: 0]
  |  Branch (545:42): [True: 0, False: 0]
  ------------------
  546|      0|        term_msg_lines += !term_w ? (str.len ? 1 : 0)
  ------------------
  |  Branch (546:27): [True: 0, False: 0]
  |  Branch (546:38): [True: 0, False: 0]
  ------------------
  547|      0|                                  : (line_w + term_w - 1) / term_w;
  548|  12.5M|    } else if (str.len) {
  ------------------
  |  Branch (548:16): [True: 316k, False: 12.2M]
  ------------------
  549|   316k|        bstr_xappend(NULL, &log->partial[lev], str);
  550|   316k|    }
  551|       |
  552|  12.5M|    if (print_term && (root->term_msg_tmp.len || lev == MSGL_STATUS)) {
  ------------------
  |  Branch (552:9): [True: 0, False: 12.5M]
  |  Branch (552:24): [True: 0, False: 0]
  |  Branch (552:50): [True: 0, False: 0]
  ------------------
  553|      0|        prepare_prefix(root, out, lev, term_msg_lines);
  554|      0|        if (root->color[fileno] && root->term_msg_tmp.len) {
  ------------------
  |  Branch (554:13): [True: 0, False: 0]
  |  Branch (554:36): [True: 0, False: 0]
  ------------------
  555|      0|            set_msg_color(root, out, lev);
  556|      0|            set_term_color(root, &root->term_msg_tmp, -1);
  557|      0|        }
  558|      0|        bstr_xappend(root, out, root->term_msg_tmp);
  559|      0|    }
  560|  12.5M|}
msg.c:write_msg_to_buffers:
  443|  20.3M|{
  444|  20.3M|    struct mp_log_root *root = log->root;
  445|  22.7M|    for (int n = 0; n < root->num_buffers; n++) {
  ------------------
  |  Branch (445:21): [True: 2.45M, False: 20.3M]
  ------------------
  446|  2.45M|        struct mp_log_buffer *buffer = root->buffers[n];
  447|  2.45M|        bool wakeup = false;
  448|  2.45M|        mp_mutex_lock(&buffer->lock);
  ------------------
  |  |  131|  2.45M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  449|  2.45M|        int buffer_level = buffer->level;
  450|  2.45M|        if (buffer_level == MP_LOG_BUFFER_MSGL_TERM)
  ------------------
  |  |   27|  2.45M|#define MP_LOG_BUFFER_MSGL_TERM (MSGL_MAX + 1)
  ------------------
  |  Branch (450:13): [True: 1.22M, False: 1.22M]
  ------------------
  451|  1.22M|            buffer_level = log->terminal_level;
  452|  2.45M|        if (buffer_level == MP_LOG_BUFFER_MSGL_LOGFILE)
  ------------------
  |  |   29|  2.45M|#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
  ------------------
  |  Branch (452:13): [True: 1.22M, False: 1.22M]
  ------------------
  453|  1.22M|            buffer_level = MPMAX(log->terminal_level, MSGL_DEBUG);
  ------------------
  |  |   43|  1.22M|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 1.22M, False: 0]
  |  |  ------------------
  ------------------
  454|  2.45M|        if (lev <= buffer_level && lev != MSGL_STATUS) {
  ------------------
  |  Branch (454:13): [True: 2.45M, False: 0]
  |  Branch (454:36): [True: 2.45M, False: 0]
  ------------------
  455|  2.45M|            if (buffer->level == MP_LOG_BUFFER_MSGL_LOGFILE) {
  ------------------
  |  |   29|  2.45M|#define MP_LOG_BUFFER_MSGL_LOGFILE (MSGL_MAX + 2)
  ------------------
  |  Branch (455:17): [True: 1.22M, False: 1.22M]
  ------------------
  456|       |                // If the buffer is full, block until we can write again,
  457|       |                // unless there's no write thread (died, or early filebuffer)
  458|  1.22M|                bool dead = false;
  459|  1.22M|                while (buffer->num_entries == buffer->capacity && !dead) {
  ------------------
  |  Branch (459:24): [True: 0, False: 1.22M]
  |  Branch (459:67): [True: 0, False: 0]
  ------------------
  460|       |                    // Temporary unlock is OK; buffer->level is immutable, and
  461|       |                    // buffer can't go away because the global log lock is held.
  462|      0|                    mp_mutex_unlock(&buffer->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  463|      0|                    mp_mutex_lock(&root->log_file_lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  464|      0|                    if (root->log_file_thread_active) {
  ------------------
  |  Branch (464:25): [True: 0, False: 0]
  ------------------
  465|      0|                        mp_cond_wait(&root->log_file_wakeup,
  466|      0|                                          &root->log_file_lock);
  467|      0|                    } else {
  468|      0|                        dead = true;
  469|      0|                    }
  470|      0|                    mp_mutex_unlock(&root->log_file_lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  471|      0|                    mp_mutex_lock(&buffer->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  472|      0|                }
  473|  1.22M|            }
  474|  2.45M|            if (buffer->num_entries == buffer->capacity) {
  ------------------
  |  Branch (474:17): [True: 644k, False: 1.80M]
  ------------------
  475|   644k|                struct mp_log_buffer_entry *skip = log_buffer_read(buffer);
  476|   644k|                talloc_free(skip);
  ------------------
  |  |   47|   644k|#define talloc_free                     ta_free
  ------------------
  477|   644k|                buffer->dropped += 1;
  478|   644k|            }
  479|  2.45M|            struct mp_log_buffer_entry *entry = talloc_ptrtype(NULL, entry);
  ------------------
  |  |   34|  2.45M|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  2.45M|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  2.45M|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  480|  2.45M|            *entry = (struct mp_log_buffer_entry) {
  481|  2.45M|                .prefix = talloc_strdup(entry, log->verbose_prefix),
  ------------------
  |  |   50|  2.45M|#define talloc_strdup                   ta_xstrdup
  ------------------
  482|  2.45M|                .level = lev,
  483|  2.45M|                .text = bstrdup0(entry, text),
  484|  2.45M|            };
  485|  2.45M|            int pos = (buffer->entry0 + buffer->num_entries) % buffer->capacity;
  486|  2.45M|            buffer->entries[pos] = entry;
  487|  2.45M|            buffer->num_entries += 1;
  488|  2.45M|            if (buffer->wakeup_cb && !buffer->silent)
  ------------------
  |  Branch (488:17): [True: 0, False: 2.45M]
  |  Branch (488:38): [True: 0, False: 0]
  ------------------
  489|      0|                wakeup = true;
  490|  2.45M|        }
  491|  2.45M|        mp_mutex_unlock(&buffer->lock);
  ------------------
  |  |  133|  2.45M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  492|  2.45M|        if (wakeup)
  ------------------
  |  Branch (492:13): [True: 0, False: 2.45M]
  ------------------
  493|      0|            buffer->wakeup_cb(buffer->wakeup_cb_ctx);
  494|  2.45M|    }
  495|  20.3M|}
msg.c:destroy_log:
  619|   559k|{
  620|   559k|    struct mp_log *log = ptr;
  621|       |    // This is not managed via talloc itself, because mp_msg calls must be
  622|       |    // thread-safe, while talloc is not thread-safe.
  623|  5.59M|    for (int lvl = 0; lvl <= MSGL_MAX; ++lvl)
  ------------------
  |  Branch (623:23): [True: 5.03M, False: 559k]
  ------------------
  624|  5.03M|        talloc_free(log->partial[lvl].start);
  ------------------
  |  |   47|  5.03M|#define talloc_free                     ta_free
  ------------------
  625|   559k|}
msg.c:check_new_path:
  759|  23.2k|{
  760|  23.2k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  23.2k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  23.2k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  761|  23.2k|    bool res = false;
  762|       |
  763|  23.2k|    char *new_path = mp_get_user_path(tmp, global, opt);
  764|  23.2k|    if (!new_path)
  ------------------
  |  Branch (764:9): [True: 23.2k, False: 0]
  ------------------
  765|  23.2k|        new_path = "";
  766|       |
  767|  23.2k|    char *old_path = *current_path ? *current_path : "";
  ------------------
  |  Branch (767:22): [True: 0, False: 23.2k]
  ------------------
  768|  23.2k|    if (strcmp(old_path, new_path) != 0) {
  ------------------
  |  Branch (768:9): [True: 0, False: 23.2k]
  ------------------
  769|      0|        talloc_free(*current_path);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  770|      0|        *current_path = NULL;
  771|      0|        if (new_path[0])
  ------------------
  |  Branch (771:13): [True: 0, False: 0]
  ------------------
  772|      0|            *current_path = talloc_strdup(NULL, new_path);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  773|      0|        res = true;
  774|      0|    }
  775|       |
  776|  23.2k|    talloc_free(tmp);
  ------------------
  |  |   47|  23.2k|#define talloc_free                     ta_free
  ------------------
  777|       |
  778|  23.2k|    return res;
  779|  23.2k|}
msg.c:terminate_log_file_thread:
  733|  5.81k|{
  734|  5.81k|    bool wait_terminate = false;
  735|       |
  736|  5.81k|    mp_mutex_lock(&root->log_file_lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  737|  5.81k|    if (root->log_file_thread_active) {
  ------------------
  |  Branch (737:9): [True: 0, False: 5.81k]
  ------------------
  738|      0|        root->log_file_thread_active = false;
  739|      0|        mp_cond_broadcast(&root->log_file_wakeup);
  740|      0|        wait_terminate = true;
  741|      0|    }
  742|  5.81k|    mp_mutex_unlock(&root->log_file_lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  743|       |
  744|  5.81k|    if (wait_terminate)
  ------------------
  |  Branch (744:9): [True: 0, False: 5.81k]
  ------------------
  745|      0|        mp_thread_join(root->log_file_thread);
  ------------------
  |  |  212|      0|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  746|       |
  747|  5.81k|    mp_msg_log_buffer_destroy(root->log_file_buffer);
  748|  5.81k|    root->log_file_buffer = NULL;
  749|       |
  750|  5.81k|    if (root->log_file)
  ------------------
  |  Branch (750:9): [True: 0, False: 5.81k]
  ------------------
  751|      0|        fclose(root->log_file);
  752|  5.81k|    root->log_file = NULL;
  753|  5.81k|}
msg.c:term_msg_fileno:
  195|  25.1M|{
  196|  25.1M|    return root->force_stderr ? STDERR_FILENO : STDOUT_FILENO;
  ------------------
  |  Branch (196:12): [True: 0, False: 25.1M]
  ------------------
  197|  25.1M|}
msg.c:mp_msg_set_early_logging_raw:
  934|  23.2k|{
  935|  23.2k|    struct mp_log_root *root = global->log->root;
  936|  23.2k|    mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  23.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  937|       |
  938|  23.2k|    if (enable != !!*root_logbuf) {
  ------------------
  |  Branch (938:9): [True: 23.2k, False: 0]
  ------------------
  939|  23.2k|        if (enable) {
  ------------------
  |  Branch (939:13): [True: 11.6k, False: 11.6k]
  ------------------
  940|  11.6k|            mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  941|  11.6k|            struct mp_log_buffer *buf =
  942|  11.6k|                mp_msg_log_buffer_new(global, size, level, NULL, NULL);
  943|  11.6k|            mp_mutex_lock(&root->lock);
  ------------------
  |  |  131|  11.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  944|  11.6k|            mp_assert(!*root_logbuf); // no concurrent calls to this function
  ------------------
  |  |   41|  11.6k|#define mp_assert assert
  ------------------
  945|  11.6k|            *root_logbuf = buf;
  946|  11.6k|        } else {
  947|  11.6k|            struct mp_log_buffer *buf = *root_logbuf;
  948|  11.6k|            *root_logbuf = NULL;
  949|  11.6k|            mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  950|  11.6k|            mp_msg_log_buffer_destroy(buf);
  951|  11.6k|            return;
  952|  11.6k|        }
  953|  23.2k|    }
  954|       |
  955|  11.6k|    mp_mutex_unlock(&root->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  956|  11.6k|}
msg.c:log_buffer_read:
  434|  2.45M|{
  435|  2.45M|    mp_assert(buffer->num_entries);
  ------------------
  |  |   41|  2.45M|#define mp_assert assert
  ------------------
  436|  2.45M|    struct mp_log_buffer_entry *res = buffer->entries[buffer->entry0];
  437|  2.45M|    buffer->entry0 = (buffer->entry0 + 1) % buffer->capacity;
  438|  2.45M|    buffer->num_entries -= 1;
  439|  2.45M|    return res;
  440|  2.45M|}

av_log.c:mp_msg_test:
   64|  2.09M|{
   65|  2.09M|    return lev <= mp_msg_level(log);
   66|  2.09M|}
msg.c:mp_msg_test:
   64|  15.2M|{
   65|  15.2M|    return lev <= mp_msg_level(log);
   66|  15.2M|}
cmd.c:mp_msg_test:
   64|  11.6k|{
   65|  11.6k|    return lev <= mp_msg_level(log);
   66|  11.6k|}
input.c:mp_msg_test:
   64|  1.11M|{
   65|  1.11M|    return lev <= mp_msg_level(log);
   66|  1.11M|}
m_config_frontend.c:mp_msg_test:
   64|  40.6k|{
   65|  40.6k|    return lev <= mp_msg_level(log);
   66|  40.6k|}
chmap_sel.c:mp_msg_test:
   64|  1.35k|{
   65|  1.35k|    return lev <= mp_msg_level(log);
   66|  1.35k|}

playlist_entry_new:
   31|  94.7k|{
   32|  94.7k|    struct playlist_entry *e = talloc_zero(NULL, struct playlist_entry);
  ------------------
  |  |   27|  94.7k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  94.7k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  94.7k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   33|  94.7k|    char *local_filename = mp_file_url_to_filename(e, bstr0(filename));
   34|  94.7k|    e->filename = local_filename ? local_filename : talloc_strdup(e, filename);
  ------------------
  |  |   50|  94.7k|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (34:19): [True: 0, False: 94.7k]
  ------------------
   35|  94.7k|    e->stream_flags = STREAM_ORIGIN_DIRECT;
  ------------------
  |  |   47|  94.7k|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  ------------------
   36|  94.7k|    e->original_index = -1;
   37|  94.7k|    return e;
   38|  94.7k|}
playlist_insert_at:
   67|  94.7k|{
   68|  94.7k|    mp_assert(add->filename);
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
   69|  94.7k|    mp_assert(!at || at->pl == pl);
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
   70|       |
   71|  94.7k|    int index = at ? at->pl_index : pl->num_entries;
  ------------------
  |  Branch (71:17): [True: 0, False: 94.7k]
  ------------------
   72|  94.7k|    MP_TARRAY_INSERT_AT(pl, pl->entries, pl->num_entries, index, add);
  ------------------
  |  |  115|  94.7k|    do {                                            \
  |  |  116|  94.7k|        size_t at_ = (at);                          \
  |  |  117|  94.7k|        assert(at_ <= (idxvar));                    \
  |  |  118|  94.7k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  94.7k|    do {                                            \
  |  |  |  |   97|  94.7k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  94.7k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  94.7k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  94.7k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 7.52k, False: 87.2k]
  |  |  |  |  ------------------
  |  |  |  |   99|  94.7k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  7.52k|    do {                                                        \
  |  |  |  |  |  |   89|  7.52k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  7.52k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  7.52k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  7.52k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  7.52k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  7.52k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  7.52k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  94.7k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|  94.7k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|  94.7k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|  94.7k|        (idxvar)++;                                 \
  |  |  122|  94.7k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|  94.7k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   73|       |
   74|  94.7k|    add->pl = pl;
   75|  94.7k|    add->pl_index = index;
   76|  94.7k|    add->id = ++pl->id_alloc;
   77|       |
   78|  94.7k|    playlist_update_indexes(pl, index, pl->num_entries);
   79|       |
   80|  94.7k|    talloc_steal(pl, add);
  ------------------
  |  |   38|  94.7k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  94.7k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
   81|  94.7k|}
playlist_entry_unref:
   84|  7.85k|{
   85|  7.85k|    e->reserved--;
   86|  7.85k|    if (e->reserved < 0) {
  ------------------
  |  Branch (86:9): [True: 389, False: 7.46k]
  ------------------
   87|    389|        mp_assert(!e->pl);
  ------------------
  |  |   41|    389|#define mp_assert assert
  ------------------
   88|    389|        talloc_free(e);
  ------------------
  |  |   47|    389|#define talloc_free                     ta_free
  ------------------
   89|    389|    }
   90|  7.85k|}
playlist_remove:
   93|    389|{
   94|    389|    mp_assert(pl && entry->pl == pl);
  ------------------
  |  |   41|    389|#define mp_assert assert
  ------------------
   95|       |
   96|    389|    if (pl->current == entry) {
  ------------------
  |  Branch (96:9): [True: 389, False: 0]
  ------------------
   97|    389|        pl->current = playlist_entry_get_rel(entry, 1);
   98|    389|        pl->current_was_replaced = true;
   99|    389|    }
  100|       |
  101|    389|    MP_TARRAY_REMOVE_AT(pl->entries, pl->num_entries, entry->pl_index);
  ------------------
  |  |  143|    389|    do {                                            \
  |  |  144|    389|        size_t at_ = (at);                          \
  |  |  145|    389|        assert(at_ <= (idxvar));                    \
  |  |  146|    389|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|    389|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|    389|        (idxvar)--;                                 \
  |  |  149|    389|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  102|    389|    playlist_update_indexes(pl, entry->pl_index, -1);
  103|       |
  104|    389|    entry->pl = NULL;
  105|    389|    entry->pl_index = -1;
  106|    389|    ta_set_parent(entry, NULL);
  107|       |
  108|    389|    entry->removed = true;
  109|    389|    playlist_entry_unref(entry);
  110|    389|}
playlist_clear:
  113|  35.4k|{
  114|  35.4k|    for (int n = pl->num_entries - 1; n >= 0; n--)
  ------------------
  |  Branch (114:39): [True: 0, False: 35.4k]
  ------------------
  115|      0|        playlist_remove(pl, pl->entries[n]);
  116|  35.4k|    mp_assert(!pl->current);
  ------------------
  |  |   41|  35.4k|#define mp_assert assert
  ------------------
  117|  35.4k|    pl->current_was_replaced = false;
  118|  35.4k|    pl->playlist_completed = false;
  119|  35.4k|    pl->playlist_started = false;
  120|  35.4k|    TA_FREEP(&pl->playlist_dir);
  ------------------
  |  |   81|  35.4k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  35.4k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  121|  35.4k|}
playlist_append_file:
  156|    538|{
  157|    538|    playlist_insert_at(pl, playlist_entry_new(filename), NULL);
  158|    538|}
playlist_populate_playlist_path:
  161|    557|{
  162|    557|    char *playlist_path = talloc_strdup(pl, path);
  ------------------
  |  |   50|    557|#define talloc_strdup                   ta_xstrdup
  ------------------
  163|  89.4k|    for (int n = 0; n < pl->num_entries; n++) {
  ------------------
  |  Branch (163:21): [True: 88.9k, False: 557]
  ------------------
  164|  88.9k|        struct playlist_entry *e = pl->entries[n];
  165|  88.9k|        e->playlist_path = playlist_path;
  166|  88.9k|    }
  167|    557|}
playlist_get_first:
  202|  6.58k|{
  203|  6.58k|    return pl->num_entries ? pl->entries[0] : NULL;
  ------------------
  |  Branch (203:12): [True: 5.91k, False: 679]
  ------------------
  204|  6.58k|}
playlist_get_next:
  213|   104k|{
  214|   104k|    mp_assert(direction == -1 || direction == +1);
  ------------------
  |  |   41|   104k|#define mp_assert assert
  ------------------
  215|   104k|    if (!pl->current && pl->playlist_completed && direction < 0) {
  ------------------
  |  Branch (215:9): [True: 0, False: 104k]
  |  Branch (215:25): [True: 0, False: 0]
  |  Branch (215:51): [True: 0, False: 0]
  ------------------
  216|      0|        return playlist_entry_from_index(pl, pl->num_entries - 1);
  217|   104k|    } else if (!pl->current && !pl->playlist_started && direction > 0) {
  ------------------
  |  Branch (217:16): [True: 0, False: 104k]
  |  Branch (217:32): [True: 0, False: 0]
  |  Branch (217:57): [True: 0, False: 0]
  ------------------
  218|      0|        return playlist_entry_from_index(pl, 0);
  219|   104k|    } else if (!pl->current) {
  ------------------
  |  Branch (219:16): [True: 0, False: 104k]
  ------------------
  220|      0|        return NULL;
  221|      0|    }
  222|   104k|    mp_assert(pl->current->pl == pl);
  ------------------
  |  |   41|   104k|#define mp_assert assert
  ------------------
  223|   104k|    if (direction < 0)
  ------------------
  |  Branch (223:9): [True: 0, False: 104k]
  ------------------
  224|      0|        return playlist_entry_get_rel(pl->current, -1);
  225|   104k|    return pl->current_was_replaced ? pl->current :
  ------------------
  |  Branch (225:12): [True: 389, False: 104k]
  ------------------
  226|   104k|           playlist_entry_get_rel(pl->current, 1);
  227|   104k|}
playlist_entry_get_rel:
  232|   104k|{
  233|   104k|    mp_assert(direction == -1 || direction == +1);
  ------------------
  |  |   41|   104k|#define mp_assert assert
  ------------------
  234|   104k|    if (!e->pl)
  ------------------
  |  Branch (234:9): [True: 0, False: 104k]
  ------------------
  235|      0|        return NULL;
  236|   104k|    return playlist_entry_from_index(e->pl, e->pl_index + direction);
  237|   104k|}
playlist_set_stream_flags:
  322|    558|{
  323|  89.5k|    for (int n = 0; n < pl->num_entries; n++)
  ------------------
  |  Branch (323:21): [True: 88.9k, False: 558]
  ------------------
  324|  88.9k|        pl->entries[n]->stream_flags = flags;
  325|    558|}
playlist_transfer_entries_to:
  329|    389|{
  330|    389|    mp_assert(pl != source_pl);
  ------------------
  |  |   41|    389|#define mp_assert assert
  ------------------
  331|    389|    struct playlist_entry *first = playlist_get_first(source_pl);
  332|       |
  333|    389|    int count = source_pl->num_entries;
  334|    389|    MP_TARRAY_INSERT_N_AT(pl, pl->entries, pl->num_entries, dst_index, count);
  ------------------
  |  |  130|    389|    do {                                            \
  |  |  131|    389|        size_t at_ = (at);                          \
  |  |  132|    389|        assert(at_ <= (idxvar));                    \
  |  |  133|    389|        size_t c_ = (c);                            \
  |  |  134|    389|        MP_TARRAY_GROW(ctx, p, (idxvar) + c_);      \
  |  |  ------------------
  |  |  |  |   96|    389|    do {                                            \
  |  |  |  |   97|    389|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    389|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    389|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    389|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 389, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|    389|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    389|    do {                                                        \
  |  |  |  |  |  |   89|    389|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    389|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    389|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    389|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    389|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    389|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    389|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    389|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  135|    389|        memmove((p) + at_ + c_, (p) + at_,          \
  |  |  136|    389|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  137|    389|        (idxvar) += c_;                             \
  |  |  138|    389|    } while (0)
  |  |  ------------------
  |  |  |  Branch (138:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  335|       |
  336|  89.3k|    for (int n = 0; n < count; n++) {
  ------------------
  |  Branch (336:21): [True: 88.9k, False: 389]
  ------------------
  337|  88.9k|        struct playlist_entry *e = source_pl->entries[n];
  338|  88.9k|        e->pl = pl;
  339|  88.9k|        e->pl_index = dst_index + n;
  340|  88.9k|        e->id = ++pl->id_alloc;
  341|  88.9k|        pl->entries[e->pl_index] = e;
  342|  88.9k|        talloc_steal(pl, e);
  ------------------
  |  |   38|  88.9k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  88.9k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  343|  88.9k|        talloc_steal(pl, e->playlist_path);
  ------------------
  |  |   38|  88.9k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  88.9k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  344|  88.9k|    }
  345|       |
  346|    389|    playlist_update_indexes(pl, dst_index + count, -1);
  347|    389|    source_pl->num_entries = 0;
  348|       |
  349|    389|    pl->playlist_completed = source_pl->playlist_completed;
  350|    389|    pl->playlist_started = source_pl->playlist_started;
  351|       |
  352|    389|    return first ? first->id : 0;
  ------------------
  |  Branch (352:12): [True: 389, False: 0]
  ------------------
  353|    389|}
playlist_transfer_entries:
  361|    389|{
  362|       |
  363|    389|    int add_at = pl->num_entries;
  364|    389|    if (pl->current) {
  ------------------
  |  Branch (364:9): [True: 389, False: 0]
  ------------------
  365|    389|        add_at = pl->current->pl_index + 1;
  366|    389|        if (pl->current_was_replaced)
  ------------------
  |  Branch (366:13): [True: 0, False: 389]
  ------------------
  367|      0|            add_at += 1;
  368|    389|    }
  369|    389|    mp_assert(add_at >= 0);
  ------------------
  |  |   41|    389|#define mp_assert assert
  ------------------
  370|    389|    mp_assert(add_at <= pl->num_entries);
  ------------------
  |  |   41|    389|#define mp_assert assert
  ------------------
  371|       |
  372|    389|    return playlist_transfer_entries_to(pl, add_at, source_pl);
  373|    389|}
playlist_entry_to_index:
  383|  5.81k|{
  384|  5.81k|    if (!e || e->pl != pl)
  ------------------
  |  Branch (384:9): [True: 0, False: 5.81k]
  |  Branch (384:15): [True: 0, False: 5.81k]
  ------------------
  385|      0|        return -1;
  386|  5.81k|    return e->pl_index;
  387|  5.81k|}
playlist_entry_from_index:
  397|   104k|{
  398|   104k|    return index >= 0 && index < pl->num_entries ? pl->entries[index] : NULL;
  ------------------
  |  Branch (398:12): [True: 104k, False: 0]
  |  Branch (398:26): [True: 89.1k, False: 15.3k]
  ------------------
  399|   104k|}
playlist.c:playlist_update_indexes:
   55|  95.5k|{
   56|  95.5k|    start = MPMAX(start, 0);
  ------------------
  |  |   43|  95.5k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 88.9k, False: 6.59k]
  |  |  ------------------
  ------------------
   57|  95.5k|    end = end < 0 ? pl->num_entries : MPMIN(end, pl->num_entries);
  ------------------
  |  |   44|   190k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 94.7k]
  |  |  ------------------
  ------------------
  |  Branch (57:11): [True: 778, False: 94.7k]
  ------------------
   58|       |
   59|   279k|    for (int n = start; n < end; n++)
  ------------------
  |  Branch (59:25): [True: 183k, False: 95.5k]
  ------------------
   60|   183k|        pl->entries[n]->pl_index = n;
   61|  95.5k|}

stats_global_init:
   81|  5.81k|{
   82|  5.81k|    mp_assert(!global->stats);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   83|  5.81k|    struct stats_base *stats = talloc_zero(global, struct stats_base);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   84|  5.81k|    ta_set_destructor(stats, stats_destroy);
   85|  5.81k|    mp_mutex_init(&stats->lock);
   86|       |
   87|  5.81k|    global->stats = stats;
   88|  5.81k|    stats->global = global;
   89|  5.81k|}
stats_ctx_create:
  224|   229k|{
  225|   229k|    struct stats_base *base = global->stats;
  226|   229k|    mp_assert(base);
  ------------------
  |  |   41|   229k|#define mp_assert assert
  ------------------
  227|       |
  228|   229k|    struct stats_ctx *ctx = talloc_zero(ta_parent, struct stats_ctx);
  ------------------
  |  |   27|   229k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   229k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   229k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  229|   229k|    ctx->base = base;
  230|   229k|    ctx->prefix = talloc_strdup(ctx, prefix);
  ------------------
  |  |   50|   229k|#define talloc_strdup                   ta_xstrdup
  ------------------
  231|   229k|    ta_set_destructor(ctx, stats_ctx_destroy);
  232|       |
  233|   229k|    mp_mutex_lock(&base->lock);
  ------------------
  |  |  131|   229k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  234|   229k|    LL_APPEND(list, &base->list, ctx);
  ------------------
  |  |   44|   229k|#define LL_APPEND(field, list, item)  do {                              \
  |  |   45|   229k|    (item)->field.prev = (list)->tail;                                  \
  |  |   46|   229k|    (item)->field.next = NULL;                                          \
  |  |   47|   229k|    LL_RELINK_(field, list, item)                                       \
  |  |  ------------------
  |  |  |  |   98|   229k|    if ((item)->field.prev) {                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:9): [True: 223k, False: 5.81k]
  |  |  |  |  ------------------
  |  |  |  |   99|   223k|        (item)->field.prev->field.next = (item);                        \
  |  |  |  |  100|   223k|    } else {                                                            \
  |  |  |  |  101|  5.81k|        (list)->head = (item);                                          \
  |  |  |  |  102|  5.81k|    }                                                                   \
  |  |  |  |  103|   229k|    if ((item)->field.next) {                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:9): [True: 0, False: 229k]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        (item)->field.next->field.prev = (item);                        \
  |  |  |  |  105|   229k|    } else {                                                            \
  |  |  |  |  106|   229k|        (list)->tail = (item);                                          \
  |  |  |  |  107|   229k|    }
  |  |  ------------------
  |  |   48|   229k|} while (0)
  |  |  ------------------
  |  |  |  Branch (48:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  235|   229k|    base->num_entries = 0; // invalidate
  236|   229k|    mp_mutex_unlock(&base->lock);
  ------------------
  |  |  133|   229k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  237|       |
  238|   229k|    return ctx;
  239|   229k|}
stats_time_start:
  283|   143k|{
  284|   143k|    MP_STATS(ctx->base->global, "start %s", name);
  ------------------
  |  |   95|   143k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   143k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  285|   143k|    if (!IS_ACTIVE(ctx))
  ------------------
  |  |   68|   143k|    (atomic_load_explicit(&(ctx)->base->active, memory_order_relaxed))
  ------------------
  |  Branch (285:9): [True: 143k, False: 0]
  ------------------
  286|   143k|        return;
  287|      0|    mp_mutex_lock(&ctx->base->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  288|      0|    struct stat_entry *e = find_entry(ctx, name);
  289|      0|    e->type = VAL_TIME;
  290|      0|    e->thread_id = mp_thread_current_id();
  ------------------
  |  |  214|      0|#define mp_thread_current_id      pthread_self
  ------------------
  291|      0|    e->cpu_start_ns = mp_thread_cpu_time_ns(e->thread_id);
  292|      0|    e->time_start_ns = mp_time_ns();
  293|      0|    mp_mutex_unlock(&ctx->base->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  294|      0|}
stats_time_end:
  297|   143k|{
  298|   143k|    MP_STATS(ctx->base->global, "end %s", name);
  ------------------
  |  |   95|   143k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   143k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  299|   143k|    if (!IS_ACTIVE(ctx))
  ------------------
  |  |   68|   143k|    (atomic_load_explicit(&(ctx)->base->active, memory_order_relaxed))
  ------------------
  |  Branch (299:9): [True: 143k, False: 0]
  ------------------
  300|   143k|        return;
  301|      0|    mp_mutex_lock(&ctx->base->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  302|      0|    struct stat_entry *e = find_entry(ctx, name);
  303|      0|    if (e->type == VAL_TIME && e->time_start_ns) {
  ------------------
  |  Branch (303:9): [True: 0, False: 0]
  |  Branch (303:32): [True: 0, False: 0]
  ------------------
  304|      0|        e->val_th += mp_thread_cpu_time_ns(e->thread_id) - e->cpu_start_ns;
  305|      0|        e->val_rt += mp_time_ns() - e->time_start_ns;
  306|      0|        e->time_start_ns = 0;
  307|      0|    }
  308|      0|    mp_mutex_unlock(&ctx->base->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  309|      0|}
stats_event:
  312|   254k|{
  313|   254k|    if (!IS_ACTIVE(ctx))
  ------------------
  |  |   68|   254k|    (atomic_load_explicit(&(ctx)->base->active, memory_order_relaxed))
  ------------------
  |  Branch (313:9): [True: 254k, False: 0]
  ------------------
  314|   254k|        return;
  315|      0|    mp_mutex_lock(&ctx->base->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  316|      0|    struct stat_entry *e = find_entry(ctx, name);
  317|      0|    e->val_d += 1;
  318|      0|    e->type = VAL_INC;
  319|      0|    mp_mutex_unlock(&ctx->base->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  320|      0|}
stats_register_thread_cputime:
  333|  9.92k|{
  334|  9.92k|    register_thread(ctx, name, VAL_THREAD_CPU_TIME);
  335|  9.92k|}
stats_unregister_thread:
  338|  4.11k|{
  339|  4.11k|    register_thread(ctx, name, 0);
  340|  4.11k|}
stats.c:stats_destroy:
   71|  5.81k|{
   72|  5.81k|    struct stats_base *stats = p;
   73|       |
   74|       |    // All entries must have been destroyed before this.
   75|  5.81k|    mp_assert(!stats->list.head);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   76|       |
   77|  5.81k|    mp_mutex_destroy(&stats->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
   78|  5.81k|}
stats.c:stats_ctx_destroy:
  213|   229k|{
  214|   229k|    struct stats_ctx *ctx = p;
  215|       |
  216|   229k|    mp_mutex_lock(&ctx->base->lock);
  ------------------
  |  |  131|   229k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  217|   229k|    LL_REMOVE(list, &ctx->base->list, ctx);
  ------------------
  |  |   78|   229k|#define LL_REMOVE(field, list, item) do {                               \
  |  |   79|   229k|    if ((item)->field.prev) {                                           \
  |  |  ------------------
  |  |  |  Branch (79:9): [True: 223k, False: 5.81k]
  |  |  ------------------
  |  |   80|   223k|        (item)->field.prev->field.next = (item)->field.next;            \
  |  |   81|   223k|    } else {                                                            \
  |  |   82|  5.81k|        (list)->head = (item)->field.next;                              \
  |  |   83|  5.81k|    }                                                                   \
  |  |   84|   229k|    if ((item)->field.next) {                                           \
  |  |  ------------------
  |  |  |  Branch (84:9): [True: 18.3k, False: 211k]
  |  |  ------------------
  |  |   85|  18.3k|        (item)->field.next->field.prev = (item)->field.prev;            \
  |  |   86|   211k|    } else {                                                            \
  |  |   87|   211k|        (list)->tail = (item)->field.prev;                              \
  |  |   88|   211k|    }                                                                   \
  |  |   89|   229k|} while (0)
  |  |  ------------------
  |  |  |  Branch (89:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  218|   229k|    ctx->base->num_entries = 0; // invalidate
  219|   229k|    mp_mutex_unlock(&ctx->base->lock);
  ------------------
  |  |  133|   229k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  220|   229k|}
stats.c:find_entry:
  242|  14.0k|{
  243|  14.0k|    for (int n = 0; n < ctx->num_entries; n++) {
  ------------------
  |  Branch (243:21): [True: 4.11k, False: 9.92k]
  ------------------
  244|  4.11k|        if (strcmp(ctx->entries[n]->name, name) == 0)
  ------------------
  |  Branch (244:13): [True: 4.11k, False: 0]
  ------------------
  245|  4.11k|            return ctx->entries[n];
  246|  4.11k|    }
  247|       |
  248|  9.92k|    struct stat_entry *e = talloc_zero(ctx, struct stat_entry);
  ------------------
  |  |   27|  9.92k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  9.92k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  9.92k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  249|  9.92k|    snprintf(e->name, sizeof(e->name), "%s", name);
  250|  9.92k|    mp_assert(strcmp(e->name, name) == 0); // make e->name larger and don't complain
  ------------------
  |  |   41|  9.92k|#define mp_assert assert
  ------------------
  251|       |
  252|  9.92k|    e->full_name = talloc_asprintf(e, "%s/%s", ctx->prefix, e->name);
  ------------------
  |  |   52|  9.92k|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|  9.92k|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  253|       |
  254|  9.92k|    MP_TARRAY_APPEND(ctx, ctx->entries, ctx->num_entries, e);
  ------------------
  |  |  105|  9.92k|    do {                                            \
  |  |  106|  9.92k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  9.92k|    do {                                            \
  |  |  |  |   97|  9.92k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  9.92k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  9.92k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  9.92k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 9.92k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  9.92k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  9.92k|    do {                                                        \
  |  |  |  |  |  |   89|  9.92k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  9.92k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  9.92k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  9.92k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  9.92k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  9.92k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  9.92k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  9.92k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  9.92k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  9.92k|        (idxvar)++;                                 \
  |  |  109|  9.92k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  255|  9.92k|    ctx->base->num_entries = 0; // invalidate
  256|       |
  257|  9.92k|    return e;
  258|  9.92k|}
stats.c:register_thread:
  324|  14.0k|{
  325|  14.0k|    mp_mutex_lock(&ctx->base->lock);
  ------------------
  |  |  131|  14.0k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  326|  14.0k|    struct stat_entry *e = find_entry(ctx, name);
  327|  14.0k|    e->type = type;
  328|  14.0k|    e->thread_id = mp_thread_current_id();
  ------------------
  |  |  214|  14.0k|#define mp_thread_current_id      pthread_self
  ------------------
  329|  14.0k|    mp_mutex_unlock(&ctx->base->lock);
  ------------------
  |  |  133|  14.0k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  330|  14.0k|}

mp_tags_set_str:
   27|  76.3k|{
   28|  76.3k|    mp_tags_set_bstr(tags, bstr0(key), bstr0(value));
   29|  76.3k|}
mp_tags_set_bstr:
   32|  76.3k|{
   33|  94.1k|    for (int n = 0; n < tags->num_keys; n++) {
  ------------------
  |  Branch (33:21): [True: 17.7k, False: 76.3k]
  ------------------
   34|  17.7k|        if (bstrcasecmp0(key, tags->keys[n]) == 0) {
  ------------------
  |  Branch (34:13): [True: 0, False: 17.7k]
  ------------------
   35|      0|            talloc_free(tags->values[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
   36|      0|            tags->values[n] = bstrto0(tags, value);
   37|      0|            return;
   38|      0|        }
   39|  17.7k|    }
   40|       |
   41|  76.3k|    MP_RESIZE_ARRAY(tags, tags->keys,   tags->num_keys + 1);
  ------------------
  |  |   88|  76.3k|    do {                                                        \
  |  |   89|  76.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  ------------------
  |  |  |  |  158|  76.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  76.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  76.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  76.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   90|  76.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |   91|  76.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   42|  76.3k|    MP_RESIZE_ARRAY(tags, tags->values, tags->num_keys + 1);
  ------------------
  |  |   88|  76.3k|    do {                                                        \
  |  |   89|  76.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  ------------------
  |  |  |  |  158|  76.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  76.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  76.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  76.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   90|  76.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |   91|  76.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   43|  76.3k|    tags->keys[tags->num_keys]   = bstrto0(tags, key);
   44|  76.3k|    tags->values[tags->num_keys] = bstrto0(tags, value);
   45|  76.3k|    tags->num_keys++;
   46|  76.3k|}
mp_tags_get_str:
   67|  1.78M|{
   68|  1.78M|    return mp_tags_get_bstr(tags, bstr0(key));
   69|  1.78M|}
mp_tags_get_bstr:
   72|  1.78M|{
   73|  1.81M|    for (int n = 0; n < tags->num_keys; n++) {
  ------------------
  |  Branch (73:21): [True: 30.5k, False: 1.78M]
  ------------------
   74|  30.5k|        if (bstrcasecmp0(key, tags->keys[n]) == 0)
  ------------------
  |  Branch (74:13): [True: 1.13k, False: 29.4k]
  ------------------
   75|  1.13k|            return tags->values[n];
   76|  30.5k|    }
   77|  1.78M|    return NULL;
   78|  1.78M|}
mp_tags_clear:
   81|  86.3k|{
   82|  86.3k|    *tags = (struct mp_tags){0};
   83|  86.3k|    talloc_free_children(tags);
  ------------------
  |  |   46|  86.3k|#define talloc_free_children            ta_free_children
  ------------------
   84|  86.3k|}
mp_tags_dup:
   89|  86.3k|{
   90|  86.3k|    struct mp_tags *new = talloc_zero(tparent, struct mp_tags);
  ------------------
  |  |   27|  86.3k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  86.3k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  86.3k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   91|  86.3k|    mp_tags_replace(new, tags);
   92|  86.3k|    return new;
   93|  86.3k|}
mp_tags_replace:
   96|  86.3k|{
   97|  86.3k|    mp_tags_clear(dst);
   98|  86.3k|    MP_RESIZE_ARRAY(dst, dst->keys,   src->num_keys);
  ------------------
  |  |   88|  86.3k|    do {                                                        \
  |  |   89|  86.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  ------------------
  |  |  |  |  158|  86.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  86.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  86.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  86.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   90|  86.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |   91|  86.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   99|  86.3k|    MP_RESIZE_ARRAY(dst, dst->values, src->num_keys);
  ------------------
  |  |   88|  86.3k|    do {                                                        \
  |  |   89|  86.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  ------------------
  |  |  |  |  158|  86.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  86.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  86.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  86.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   90|  86.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |   91|  86.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  100|  86.3k|    dst->num_keys = src->num_keys;
  101|   153k|    for (int n = 0; n < src->num_keys; n++) {
  ------------------
  |  Branch (101:21): [True: 67.5k, False: 86.3k]
  ------------------
  102|  67.5k|        dst->keys[n] = talloc_strdup(dst, src->keys[n]);
  ------------------
  |  |   50|  67.5k|#define talloc_strdup                   ta_xstrdup
  ------------------
  103|  67.5k|        dst->values[n] = talloc_strdup(dst, src->values[n]);
  ------------------
  |  |   50|  67.5k|#define talloc_strdup                   ta_xstrdup
  ------------------
  104|  67.5k|    }
  105|  86.3k|}
mp_tags_filtered:
  111|  4.53k|{
  112|  4.53k|    struct mp_tags *new = talloc_zero(tparent, struct mp_tags);
  ------------------
  |  |   27|  4.53k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  4.53k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  4.53k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  113|  81.6k|    for (int n = 0; list && list[n]; n++) {
  ------------------
  |  Branch (113:21): [True: 81.6k, False: 0]
  |  Branch (113:29): [True: 77.1k, False: 4.53k]
  ------------------
  114|  77.1k|        char *key = list[n];
  115|  77.1k|        size_t keylen = strlen(key);
  116|  77.1k|        if (keylen >= INT_MAX)
  ------------------
  |  Branch (116:13): [True: 0, False: 77.1k]
  ------------------
  117|      0|            continue;
  118|  77.1k|        bool prefix = keylen && key[keylen - 1] == '*';
  ------------------
  |  Branch (118:23): [True: 77.1k, False: 0]
  |  Branch (118:33): [True: 0, False: 77.1k]
  ------------------
  119|  77.1k|        int matchlen = prefix ? keylen - 1 : keylen + 1;
  ------------------
  |  Branch (119:24): [True: 0, False: 77.1k]
  ------------------
  120|   117k|        for (int x = 0; x < tags->num_keys; x++) {
  ------------------
  |  Branch (120:25): [True: 40.8k, False: 77.1k]
  ------------------
  121|  40.8k|            if (strncasecmp(tags->keys[x], key, matchlen) == 0) {
  ------------------
  |  Branch (121:17): [True: 1.30k, False: 39.5k]
  ------------------
  122|  1.30k|                char skey[320];
  123|  1.30k|                snprintf(skey, sizeof(skey), "%.*s%s", matchlen, key,
  124|  1.30k|                         prefix ? tags->keys[x] + keylen - 1 : "");
  ------------------
  |  Branch (124:26): [True: 0, False: 1.30k]
  ------------------
  125|  1.30k|                mp_tags_set_str(new, skey, tags->values[x]);
  126|  1.30k|            }
  127|  40.8k|        }
  128|  77.1k|    }
  129|  4.53k|    return new;
  130|  4.53k|}
mp_tags_merge:
  133|  10.6k|{
  134|  10.6k|    for (int n = 0; n < src->num_keys; n++)
  ------------------
  |  Branch (134:21): [True: 0, False: 10.6k]
  ------------------
  135|      0|        mp_tags_set_str(tags, src->keys[n], src->values[n]);
  136|  10.6k|}
mp_tags_copy_from_av_dictionary:
  140|  47.6k|{
  141|  47.6k|    AVDictionaryEntry *entry = NULL;
  142|  50.4k|    while ((entry = av_dict_get(av_dict, "", entry, AV_DICT_IGNORE_SUFFIX)))
  ------------------
  |  Branch (142:12): [True: 2.75k, False: 47.6k]
  ------------------
  143|  2.75k|        mp_tags_set_str(tags, entry->key, entry->value);
  144|  47.6k|}
mp_tags_move_from_av_dictionary:
  148|  47.6k|{
  149|  47.6k|    mp_tags_copy_from_av_dictionary(tags, *av_dict_ptr);
  150|  47.6k|    av_dict_free(av_dict_ptr);
  151|  47.6k|}

mp_map_mimetype_to_video_codec:
  197|  4.80k|{
  198|  4.80k|    if (mimetype) {
  ------------------
  |  Branch (198:9): [True: 0, False: 4.80k]
  ------------------
  199|      0|        for (int n = 0; mimetype_to_codec[n][0]; n++) {
  ------------------
  |  Branch (199:25): [True: 0, False: 0]
  ------------------
  200|      0|            if (strcasecmp(mimetype_to_codec[n][0], mimetype) == 0)
  ------------------
  |  Branch (200:17): [True: 0, False: 0]
  ------------------
  201|      0|                return mimetype_to_codec[n][1];
  202|      0|        }
  203|      0|    }
  204|  4.80k|    return NULL;
  205|  4.80k|}

mp_probe_cue:
  180|  24.4k|{
  181|  24.4k|    bool valid = false;
  182|  24.4k|    data = skip_utf8_bom(data);
  183|  24.9k|    for (;;) {
  184|  24.9k|        enum cue_command cmd = read_cmd(&data, NULL);
  185|       |        // End reached. Since the line was most likely cut off, don't use the
  186|       |        // result of the last parsing call.
  187|  24.9k|        if (data.len == 0)
  ------------------
  |  Branch (187:13): [True: 19.8k, False: 5.12k]
  ------------------
  188|  19.8k|            break;
  189|  5.12k|        if (cmd == CUE_ERROR)
  ------------------
  |  Branch (189:13): [True: 4.57k, False: 544]
  ------------------
  190|  4.57k|            return false;
  191|    544|        if (cmd != CUE_EMPTY)
  ------------------
  |  Branch (191:13): [True: 354, False: 190]
  ------------------
  192|    354|            valid = true;
  193|    544|    }
  194|  19.8k|    return valid;
  195|  24.4k|}
mp_parse_cue:
  198|     52|{
  199|     52|    struct cue_file *f = talloc_zero(NULL, struct cue_file);
  ------------------
  |  |   27|     52|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|     52|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|     52|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  200|     52|    f->tags = talloc_zero(f, struct mp_tags);
  ------------------
  |  |   27|     52|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|     52|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|     52|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  201|       |
  202|     52|    data = skip_utf8_bom(data);
  203|       |
  204|     52|    char *filename = NULL;
  205|       |    // Global metadata, and copied into new tracks.
  206|     52|    struct cue_track proto_track = {0};
  207|     52|    struct cue_track *cur_track = NULL;
  208|       |
  209|  3.42k|    while (data.len) {
  ------------------
  |  Branch (209:12): [True: 3.42k, False: 3]
  ------------------
  210|  3.42k|        struct bstr param;
  211|  3.42k|        int cmd = read_cmd(&data, &param);
  212|  3.42k|        switch (cmd) {
  ------------------
  |  Branch (212:17): [True: 1.17k, False: 2.25k]
  ------------------
  213|     49|        case CUE_ERROR:
  ------------------
  |  Branch (213:9): [True: 49, False: 3.37k]
  ------------------
  214|     49|            talloc_free(f);
  ------------------
  |  |   47|     49|#define talloc_free                     ta_free
  ------------------
  215|     49|            return NULL;
  216|    217|        case CUE_TRACK: {
  ------------------
  |  Branch (216:9): [True: 217, False: 3.20k]
  ------------------
  217|    217|            if (bstr_find0(param, "AUDIO") == -1)
  ------------------
  |  Branch (217:17): [True: 217, False: 0]
  ------------------
  218|    217|                break;
  219|      0|            MP_TARRAY_GROW(f, f->tracks, f->num_tracks);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  220|      0|            f->num_tracks += 1;
  221|      0|            cur_track = &f->tracks[f->num_tracks - 1];
  222|      0|            *cur_track = proto_track;
  223|      0|            cur_track->tags = talloc_zero(f, struct mp_tags);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  224|      0|            break;
  225|    217|        }
  226|      0|        case CUE_TITLE:
  ------------------
  |  Branch (226:9): [True: 0, False: 3.42k]
  ------------------
  227|      0|        case CUE_PERFORMER: {
  ------------------
  |  Branch (227:9): [True: 0, False: 3.42k]
  ------------------
  228|      0|            static const char *metanames[] = {
  229|      0|                [CUE_TITLE] = "title",
  230|      0|                [CUE_PERFORMER] = "performer",
  231|      0|            };
  232|      0|            struct mp_tags *tags = cur_track ? cur_track->tags : f->tags;
  ------------------
  |  Branch (232:36): [True: 0, False: 0]
  ------------------
  233|      0|            mp_tags_set_bstr(tags, bstr0(metanames[cmd]), strip_quotes(param));
  234|      0|            break;
  235|      0|        }
  236|      0|        case CUE_INDEX: {
  ------------------
  |  Branch (236:9): [True: 0, False: 3.42k]
  ------------------
  237|      0|            int type = read_int(&param, true);
  238|      0|            double time = read_time(&param);
  239|      0|            if (cur_track) {
  ------------------
  |  Branch (239:17): [True: 0, False: 0]
  ------------------
  240|      0|                if (type == 1) {
  ------------------
  |  Branch (240:21): [True: 0, False: 0]
  ------------------
  241|      0|                    cur_track->start = time;
  242|      0|                    cur_track->filename = filename;
  243|      0|                } else if (type == 0) {
  ------------------
  |  Branch (243:28): [True: 0, False: 0]
  ------------------
  244|      0|                    cur_track->pregap_start = time;
  245|      0|                }
  246|      0|            }
  247|      0|            break;
  248|      0|        }
  249|  1.98k|        case CUE_FILE:
  ------------------
  |  Branch (249:9): [True: 1.98k, False: 1.44k]
  ------------------
  250|       |            // NOTE: FILE comes before TRACK, so don't use cur_track->filename
  251|  1.98k|            filename = read_quoted(f, &param);
  252|  1.98k|            break;
  253|  3.42k|        }
  254|  3.42k|    }
  255|       |
  256|      3|    return f;
  257|     52|}
cue.c:skip_utf8_bom:
  172|  24.4k|{
  173|  24.4k|    return bstr_startswith0(data, "\xEF\xBB\xBF") ? bstr_cut(data, 3) : data;
  ------------------
  |  Branch (173:12): [True: 47, False: 24.4k]
  ------------------
  174|  24.4k|}
cue.c:read_cmd:
   91|  28.3k|{
   92|  28.3k|    struct bstr line = bstr_strip_linebreaks(bstr_getline(*data, data));
   93|  28.3k|    line = lstrip_whitespace(line);
   94|  28.3k|    if (line.len == 0)
  ------------------
  |  Branch (94:9): [True: 250, False: 28.1k]
  ------------------
   95|    250|        return CUE_EMPTY;
   96|   376k|    for (int n = 0; cue_command_strings[n].command != -1; n++) {
  ------------------
  |  Branch (96:21): [True: 352k, False: 24.3k]
  ------------------
   97|   352k|        struct bstr name = bstr0(cue_command_strings[n].text);
   98|   352k|        if (bstr_case_startswith(line, name)) {
  ------------------
  |  Branch (98:13): [True: 3.74k, False: 348k]
  ------------------
   99|  3.74k|            struct bstr rest = bstr_cut(line, name.len);
  100|  3.74k|            struct bstr par = lstrip_whitespace(rest);
  101|  3.74k|            if (rest.len && par.len == rest.len)
  ------------------
  |  Branch (101:17): [True: 3.73k, False: 3]
  |  Branch (101:29): [True: 16, False: 3.72k]
  ------------------
  102|     16|                continue;
  103|  3.72k|            if (out_params)
  ------------------
  |  Branch (103:17): [True: 3.32k, False: 405]
  ------------------
  104|  3.32k|                *out_params = par;
  105|  3.72k|            return cue_command_strings[n].command;
  106|  3.74k|        }
  107|   352k|    }
  108|  24.3k|    return CUE_ERROR;
  109|  28.1k|}
cue.c:lstrip_whitespace:
   68|  34.0k|{
   69|  63.6k|    while (data.len) {
  ------------------
  |  Branch (69:12): [True: 63.2k, False: 376]
  ------------------
   70|  63.2k|        bstr rest = data;
   71|  63.2k|        int code = bstr_decode_utf8(data, &rest);
   72|  63.2k|        if (code < 0) {
  ------------------
  |  Branch (72:13): [True: 4.31k, False: 58.9k]
  ------------------
   73|       |            // Tolerate Latin1 => probing works (which doesn't convert charsets).
   74|  4.31k|            code = data.start[0];
   75|  4.31k|            rest.start += 1;
   76|  4.31k|            rest.len -= 1;
   77|  4.31k|        }
   78|   411k|        for (size_t n = 0; n < MP_ARRAY_SIZE(spaces); n++) {
  ------------------
  |  |   48|   411k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (78:28): [True: 378k, False: 33.7k]
  ------------------
   79|   378k|            if (spaces[n] == code) {
  ------------------
  |  Branch (79:17): [True: 29.5k, False: 348k]
  ------------------
   80|  29.5k|                data = rest;
   81|  29.5k|                goto next;
   82|  29.5k|            }
   83|   378k|        }
   84|  33.7k|        break;
   85|  33.7k|    next: ;
   86|  29.5k|    }
   87|  34.0k|    return data;
   88|  34.0k|}
cue.c:eat_char:
  112|  1.98k|{
  113|  1.98k|    if (data->len && data->start[0] == ch) {
  ------------------
  |  Branch (113:9): [True: 1.98k, False: 0]
  |  Branch (113:22): [True: 212, False: 1.77k]
  ------------------
  114|    212|        *data = bstr_cut(*data, 1);
  115|    212|        return true;
  116|  1.77k|    } else {
  117|  1.77k|        return false;
  118|  1.77k|    }
  119|  1.98k|}
cue.c:read_quoted:
  122|  1.98k|{
  123|  1.98k|    *data = lstrip_whitespace(*data);
  124|  1.98k|    if (!eat_char(data, '"'))
  ------------------
  |  Branch (124:9): [True: 1.77k, False: 212]
  ------------------
  125|  1.77k|        return NULL;
  126|    212|    int end = bstrchr(*data, '"');
  127|    212|    if (end < 0)
  ------------------
  |  Branch (127:9): [True: 130, False: 82]
  ------------------
  128|    130|        return NULL;
  129|     82|    struct bstr res = bstr_splice(*data, 0, end);
  130|     82|    *data = bstr_cut(*data, end + 1);
  131|     82|    return bstrto0(talloc_ctx, res);
  132|    212|}

demux_set_ts_offset:
  921|  66.9k|{
  922|  66.9k|    struct demux_internal *in = demuxer->in;
  923|  66.9k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  66.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  924|  66.9k|    in->ts_offset = offset;
  925|  66.9k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  66.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  926|  66.9k|}
demux_alloc_sh_stream:
  950|  26.9k|{
  951|  26.9k|    struct sh_stream *sh = talloc_ptrtype(NULL, sh);
  ------------------
  |  |   34|  26.9k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  26.9k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  26.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  952|  26.9k|    *sh = (struct sh_stream) {
  953|  26.9k|        .type = type,
  954|  26.9k|        .index = -1,
  955|  26.9k|        .ff_index = -1,     // may be overwritten by demuxer
  956|  26.9k|        .demuxer_id = -1,   // ... same
  957|  26.9k|        .program_id = -1,   // ... same
  958|  26.9k|        .codec = talloc_zero(sh, struct mp_codec_params),
  ------------------
  |  |   27|  26.9k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  26.9k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  26.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  959|  26.9k|        .tags = talloc_zero(sh, struct mp_tags),
  ------------------
  |  |   27|  26.9k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  26.9k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  26.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  960|  26.9k|    };
  961|  26.9k|    sh->codec->type = type;
  962|  26.9k|    return sh;
  963|  26.9k|}
demux_add_sh_stream:
 1036|  26.9k|{
 1037|  26.9k|    struct demux_internal *in = demuxer->in;
 1038|  26.9k|    mp_assert(demuxer == in->d_thread);
  ------------------
  |  |   41|  26.9k|#define mp_assert assert
  ------------------
 1039|  26.9k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  26.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1040|  26.9k|    demux_add_sh_stream_locked(in, sh);
 1041|  26.9k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  26.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1042|  26.9k|}
demux_get_stream:
 1049|  70.6M|{
 1050|  70.6M|    struct demux_internal *in = demuxer->in;
 1051|  70.6M|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  70.6M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1052|  70.6M|    mp_assert(index >= 0 && index < in->num_streams);
  ------------------
  |  |   41|  70.6M|#define mp_assert assert
  ------------------
 1053|  70.6M|    struct sh_stream *r = in->streams[index];
 1054|  70.6M|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  70.6M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1055|  70.6M|    return r;
 1056|  70.6M|}
demux_get_num_stream:
 1060|   207k|{
 1061|   207k|    struct demux_internal *in = demuxer->in;
 1062|   207k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   207k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1063|   207k|    int r = in->num_streams;
 1064|   207k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   207k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1065|   207k|    return r;
 1066|   207k|}
demux_free:
 1109|   236k|{
 1110|   236k|    if (!demuxer)
  ------------------
  |  Branch (1110:9): [True: 25.0k, False: 211k]
  ------------------
 1111|  25.0k|        return;
 1112|   211k|    struct demux_internal *in = demuxer->in;
 1113|   211k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|   211k|#define mp_assert assert
  ------------------
 1114|       |
 1115|   211k|    demux_stop_thread(demuxer);
 1116|   211k|    demux_shutdown(in);
 1117|   211k|    demux_dealloc(in);
 1118|   211k|}
demux_free_async:
 1128|  5.09k|{
 1129|  5.09k|    struct demux_internal *in = demuxer->in;
 1130|  5.09k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|  5.09k|#define mp_assert assert
  ------------------
 1131|       |
 1132|  5.09k|    if (!in->threading)
  ------------------
  |  Branch (1132:9): [True: 977, False: 4.11k]
  ------------------
 1133|    977|        return NULL;
 1134|       |
 1135|  4.11k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  4.11k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1136|  4.11k|    in->thread_terminate = true;
 1137|  4.11k|    in->shutdown_async = true;
 1138|  4.11k|    mp_cond_signal(&in->wakeup);
 1139|  4.11k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  4.11k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1140|       |
 1141|  4.11k|    return (struct demux_free_async_state *)demuxer->in; // lies
 1142|  5.09k|}
demux_free_async_finish:
 1160|  12.3k|{
 1161|  12.3k|    struct demux_internal *in = (struct demux_internal *)state; // reverse lies
 1162|       |
 1163|  12.3k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  12.3k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1164|  12.3k|    bool busy = in->shutdown_async;
 1165|  12.3k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  12.3k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1166|       |
 1167|  12.3k|    if (busy)
  ------------------
  |  Branch (1167:9): [True: 8.23k, False: 4.11k]
  ------------------
 1168|  8.23k|        return false;
 1169|       |
 1170|  4.11k|    demux_stop_thread(in->d_user);
 1171|  4.11k|    demux_dealloc(in);
 1172|  4.11k|    return true;
 1173|  12.3k|}
demux_cancel_and_free:
 1179|  5.09k|{
 1180|  5.09k|    if (!demuxer)
  ------------------
  |  Branch (1180:9): [True: 4.11k, False: 977]
  ------------------
 1181|  4.11k|        return;
 1182|    977|    mp_cancel_trigger(demuxer->cancel);
 1183|    977|    demux_free(demuxer);
 1184|    977|}
demux_start_thread:
 1188|  4.25k|{
 1189|  4.25k|    struct demux_internal *in = demuxer->in;
 1190|  4.25k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|  4.25k|#define mp_assert assert
  ------------------
 1191|       |
 1192|  4.25k|    if (!in->threading) {
  ------------------
  |  Branch (1192:9): [True: 4.11k, False: 138]
  ------------------
 1193|  4.11k|        in->threading = true;
 1194|  4.11k|        if (mp_thread_create(&in->thread, demux_thread, in))
  ------------------
  |  |  211|  4.11k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 4.11k]
  |  |  ------------------
  ------------------
 1195|      0|            in->threading = false;
 1196|  4.11k|    }
 1197|  4.25k|}
demux_stop_thread:
 1200|   215k|{
 1201|   215k|    struct demux_internal *in = demuxer->in;
 1202|   215k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
 1203|       |
 1204|   215k|    if (in->threading) {
  ------------------
  |  Branch (1204:9): [True: 4.11k, False: 211k]
  ------------------
 1205|  4.11k|        mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  4.11k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1206|  4.11k|        in->thread_terminate = true;
 1207|  4.11k|        mp_cond_signal(&in->wakeup);
 1208|  4.11k|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  4.11k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1209|  4.11k|        mp_thread_join(in->thread);
  ------------------
  |  |  212|  4.11k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
 1210|  4.11k|        in->threading = false;
 1211|  4.11k|        in->thread_terminate = false;
 1212|  4.11k|    }
 1213|   215k|}
demux_set_wakeup_cb:
 1217|  9.35k|{
 1218|  9.35k|    struct demux_internal *in = demuxer->in;
 1219|  9.35k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  9.35k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1220|  9.35k|    in->wakeup_cb = cb;
 1221|  9.35k|    in->wakeup_cb_ctx = ctx;
 1222|  9.35k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  9.35k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1223|  9.35k|}
demux_start_prefetch:
 1226|    138|{
 1227|    138|    struct demux_internal *in = demuxer->in;
 1228|    138|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|    138|#define mp_assert assert
  ------------------
 1229|       |
 1230|    138|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|    138|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1231|    138|    in->reading = true;
 1232|    138|    mp_cond_signal(&in->wakeup);
 1233|    138|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|    138|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1234|    138|}
stream_type_name:
 1237|  1.49M|{
 1238|  1.49M|    switch (type) {
 1239|   296k|    case STREAM_VIDEO:  return "video";
  ------------------
  |  Branch (1239:5): [True: 296k, False: 1.20M]
  ------------------
 1240|  1.20M|    case STREAM_AUDIO:  return "audio";
  ------------------
  |  Branch (1240:5): [True: 1.20M, False: 296k]
  ------------------
 1241|     79|    case STREAM_SUB:    return "sub";
  ------------------
  |  Branch (1241:5): [True: 79, False: 1.49M]
  ------------------
 1242|      0|    default:            return "unknown";
  ------------------
  |  Branch (1242:5): [True: 0, False: 1.49M]
  ------------------
 1243|  1.49M|    }
 1244|  1.49M|}
demux_read_packet_async:
 2771|  1.43M|{
 2772|  1.43M|    return demux_read_packet_async_until(sh, MP_NOPTS_VALUE, out_pkt);
  ------------------
  |  |   38|  1.43M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2773|  1.43M|}
demux_read_packet_async_until:
 2781|  1.43M|{
 2782|  1.43M|    struct demux_stream *ds = sh ? sh->ds : NULL;
  ------------------
  |  Branch (2782:31): [True: 1.43M, False: 0]
  ------------------
 2783|  1.43M|    *out_pkt = NULL;
 2784|  1.43M|    if (!ds)
  ------------------
  |  Branch (2784:9): [True: 0, False: 1.43M]
  ------------------
 2785|      0|        return -1;
 2786|  1.43M|    struct demux_internal *in = ds->in;
 2787|       |
 2788|  1.43M|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  1.43M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2789|  1.43M|    int r = -1;
 2790|  1.43M|    while (1) {
  ------------------
  |  Branch (2790:12): [Folded - Ignored]
  ------------------
 2791|  1.43M|        r = dequeue_packet(ds, min_pts, out_pkt);
 2792|  1.43M|        if (in->threading || in->blocked || r != 0)
  ------------------
  |  Branch (2792:13): [True: 1.43M, False: 0]
  |  Branch (2792:30): [True: 0, False: 0]
  |  Branch (2792:45): [True: 0, False: 0]
  ------------------
 2793|  1.43M|            break;
 2794|       |        // Needs to actually read packets until we got a packet or EOF.
 2795|      0|        thread_work(in);
 2796|      0|    }
 2797|  1.43M|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  1.43M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2798|  1.43M|    return r;
 2799|  1.43M|}
demux_read_any_packet:
 2804|  68.7k|{
 2805|  68.7k|    struct demux_internal *in = demuxer->in;
 2806|  68.7k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  68.7k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2807|  68.7k|    mp_assert(!in->threading); // doesn't work with threading
  ------------------
  |  |   41|  68.7k|#define mp_assert assert
  ------------------
 2808|  68.7k|    struct demux_packet *out_pkt = NULL;
 2809|  68.7k|    bool read_more = true;
 2810|   275k|    while (read_more && !in->blocked) {
  ------------------
  |  Branch (2810:12): [True: 213k, False: 62.3k]
  |  Branch (2810:25): [True: 213k, False: 0]
  ------------------
 2811|   213k|        bool all_eof = true;
 2812|   537k|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2812:25): [True: 330k, False: 206k]
  ------------------
 2813|   330k|            int r = dequeue_packet(in->streams[n]->ds, MP_NOPTS_VALUE, &out_pkt);
  ------------------
  |  |   38|   330k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2814|   330k|            if (r > 0)
  ------------------
  |  Branch (2814:17): [True: 6.35k, False: 324k]
  ------------------
 2815|  6.35k|                goto done;
 2816|   324k|            if (r == 0)
  ------------------
  |  Branch (2816:17): [True: 245k, False: 78.9k]
  ------------------
 2817|   245k|                all_eof = false;
 2818|   324k|        }
 2819|       |        // retry after calling this
 2820|   206k|        read_more = thread_work(in);
 2821|   206k|        read_more &= !all_eof;
 2822|   206k|    }
 2823|  68.7k|done:
 2824|  68.7k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  68.7k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2825|  68.7k|    return out_pkt;
 2826|  68.7k|}
demux_update:
 3142|   119k|{
 3143|   119k|    mp_assert(demuxer == demuxer->in->d_user);
  ------------------
  |  |   41|   119k|#define mp_assert assert
  ------------------
 3144|   119k|    struct demux_internal *in = demuxer->in;
 3145|       |
 3146|   119k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   119k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 3147|       |
 3148|   119k|    if (!in->threading)
  ------------------
  |  Branch (3148:9): [True: 21.9k, False: 97.4k]
  ------------------
 3149|  21.9k|        update_cache(in);
 3150|       |
 3151|       |    // This implies this function is actually called from "the" user thread.
 3152|   119k|    in->d_user->filesize = in->stream_size;
 3153|       |
 3154|   119k|    pts = MP_ADD_PTS(pts, -in->ts_offset);
  ------------------
  |  |   66|   119k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|   119k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 21.5k, False: 97.8k]
  |  |  ------------------
  ------------------
 3155|       |
 3156|   119k|    struct timed_metadata *prev = lookup_timed_metadata(in, in->last_playback_pts);
 3157|   119k|    struct timed_metadata *cur = lookup_timed_metadata(in, pts);
 3158|   119k|    if (prev != cur || in->force_metadata_update) {
  ------------------
  |  Branch (3158:9): [True: 0, False: 119k]
  |  Branch (3158:24): [True: 21.5k, False: 97.8k]
  ------------------
 3159|  21.5k|        in->force_metadata_update = false;
 3160|  21.5k|        update_final_metadata(demuxer, cur);
 3161|  21.5k|        demuxer->events |= DEMUX_EVENT_METADATA;
 3162|  21.5k|    }
 3163|       |
 3164|   119k|    in->last_playback_pts = pts;
 3165|       |
 3166|   119k|    demuxer->events |= in->events;
 3167|   119k|    in->events = 0;
 3168|   119k|    if (demuxer->events & (DEMUX_EVENT_METADATA | DEMUX_EVENT_STREAMS))
  ------------------
  |  Branch (3168:9): [True: 26.0k, False: 93.3k]
  ------------------
 3169|  26.0k|        demux_update_replaygain(demuxer);
 3170|   119k|    if (demuxer->events & DEMUX_EVENT_DURATION)
  ------------------
  |  Branch (3170:9): [True: 38.7k, False: 80.6k]
  ------------------
 3171|  38.7k|        demuxer->duration = in->duration;
 3172|       |
 3173|   119k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   119k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 3174|   119k|}
demux_close_stream:
 3211|  1.46k|{
 3212|  1.46k|    struct demux_internal *in = demuxer->in;
 3213|  1.46k|    mp_assert(!in->threading && demuxer == in->d_thread);
  ------------------
  |  |   41|  1.46k|#define mp_assert assert
  ------------------
 3214|       |
 3215|  1.46k|    if (!demuxer->stream || !in->owns_stream)
  ------------------
  |  Branch (3215:9): [True: 0, False: 1.46k]
  |  Branch (3215:29): [True: 0, False: 1.46k]
  ------------------
 3216|      0|        return;
 3217|       |
 3218|  1.46k|    MP_VERBOSE(demuxer, "demuxer read all data; closing stream\n");
  ------------------
  |  |   88|  1.46k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.46k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3219|  1.46k|    free_stream(demuxer->stream);
 3220|  1.46k|    demuxer->stream = NULL;
 3221|  1.46k|    in->d_user->stream = NULL;
 3222|  1.46k|}
demux_open_url:
 3482|  23.6k|{
 3483|  23.6k|    if (!params)
  ------------------
  |  Branch (3483:9): [True: 0, False: 23.6k]
  ------------------
 3484|      0|        return NULL;
 3485|  23.6k|    struct mp_cancel *priv_cancel = mp_cancel_new(NULL);
 3486|  23.6k|    if (cancel)
  ------------------
  |  Branch (3486:9): [True: 23.6k, False: 0]
  ------------------
 3487|  23.6k|        mp_cancel_set_parent(priv_cancel, cancel);
 3488|  23.6k|    struct stream *s = params->external_stream;
 3489|  23.6k|    if (!s) {
  ------------------
  |  Branch (3489:9): [True: 23.6k, False: 0]
  ------------------
 3490|  23.6k|        s = stream_create(url, STREAM_READ | params->stream_flags,
  ------------------
  |  |   41|  23.6k|#define STREAM_READ               0
  ------------------
 3491|  23.6k|                          priv_cancel, global);
 3492|  23.6k|        if (s && params->init_fragment.len) {
  ------------------
  |  Branch (3492:13): [True: 22.9k, False: 693]
  |  Branch (3492:18): [True: 0, False: 22.9k]
  ------------------
 3493|      0|            s = create_webshit_concat_stream(global, priv_cancel,
 3494|      0|                                             params->init_fragment, s);
 3495|      0|        }
 3496|  23.6k|    }
 3497|  23.6k|    if (!s) {
  ------------------
  |  Branch (3497:9): [True: 693, False: 22.9k]
  ------------------
 3498|    693|        talloc_free(priv_cancel);
  ------------------
  |  |   47|    693|#define talloc_free                     ta_free
  ------------------
 3499|    693|        return NULL;
 3500|    693|    }
 3501|  22.9k|    struct demuxer *d = demux_open(s, priv_cancel, params, global);
 3502|  22.9k|    if (d) {
  ------------------
  |  Branch (3502:9): [True: 21.1k, False: 1.85k]
  ------------------
 3503|  21.1k|        talloc_steal(d->in, priv_cancel);
  ------------------
  |  |   38|  21.1k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  21.1k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 3504|  21.1k|        mp_assert(d->cancel);
  ------------------
  |  |   41|  21.1k|#define mp_assert assert
  ------------------
 3505|  21.1k|    } else {
 3506|  1.85k|        params->demuxer_failed = true;
 3507|  1.85k|        if (!params->external_stream)
  ------------------
  |  Branch (3507:13): [True: 1.85k, False: 0]
  ------------------
 3508|  1.85k|            free_stream(s);
 3509|  1.85k|        talloc_free(priv_cancel);
  ------------------
  |  |   47|  1.85k|#define talloc_free                     ta_free
  ------------------
 3510|  1.85k|    }
 3511|  22.9k|    return d;
 3512|  22.9k|}
demux_flush:
 3516|   215k|{
 3517|   215k|    struct demux_internal *in = demuxer->in;
 3518|   215k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
 3519|       |
 3520|   215k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   215k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 3521|   215k|    clear_reader_state(in, true);
 3522|   236k|    for (int n = 0; n < in->num_ranges; n++)
  ------------------
  |  Branch (3522:21): [True: 21.5k, False: 215k]
  ------------------
 3523|  21.5k|        clear_cached_range(in, in->ranges[n]);
 3524|   215k|    free_empty_cached_ranges(in);
 3525|   242k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3525:21): [True: 26.9k, False: 215k]
  ------------------
 3526|  26.9k|        struct demux_stream *ds = in->streams[n]->ds;
 3527|  26.9k|        ds->refreshing = false;
 3528|  26.9k|        ds->eof = false;
 3529|  26.9k|    }
 3530|   215k|    in->eof = false;
 3531|   215k|    in->seeking = false;
 3532|   215k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   215k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 3533|   215k|}
demux_seek:
 3792|  62.3k|{
 3793|  62.3k|    struct demux_internal *in = demuxer->in;
 3794|  62.3k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|  62.3k|#define mp_assert assert
  ------------------
 3795|       |
 3796|  62.3k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  62.3k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 3797|       |
 3798|  62.3k|    if (!(flags & SEEK_FACTOR))
  ------------------
  |  |   92|  62.3k|#define SEEK_FACTOR   (1 << 1)      // argument is in range [0,1]
  ------------------
  |  Branch (3798:9): [True: 62.3k, False: 0]
  ------------------
 3799|  62.3k|        seek_pts = MP_ADD_PTS(seek_pts, -in->ts_offset);
  ------------------
  |  |   66|  62.3k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  62.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 62.3k]
  |  |  ------------------
  ------------------
 3800|       |
 3801|  62.3k|    int res = queue_seek(in, seek_pts, flags, true);
 3802|       |
 3803|  62.3k|    mp_cond_signal(&in->wakeup);
 3804|  62.3k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  62.3k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 3805|       |
 3806|  62.3k|    return res;
 3807|  62.3k|}
demuxer_select_track:
 4008|  70.5M|{
 4009|  70.5M|    struct demux_internal *in = demuxer->in;
 4010|  70.5M|    struct demux_stream *ds = stream->ds;
 4011|  70.5M|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  70.5M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 4012|       |    // don't flush buffers if stream is already selected / unselected
 4013|  70.5M|    if (ds->selected != selected) {
  ------------------
  |  Branch (4013:9): [True: 162k, False: 70.3M]
  ------------------
 4014|   162k|        MP_VERBOSE(in, "%sselect track %d\n", selected ? "" : "de", stream->index);
  ------------------
  |  |   88|   162k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   324k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 83.3k, False: 78.9k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4015|   162k|        ds->selected = selected;
 4016|   162k|        update_stream_selection_state(in, ds);
 4017|   162k|        in->tracks_switched = true;
 4018|   162k|        if (ds->selected)
  ------------------
  |  Branch (4018:13): [True: 83.3k, False: 78.9k]
  ------------------
 4019|  83.3k|            refresh_track(in, stream, ref_pts);
 4020|   162k|        if (in->threading) {
  ------------------
  |  Branch (4020:13): [True: 5.70k, False: 156k]
  ------------------
 4021|  5.70k|            mp_cond_signal(&in->wakeup);
 4022|   156k|        } else {
 4023|   156k|            execute_trackswitch(in);
 4024|   156k|        }
 4025|   162k|    }
 4026|  70.5M|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  70.5M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 4027|  70.5M|}
demux_stream_is_selected:
 4049|  1.79M|{
 4050|  1.79M|    if (!stream)
  ------------------
  |  Branch (4050:9): [True: 0, False: 1.79M]
  ------------------
 4051|      0|        return false;
 4052|  1.79M|    bool r = false;
 4053|  1.79M|    mp_mutex_lock(&stream->ds->in->lock);
  ------------------
  |  |  131|  1.79M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 4054|  1.79M|    r = stream->ds->selected;
 4055|  1.79M|    mp_mutex_unlock(&stream->ds->in->lock);
  ------------------
  |  |  133|  1.79M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 4056|  1.79M|    return r;
 4057|  1.79M|}
demux_set_stream_wakeup_cb:
 4061|  9.76k|{
 4062|  9.76k|    mp_mutex_lock(&sh->ds->in->lock);
  ------------------
  |  |  131|  9.76k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 4063|  9.76k|    sh->ds->wakeup_cb = cb;
 4064|  9.76k|    sh->ds->wakeup_cb_ctx = ctx;
 4065|  9.76k|    sh->ds->need_wakeup = true;
 4066|  9.76k|    mp_mutex_unlock(&sh->ds->in->lock);
  ------------------
  |  |  133|  9.76k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 4067|  9.76k|}
demuxer_add_chapter:
 4108|  2.13k|{
 4109|  2.13k|    struct demux_chapter new = {
 4110|  2.13k|        .original_index = demuxer->num_chapters,
 4111|  2.13k|        .pts = pts,
 4112|  2.13k|        .metadata = talloc_zero(demuxer, struct mp_tags),
  ------------------
  |  |   27|  2.13k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  2.13k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  2.13k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4113|  2.13k|        .demuxer_id = demuxer_id,
 4114|  2.13k|    };
 4115|  2.13k|    mp_tags_set_str(new.metadata, "TITLE", name);
 4116|  2.13k|    MP_TARRAY_APPEND(demuxer, demuxer->chapters, demuxer->num_chapters, new);
  ------------------
  |  |  105|  2.13k|    do {                                            \
  |  |  106|  2.13k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  2.13k|    do {                                            \
  |  |  |  |   97|  2.13k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  2.13k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  2.13k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  2.13k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 120, False: 2.01k]
  |  |  |  |  ------------------
  |  |  |  |   99|  2.13k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    120|    do {                                                        \
  |  |  |  |  |  |   89|    120|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    120|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    120|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    120|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    120|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    120|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    120|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  2.13k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  2.13k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  2.13k|        (idxvar)++;                                 \
  |  |  109|  2.13k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4117|  2.13k|    return demuxer->num_chapters - 1;
 4118|  2.13k|}
demux_report_unbuffered_read_bytes:
 4464|  70.6M|{
 4465|  70.6M|    struct demux_internal *in = demuxer->in;
 4466|  70.6M|    mp_assert(demuxer == in->d_thread);
  ------------------
  |  |   41|  70.6M|#define mp_assert assert
  ------------------
 4467|       |
 4468|  70.6M|    in->slave_unbuffered_read_bytes += new;
 4469|  70.6M|}
demux_get_bytes_read_hack:
 4474|  70.6M|{
 4475|  70.6M|    struct demux_internal *in = demuxer->in;
 4476|       |
 4477|       |    // Required because demuxer==in->d_user, and we access in->d_thread.
 4478|       |    // Locking won't solve this, because we also need to access struct stream.
 4479|  70.6M|    mp_assert(!in->threading);
  ------------------
  |  |   41|  70.6M|#define mp_assert assert
  ------------------
 4480|       |
 4481|  70.6M|    update_bytes_read(in);
 4482|       |
 4483|  70.6M|    int64_t res = in->hack_unbuffered_read_bytes;
 4484|  70.6M|    in->hack_unbuffered_read_bytes = 0;
 4485|  70.6M|    return res;
 4486|  70.6M|}
demux_get_reader_state:
 4507|   175k|{
 4508|   175k|    struct demux_internal *in = demuxer->in;
 4509|   175k|    mp_assert(demuxer == in->d_user);
  ------------------
  |  |   41|   175k|#define mp_assert assert
  ------------------
 4510|       |
 4511|   175k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   175k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 4512|       |
 4513|   175k|    *r = (struct demux_reader_state){
 4514|   175k|        .eof = in->eof,
 4515|   175k|        .ts_info = {
 4516|   175k|            .reader = MP_NOPTS_VALUE,
  ------------------
  |  |   38|   175k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 4517|   175k|            .end = MP_NOPTS_VALUE,
  ------------------
  |  |   38|   175k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 4518|   175k|            .duration = -1,
 4519|   175k|        },
 4520|   175k|        .total_bytes = in->total_bytes,
 4521|   175k|        .seeking = in->seeking_in_progress,
 4522|   175k|        .low_level_seeks = in->low_level_seeks,
 4523|   175k|        .ts_last = in->demux_ts,
 4524|   175k|        .bytes_per_second = in->bytes_per_second,
 4525|   175k|        .byte_level_seeks = in->byte_level_seeks,
 4526|   175k|        .file_cache_bytes = in->cache ? demux_cache_get_size(in->cache) : -1,
  ------------------
  |  Branch (4526:29): [True: 0, False: 175k]
  ------------------
 4527|   175k|    };
 4528|   175k|    bool any_packets = false;
 4529|   703k|    for (int n = 0; n < STREAM_TYPE_COUNT; n++) {
  ------------------
  |  Branch (4529:21): [True: 527k, False: 175k]
  ------------------
 4530|   527k|        r->ts_per_stream[n] = r->ts_info;
 4531|   527k|    }
 4532|   356k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (4532:21): [True: 180k, False: 175k]
  ------------------
 4533|   180k|        struct demux_stream *ds = in->streams[n]->ds;
 4534|   180k|        if (ds->eager && !(!ds->queue->head && ds->eof) && !ds->ignore_eof) {
  ------------------
  |  Branch (4534:13): [True: 175k, False: 5.00k]
  |  Branch (4534:28): [True: 17.4k, False: 158k]
  |  Branch (4534:48): [True: 11.7k, False: 5.62k]
  |  Branch (4534:60): [True: 164k, False: 0]
  ------------------
 4535|   164k|            r->underrun |= !ds->reader_head && !ds->eof && !ds->still_image;
  ------------------
  |  Branch (4535:28): [True: 5.62k, False: 158k]
  |  Branch (4535:48): [True: 5.62k, False: 0]
  |  Branch (4535:60): [True: 5.62k, False: 0]
  ------------------
 4536|   164k|            any_packets |= !!ds->reader_head;
 4537|       |
 4538|   164k|            double ts_reader = ds->base_ts;
 4539|   164k|            double ts_end = ds->queue->last_ts;
 4540|   164k|            double ts_duration = -1;
 4541|   164k|            if (ts_reader != MP_NOPTS_VALUE && ts_reader <= ts_end)
  ------------------
  |  |   38|   328k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (4541:17): [True: 155k, False: 9.13k]
  |  Branch (4541:48): [True: 155k, False: 0]
  ------------------
 4542|   155k|                ts_duration = ts_end - ts_reader;
 4543|       |
 4544|   164k|            struct demux_ctrl_ts_info *i = &r->ts_per_stream[ds->type];
 4545|   164k|            i->reader = MP_PTS_MIN(i->reader, ts_reader);
  ------------------
  |  |   63|   164k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|   328k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 164k]
  |  |  |  |  |  Branch (44:23): [True: 164k, False: 0]
  |  |  |  |  |  Branch (44:29): [True: 9.13k, False: 155k]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 164k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4546|   164k|            i->end = MP_PTS_MIN(i->end, ts_end);
  ------------------
  |  |   63|   164k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|   328k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 164k]
  |  |  |  |  |  Branch (44:23): [True: 164k, False: 0]
  |  |  |  |  |  Branch (44:29): [True: 9.13k, False: 155k]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 164k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4547|   164k|            i->duration = ts_duration;
 4548|   164k|        }
 4549|   180k|        r->fw_bytes += get_forward_buffered_bytes(ds);
 4550|   180k|    }
 4551|   175k|    struct demux_ctrl_ts_info *ots = &r->ts_info;
 4552|       |    // find stream type with lowest duration and use its state
 4553|   703k|    for (int n = 0; n < STREAM_TYPE_COUNT; n++) {
  ------------------
  |  Branch (4553:21): [True: 527k, False: 175k]
  ------------------
 4554|   527k|        struct demux_ctrl_ts_info *ts = &r->ts_per_stream[n];
 4555|   527k|        if (r->ts_info.duration != -1) {
  ------------------
  |  Branch (4555:13): [True: 302k, False: 225k]
  ------------------
 4556|       |            // skip if timestamps unknown
 4557|   302k|            if (ts->duration == -1)
  ------------------
  |  Branch (4557:17): [True: 302k, False: 0]
  ------------------
 4558|   302k|                continue;
 4559|       |            // skip if we already know of a smaller cached stream
 4560|      0|            if (ts->duration > ots->duration)
  ------------------
  |  Branch (4560:17): [True: 0, False: 0]
  ------------------
 4561|      0|                continue;
 4562|       |            // skip empty subtitle streams when other streams exist
 4563|      0|            if (n == STREAM_SUB && ts->duration == 0.0)
  ------------------
  |  Branch (4563:17): [True: 0, False: 0]
  |  Branch (4563:36): [True: 0, False: 0]
  ------------------
 4564|      0|                continue;
 4565|      0|        }
 4566|   225k|        ots->duration = ts->duration;
 4567|   225k|        ots->reader = ts->reader;
 4568|   225k|        ots->end = ts->end;
 4569|   225k|    }
 4570|   175k|    r->idle = (!in->reading && !r->underrun) || r->eof;
  ------------------
  |  Branch (4570:16): [True: 166k, False: 9.08k]
  |  Branch (4570:32): [True: 166k, False: 0]
  |  Branch (4570:49): [True: 0, False: 9.08k]
  ------------------
 4571|   175k|    r->underrun &= !r->idle && in->threading;
  ------------------
  |  Branch (4571:20): [True: 9.08k, False: 166k]
  |  Branch (4571:32): [True: 9.08k, False: 0]
  ------------------
 4572|   175k|    ots->reader = MP_ADD_PTS(ots->reader, in->ts_offset);
  ------------------
  |  |   66|   175k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|   175k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 20.8k, False: 155k]
  |  |  ------------------
  ------------------
 4573|   175k|    ots->end = MP_ADD_PTS(ots->end, in->ts_offset);
  ------------------
  |  |   66|   175k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|   175k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 20.8k, False: 155k]
  |  |  ------------------
  ------------------
 4574|   175k|    if (ots->reader != MP_NOPTS_VALUE && ots->reader <= ots->end)
  ------------------
  |  |   38|   351k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (4574:9): [True: 155k, False: 20.8k]
  |  Branch (4574:42): [True: 155k, False: 0]
  ------------------
 4575|   155k|        ots->duration = ots->end - ots->reader;
 4576|   175k|    if (in->seeking || !any_packets)
  ------------------
  |  Branch (4576:9): [True: 1, False: 175k]
  |  Branch (4576:24): [True: 17.3k, False: 158k]
  ------------------
 4577|  17.3k|        ots->duration = 0;
 4578|   351k|    for (int n = 0; n < MPMIN(in->num_ranges, MAX_SEEK_RANGES); n++) {
  ------------------
  |  |   44|   351k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 351k]
  |  |  ------------------
  ------------------
  |  Branch (4578:21): [True: 175k, False: 175k]
  ------------------
 4579|   175k|        struct demux_cached_range *range = in->ranges[n];
 4580|   175k|        if (range->seek_start != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   175k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (4580:13): [True: 0, False: 175k]
  ------------------
 4581|      0|            r->seek_ranges[r->num_seek_ranges++] =
 4582|      0|                (struct demux_seek_range){
 4583|      0|                    .start = MP_ADD_PTS(range->seek_start, in->ts_offset),
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 4584|      0|                    .end = MP_ADD_PTS(range->seek_end, in->ts_offset),
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 4585|      0|                };
 4586|      0|            r->bof_cached |= range->is_bof;
 4587|      0|            r->eof_cached |= range->is_eof;
 4588|      0|        }
 4589|   175k|    }
 4590|       |
 4591|   175k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   175k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 4592|   175k|}
demux_cancel_test:
 4595|  5.29M|{
 4596|  5.29M|    return mp_cancel_test(demuxer->cancel);
 4597|  5.29M|}
demux_copy_chapter_data:
 4600|  4.53k|{
 4601|  4.53k|    struct demux_chapter *new = talloc_array(NULL, struct demux_chapter, num);
  ------------------
  |  |   29|  4.53k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  4.53k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  4.53k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4602|  69.3k|    for (int n = 0; n < num; n++) {
  ------------------
  |  Branch (4602:21): [True: 64.7k, False: 4.53k]
  ------------------
 4603|  64.7k|        new[n] = c[n];
 4604|  64.7k|        new[n].metadata = mp_tags_dup(new, new[n].metadata);
 4605|  64.7k|    }
 4606|  4.53k|    return new;
 4607|  4.53k|}
demux.c:demux_add_sh_stream_locked:
  970|  26.9k|{
  971|  26.9k|    mp_assert(!sh->ds); // must not be added yet
  ------------------
  |  |   41|  26.9k|#define mp_assert assert
  ------------------
  972|       |
  973|  26.9k|    sh->index = in->num_streams;
  974|       |
  975|  26.9k|    sh->ds = talloc(sh, struct demux_stream);
  ------------------
  |  |   26|  26.9k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  26.9k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  26.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  976|  26.9k|    *sh->ds = (struct demux_stream) {
  977|  26.9k|        .in = in,
  978|  26.9k|        .sh = sh,
  979|  26.9k|        .type = sh->type,
  980|  26.9k|        .index = sh->index,
  981|  26.9k|        .global_correct_dts = true,
  982|  26.9k|        .global_correct_pos = true,
  983|  26.9k|    };
  984|       |
  985|  26.9k|    struct demux_stream *ds = sh->ds;
  986|       |
  987|  26.9k|    if (!sh->codec->codec)
  ------------------
  |  Branch (987:9): [True: 28, False: 26.8k]
  ------------------
  988|     28|        sh->codec->codec = "";
  989|       |
  990|  26.9k|    if (sh->ff_index < 0)
  ------------------
  |  Branch (990:9): [True: 1.04k, False: 25.8k]
  ------------------
  991|  1.04k|        sh->ff_index = sh->index;
  992|       |
  993|  26.9k|    MP_TARRAY_APPEND(in, in->streams, in->num_streams, sh);
  ------------------
  |  |  105|  26.9k|    do {                                            \
  |  |  106|  26.9k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  26.9k|    do {                                            \
  |  |  |  |   97|  26.9k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  26.9k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  26.9k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  26.9k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 20.2k, False: 6.64k]
  |  |  |  |  ------------------
  |  |  |  |   99|  26.9k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  20.2k|    do {                                                        \
  |  |  |  |  |  |   89|  20.2k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  20.2k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  20.2k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  20.2k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  20.2k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  20.2k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  20.2k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  26.9k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  26.9k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  26.9k|        (idxvar)++;                                 \
  |  |  109|  26.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  994|  26.9k|    mp_assert(in->streams[sh->index] == sh);
  ------------------
  |  |   41|  26.9k|#define mp_assert assert
  ------------------
  995|       |
  996|  26.9k|    if (in->current_range) {
  ------------------
  |  Branch (996:9): [True: 0, False: 26.9k]
  ------------------
  997|      0|        for (int n = 0; n < in->num_ranges; n++)
  ------------------
  |  Branch (997:25): [True: 0, False: 0]
  ------------------
  998|      0|            add_missing_streams(in, in->ranges[n]);
  999|       |
 1000|      0|        sh->ds->queue = in->current_range->streams[sh->ds->index];
 1001|      0|    }
 1002|       |
 1003|  26.9k|    update_stream_selection_state(in, sh->ds);
 1004|       |
 1005|  26.9k|    switch (ds->type) {
  ------------------
  |  Branch (1005:13): [True: 394, False: 26.5k]
  ------------------
 1006|  16.8k|    case STREAM_AUDIO:
  ------------------
  |  Branch (1006:5): [True: 16.8k, False: 10.0k]
  ------------------
 1007|  16.8k|        ds->back_preroll = in->d_user->opts->audio_back_preroll;
 1008|  16.8k|        if (ds->back_preroll < 0) { // auto
  ------------------
  |  Branch (1008:13): [True: 16.8k, False: 0]
  ------------------
 1009|  16.8k|            ds->back_preroll = mp_codec_is_lossless(sh->codec->codec) ? 0 : 1;
  ------------------
  |  Branch (1009:32): [True: 15.9k, False: 899]
  ------------------
 1010|  16.8k|            if (sh->codec->codec && (strcmp(sh->codec->codec, "opus") == 0 ||
  ------------------
  |  Branch (1010:17): [True: 16.8k, False: 0]
  |  Branch (1010:38): [True: 0, False: 16.8k]
  ------------------
 1011|  16.8k|                                     strcmp(sh->codec->codec, "vorbis") == 0 ||
  ------------------
  |  Branch (1011:38): [True: 0, False: 16.8k]
  ------------------
 1012|  16.8k|                                     strcmp(sh->codec->codec, "mp3") == 0))
  ------------------
  |  Branch (1012:38): [True: 5, False: 16.8k]
  ------------------
 1013|      5|                ds->back_preroll = 2;
 1014|  16.8k|        }
 1015|  16.8k|        break;
 1016|  9.69k|    case STREAM_VIDEO:
  ------------------
  |  Branch (1016:5): [True: 9.69k, False: 17.2k]
  ------------------
 1017|  9.69k|        ds->back_preroll = in->d_user->opts->video_back_preroll;
 1018|  9.69k|        if (ds->back_preroll < 0)
  ------------------
  |  Branch (1018:13): [True: 9.69k, False: 0]
  ------------------
 1019|  9.69k|            ds->back_preroll = 0; // auto
 1020|  9.69k|        break;
 1021|  26.9k|    }
 1022|       |
 1023|  26.9k|    if (!ds->sh->attached_picture) {
  ------------------
  |  Branch (1023:9): [True: 26.9k, False: 0]
  ------------------
 1024|       |        // Typically this is used for webradio, so any stream will do.
 1025|  26.9k|        if (!in->metadata_stream)
  ------------------
  |  Branch (1025:13): [True: 20.2k, False: 6.64k]
  ------------------
 1026|  20.2k|            in->metadata_stream = sh;
 1027|  26.9k|    }
 1028|       |
 1029|  26.9k|    in->events |= DEMUX_EVENT_STREAMS;
 1030|  26.9k|    if (in->wakeup_cb)
  ------------------
  |  Branch (1030:9): [True: 0, False: 26.9k]
  ------------------
 1031|      0|        in->wakeup_cb(in->wakeup_cb_ctx);
 1032|  26.9k|}
demux.c:add_missing_streams:
  930|  21.5k|{
  931|  48.4k|    for (int n = range->num_streams; n < in->num_streams; n++) {
  ------------------
  |  Branch (931:38): [True: 26.9k, False: 21.5k]
  ------------------
  932|  26.9k|        struct demux_stream *ds = in->streams[n]->ds;
  933|       |
  934|  26.9k|        struct demux_queue *queue = talloc_ptrtype(NULL, queue);
  ------------------
  |  |   34|  26.9k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  26.9k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  26.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  935|  26.9k|        *queue = (struct demux_queue){
  936|  26.9k|            .ds = ds,
  937|  26.9k|            .range = range,
  938|  26.9k|        };
  939|  26.9k|        clear_queue(queue);
  940|  26.9k|        MP_TARRAY_APPEND(range, range->streams, range->num_streams, queue);
  ------------------
  |  |  105|  26.9k|    do {                                            \
  |  |  106|  26.9k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  26.9k|    do {                                            \
  |  |  |  |   97|  26.9k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  26.9k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  26.9k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  26.9k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 20.2k, False: 6.64k]
  |  |  |  |  ------------------
  |  |  |  |   99|  26.9k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  20.2k|    do {                                                        \
  |  |  |  |  |  |   89|  20.2k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  20.2k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  20.2k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  20.2k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  20.2k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  20.2k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  20.2k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  26.9k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  26.9k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  26.9k|        (idxvar)++;                                 \
  |  |  109|  26.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  941|  26.9k|        mp_assert(range->streams[ds->index] == queue);
  ------------------
  |  |   41|  26.9k|#define mp_assert assert
  ------------------
  942|  26.9k|    }
  943|  21.5k|}
demux.c:clear_queue:
  724|   238k|{
  725|   238k|    struct demux_stream *ds = queue->ds;
  726|   238k|    struct demux_internal *in = ds->in;
  727|       |
  728|   238k|    if (queue->head)
  ------------------
  |  Branch (728:9): [True: 9, False: 238k]
  ------------------
  729|      9|        in->total_bytes -= queue->tail_cum_pos - queue->head->cum_pos;
  730|       |
  731|   238k|    free_index(queue);
  732|       |
  733|   238k|    demux_packet_pool_prepend(in->packet_pool, queue->head, queue->tail);
  734|   238k|    queue->head = queue->tail = NULL;
  735|   238k|    queue->keyframe_first = NULL;
  736|   238k|    queue->keyframe_latest = NULL;
  737|   238k|    queue->seek_start = queue->seek_end = queue->last_pruned = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   238k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  738|       |
  739|   238k|    queue->correct_dts = queue->correct_pos = true;
  740|   238k|    queue->last_pos = -1;
  741|   238k|    queue->last_ts = queue->last_dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   238k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  742|   238k|    queue->last_pos_fixup = -1;
  743|       |
  744|   238k|    queue->is_eof = false;
  745|   238k|    queue->is_bof = false;
  746|   238k|}
demux.c:free_index:
  712|   238k|{
  713|   238k|    struct demux_stream *ds = queue->ds;
  714|   238k|    struct demux_internal *in = ds->in;
  715|       |
  716|   238k|    in->total_bytes -= queue->index_size * sizeof(queue->index[0]);
  717|   238k|    queue->index_size = 0;
  718|   238k|    queue->index0 = 0;
  719|   238k|    queue->num_index = 0;
  720|   238k|    TA_FREEP(&queue->index);
  ------------------
  |  |   81|   238k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|   238k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  721|   238k|}
demux.c:demux_shutdown:
 1070|   215k|{
 1071|   215k|    struct demuxer *demuxer = in->d_user;
 1072|       |
 1073|   215k|    if (in->recorder) {
  ------------------
  |  Branch (1073:9): [True: 0, False: 215k]
  ------------------
 1074|      0|        mp_recorder_destroy(in->recorder);
 1075|      0|        in->recorder = NULL;
 1076|      0|    }
 1077|       |
 1078|   215k|    dumper_close(in);
 1079|       |
 1080|   215k|    if (demuxer->desc->close)
  ------------------
  |  Branch (1080:9): [True: 79.2k, False: 136k]
  ------------------
 1081|  79.2k|        demuxer->desc->close(in->d_thread);
 1082|   215k|    demuxer->priv = NULL;
 1083|   215k|    in->d_thread->priv = NULL;
 1084|       |
 1085|   215k|    demux_flush(demuxer);
 1086|   215k|    mp_assert(in->total_bytes == 0);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
 1087|       |
 1088|   215k|    in->current_range = NULL;
 1089|   215k|    free_empty_cached_ranges(in);
 1090|       |
 1091|   215k|    talloc_free(in->cache);
  ------------------
  |  |   47|   215k|#define talloc_free                     ta_free
  ------------------
 1092|   215k|    in->cache = NULL;
 1093|       |
 1094|   215k|    if (in->owns_stream)
  ------------------
  |  Branch (1094:9): [True: 215k, False: 0]
  ------------------
 1095|   215k|        free_stream(demuxer->stream);
 1096|   215k|    demuxer->stream = NULL;
 1097|   215k|}
demux.c:demux_dealloc:
 1100|   215k|{
 1101|   242k|    for (int n = 0; n < in->num_streams; n++)
  ------------------
  |  Branch (1101:21): [True: 26.9k, False: 215k]
  ------------------
 1102|  26.9k|        talloc_free(in->streams[n]);
  ------------------
  |  |   47|  26.9k|#define talloc_free                     ta_free
  ------------------
 1103|   215k|    mp_mutex_destroy(&in->lock);
  ------------------
  |  |  130|   215k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
 1104|   215k|    mp_cond_destroy(&in->wakeup);
 1105|   215k|    talloc_free(in->d_user);
  ------------------
  |  |   47|   215k|#define talloc_free                     ta_free
  ------------------
 1106|   215k|}
demux.c:add_packet_locked:
 1992|  1.42M|{
 1993|  1.42M|    struct demux_stream *ds = stream ? stream->ds : NULL;
  ------------------
  |  Branch (1993:31): [True: 1.42M, False: 0]
  ------------------
 1994|  1.42M|    mp_assert(ds && ds->in);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
 1995|  1.42M|    if (!dp->len || demux_cancel_test(ds->in->d_thread)) {
  ------------------
  |  Branch (1995:9): [True: 0, False: 1.42M]
  |  Branch (1995:21): [True: 0, False: 1.42M]
  ------------------
 1996|      0|        talloc_free(dp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1997|      0|        return;
 1998|      0|    }
 1999|       |
 2000|  1.42M|    mp_assert(dp->stream == stream->index);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
 2001|  1.42M|    mp_assert(!dp->next);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
 2002|       |
 2003|  1.42M|    struct demux_internal *in = ds->in;
 2004|       |
 2005|  1.42M|    in->after_seek = false;
 2006|  1.42M|    in->after_seek_to_start = false;
 2007|       |
 2008|  1.42M|    double ts = dp->dts == MP_NOPTS_VALUE ? dp->pts : dp->dts;
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2008:17): [True: 14.4k, False: 1.40M]
  ------------------
 2009|  1.42M|    if (dp->segmented)
  ------------------
  |  Branch (2009:9): [True: 6.35k, False: 1.41M]
  ------------------
 2010|  6.35k|        ts = MP_PTS_MIN(ts, dp->end);
  ------------------
  |  |   63|  6.35k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|  12.7k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 6.35k]
  |  |  |  |  |  Branch (44:23): [True: 4.12k, False: 2.22k]
  |  |  |  |  |  Branch (44:29): [True: 0, False: 6.35k]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 4.12k, False: 2.22k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2011|       |
 2012|  1.42M|    if (ts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2012:9): [True: 1.41M, False: 10.1k]
  ------------------
 2013|  1.41M|        in->demux_ts = ts;
 2014|       |
 2015|  1.42M|    struct demux_queue *queue = ds->queue;
 2016|       |
 2017|  1.42M|    bool drop = !ds->selected || in->seeking || ds->sh->attached_picture;
  ------------------
  |  Branch (2017:17): [True: 0, False: 1.42M]
  |  Branch (2017:34): [True: 0, False: 1.42M]
  |  Branch (2017:49): [True: 0, False: 1.42M]
  ------------------
 2018|       |
 2019|  1.42M|    if (!drop) {
  ------------------
  |  Branch (2019:9): [True: 1.42M, False: 0]
  ------------------
 2020|       |        // If libavformat splits packets, some packets will have pos unset, so
 2021|       |        // make up one based on the first packet => makes refresh seeks work.
 2022|  1.42M|        if ((dp->pos < 0 || dp->pos == queue->last_pos_fixup) &&
  ------------------
  |  Branch (2022:14): [True: 101k, False: 1.32M]
  |  Branch (2022:29): [True: 2.84k, False: 1.31M]
  ------------------
 2023|  1.42M|            !dp->keyframe && queue->last_pos_fixup >= 0)
  ------------------
  |  Branch (2023:13): [True: 0, False: 104k]
  |  Branch (2023:30): [True: 0, False: 0]
  ------------------
 2024|      0|            dp->pos = queue->last_pos_fixup + 1;
 2025|  1.42M|        queue->last_pos_fixup = dp->pos;
 2026|  1.42M|    }
 2027|       |
 2028|  1.42M|    if (!drop && ds->refreshing) {
  ------------------
  |  Branch (2028:9): [True: 1.42M, False: 0]
  |  Branch (2028:18): [True: 0, False: 1.42M]
  ------------------
 2029|       |        // Resume reading once the old position was reached (i.e. we start
 2030|       |        // returning packets where we left off before the refresh).
 2031|       |        // If it's the same position, drop, but continue normally next time.
 2032|      0|        if (queue->correct_dts) {
  ------------------
  |  Branch (2032:13): [True: 0, False: 0]
  ------------------
 2033|      0|            ds->refreshing = dp->dts < queue->last_dts;
 2034|      0|        } else if (queue->correct_pos) {
  ------------------
  |  Branch (2034:20): [True: 0, False: 0]
  ------------------
 2035|      0|            ds->refreshing = dp->pos < queue->last_pos;
 2036|      0|        } else {
 2037|      0|            ds->refreshing = false; // should not happen
 2038|      0|            MP_WARN(in, "stream %d: demux refreshing failed\n", ds->index);
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2039|      0|        }
 2040|      0|        drop = true;
 2041|      0|    }
 2042|       |
 2043|  1.42M|    if (drop) {
  ------------------
  |  Branch (2043:9): [True: 0, False: 1.42M]
  ------------------
 2044|      0|        demux_packet_pool_push(in->packet_pool, dp);
 2045|      0|        return;
 2046|      0|    }
 2047|       |
 2048|  1.42M|    record_packet(in, dp);
 2049|       |
 2050|  1.42M|    if (in->cache && in->d_user->opts->disk_cache && !dp->is_wrapped_avframe) {
  ------------------
  |  Branch (2050:9): [True: 0, False: 1.42M]
  |  Branch (2050:22): [True: 0, False: 0]
  |  Branch (2050:54): [True: 0, False: 0]
  ------------------
 2051|      0|        int64_t pos = demux_cache_write(in->cache, dp);
 2052|      0|        if (pos >= 0) {
  ------------------
  |  Branch (2052:13): [True: 0, False: 0]
  ------------------
 2053|      0|            demux_packet_unref_contents(dp);
 2054|      0|            dp->is_cached = true;
 2055|      0|            dp->cached_data.pos = pos;
 2056|      0|        }
 2057|      0|    }
 2058|       |
 2059|  1.42M|    queue->correct_pos &= dp->pos >= 0 && dp->pos > queue->last_pos;
  ------------------
  |  Branch (2059:27): [True: 1.32M, False: 101k]
  |  Branch (2059:43): [True: 1.31M, False: 2.84k]
  ------------------
 2060|  1.42M|    queue->correct_dts &= dp->dts != MP_NOPTS_VALUE && dp->dts > queue->last_dts;
  ------------------
  |  |   38|  2.84M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2060:27): [True: 1.40M, False: 14.4k]
  |  Branch (2060:56): [True: 1.35M, False: 48.7k]
  ------------------
 2061|  1.42M|    queue->last_pos = dp->pos;
 2062|  1.42M|    queue->last_dts = dp->dts;
 2063|  1.42M|    ds->global_correct_pos &= queue->correct_pos;
 2064|  1.42M|    ds->global_correct_dts &= queue->correct_dts;
 2065|       |
 2066|       |    // (keep in mind that even if the reader went out of data, the queue is not
 2067|       |    // necessarily empty due to the backbuffer)
 2068|  1.42M|    if (!ds->reader_head && (!ds->skip_to_keyframe || dp->keyframe)) {
  ------------------
  |  Branch (2068:9): [True: 18.6k, False: 1.40M]
  |  Branch (2068:30): [True: 18.6k, False: 0]
  |  Branch (2068:55): [True: 0, False: 0]
  ------------------
 2069|  18.6k|        ds->reader_head = dp;
 2070|  18.6k|        ds->skip_to_keyframe = false;
 2071|  18.6k|    }
 2072|       |
 2073|  1.42M|    size_t bytes = demux_packet_estimate_total_size(dp);
 2074|  1.42M|    in->total_bytes += bytes;
 2075|  1.42M|    dp->cum_pos = queue->tail_cum_pos;
 2076|  1.42M|    queue->tail_cum_pos += bytes;
 2077|       |
 2078|  1.42M|    if (queue->tail) {
  ------------------
  |  Branch (2078:9): [True: 1.40M, False: 18.6k]
  ------------------
 2079|       |        // next packet in stream
 2080|  1.40M|        queue->tail->next = dp;
 2081|  1.40M|        queue->tail = dp;
 2082|  1.40M|    } else {
 2083|       |        // first packet in stream
 2084|  18.6k|        queue->head = queue->tail = dp;
 2085|  18.6k|    }
 2086|       |
 2087|  1.42M|    if (!ds->ignore_eof) {
  ------------------
  |  Branch (2087:9): [True: 1.42M, False: 0]
  ------------------
 2088|       |        // obviously not true anymore
 2089|  1.42M|        ds->eof = false;
 2090|  1.42M|        in->eof = false;
 2091|  1.42M|    }
 2092|       |
 2093|       |    // For video, PTS determination is not trivial, but for other media types
 2094|       |    // distinguishing PTS and DTS is not useful.
 2095|  1.42M|    if (stream->type != STREAM_VIDEO && dp->pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.13M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2095:9): [True: 1.13M, False: 283k]
  |  Branch (2095:41): [True: 5.54k, False: 1.13M]
  ------------------
 2096|  5.54k|        dp->pts = dp->dts;
 2097|       |
 2098|  1.42M|    if (ts != MP_NOPTS_VALUE && (ts > queue->last_ts || ts + 10 < queue->last_ts))
  ------------------
  |  |   38|  2.84M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2098:9): [True: 1.41M, False: 10.1k]
  |  Branch (2098:34): [True: 1.36M, False: 48.7k]
  |  Branch (2098:57): [True: 0, False: 48.7k]
  ------------------
 2099|  1.36M|        queue->last_ts = ts;
 2100|  1.42M|    if (ds->base_ts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2100:9): [True: 14.3k, False: 1.40M]
  ------------------
 2101|  14.3k|        ds->base_ts = queue->last_ts;
 2102|       |
 2103|  1.42M|    const char *num_pkts = queue->head == queue->tail ? "1" : ">1";
  ------------------
  |  Branch (2103:28): [True: 18.6k, False: 1.40M]
  ------------------
 2104|  1.42M|    uint64_t fw_bytes = get_forward_buffered_bytes(ds);
 2105|  1.42M|    MP_TRACE(in, "append packet to %s: size=%zu pts=%f dts=%f pos=%"PRIi64" "
  ------------------
  |  |   90|  1.42M|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.42M|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2106|  1.42M|             "[num=%s size=%zd]\n", stream_type_name(stream->type),
 2107|  1.42M|             dp->len, dp->pts, dp->dts, dp->pos, num_pkts, (size_t)fw_bytes);
 2108|       |
 2109|  1.42M|    adjust_seek_range_on_packet(ds, dp);
 2110|       |
 2111|       |    // May need to reduce backward cache.
 2112|  1.42M|    prune_old_packets(in);
 2113|       |
 2114|       |    // Possibly update duration based on highest TS demuxed (but ignore subs).
 2115|  1.42M|    if (stream->type != STREAM_SUB) {
  ------------------
  |  Branch (2115:9): [True: 1.42M, False: 0]
  ------------------
 2116|  1.42M|        if (dp->segmented)
  ------------------
  |  Branch (2116:13): [True: 6.35k, False: 1.41M]
  ------------------
 2117|  6.35k|            ts = MP_PTS_MIN(ts, dp->end);
  ------------------
  |  |   63|  6.35k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|  12.7k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 6.35k]
  |  |  |  |  |  Branch (44:23): [True: 0, False: 6.35k]
  |  |  |  |  |  Branch (44:29): [True: 0, False: 6.35k]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 0, False: 6.35k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2118|  1.42M|        if (ts > in->highest_av_pts) {
  ------------------
  |  Branch (2118:13): [True: 1.36M, False: 60.1k]
  ------------------
 2119|  1.36M|            in->highest_av_pts = ts;
 2120|  1.36M|            double duration = in->highest_av_pts - in->d_thread->start_time;
 2121|  1.36M|            if (duration > in->d_thread->duration) {
  ------------------
  |  Branch (2121:17): [True: 211k, False: 1.15M]
  ------------------
 2122|   211k|                in->d_thread->duration = duration;
 2123|       |                // (Don't wakeup user thread, would be too noisy.)
 2124|   211k|                in->events |= DEMUX_EVENT_DURATION;
 2125|   211k|                in->duration = duration;
 2126|   211k|            }
 2127|  1.36M|        }
 2128|  1.42M|    }
 2129|       |
 2130|       |    // Don't process the packet further if it's skipped by the previous seek
 2131|       |    // (see reader_head check/assignment above).
 2132|  1.42M|    if (!ds->reader_head)
  ------------------
  |  Branch (2132:9): [True: 0, False: 1.42M]
  ------------------
 2133|      0|        return;
 2134|       |
 2135|  1.42M|    back_demux_see_packets(ds);
 2136|       |
 2137|  1.42M|    wakeup_ds(ds);
 2138|  1.42M|}
demux.c:record_packet:
 1961|  1.42M|{
 1962|       |    // (should preferably be outside of the lock)
 1963|  1.42M|    if (in->enable_recording && !in->recorder &&
  ------------------
  |  Branch (1963:9): [True: 0, False: 1.42M]
  |  Branch (1963:33): [True: 0, False: 0]
  ------------------
 1964|  1.42M|        in->d_user->opts->record_file && in->d_user->opts->record_file[0])
  ------------------
  |  Branch (1964:9): [True: 0, False: 0]
  |  Branch (1964:42): [True: 0, False: 0]
  ------------------
 1965|      0|    {
 1966|       |        // Later failures shouldn't make it retry and overwrite the previously
 1967|       |        // recorded file.
 1968|      0|        in->enable_recording = false;
 1969|       |
 1970|      0|        in->recorder = recorder_create(in, in->d_user->opts->record_file);
 1971|      0|        if (!in->recorder)
  ------------------
  |  Branch (1971:13): [True: 0, False: 0]
  ------------------
 1972|      0|            MP_ERR(in, "Disabling recording.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1973|      0|    }
 1974|       |
 1975|  1.42M|    if (in->recorder) {
  ------------------
  |  Branch (1975:9): [True: 0, False: 1.42M]
  ------------------
 1976|      0|        struct mp_recorder_sink *sink =
 1977|      0|            mp_recorder_get_sink(in->recorder, in->streams[dp->stream]);
 1978|      0|        if (sink) {
  ------------------
  |  Branch (1978:13): [True: 0, False: 0]
  ------------------
 1979|      0|            mp_recorder_feed_packet(sink, dp);
 1980|      0|        } else {
 1981|      0|            MP_ERR(in, "New stream appeared; stopping recording.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1982|      0|            mp_recorder_destroy(in->recorder);
 1983|      0|            in->recorder = NULL;
 1984|      0|        }
 1985|      0|    }
 1986|       |
 1987|  1.42M|    if (in->dumper_status == CONTROL_OK)
  ------------------
  |  |   68|  1.42M|#define CONTROL_OK 1
  ------------------
  |  Branch (1987:9): [True: 0, False: 1.42M]
  ------------------
 1988|      0|        write_dump_packet(in, dp);
 1989|  1.42M|}
demux.c:adjust_seek_range_on_packet:
 1867|  1.50M|{
 1868|  1.50M|    struct demux_queue *queue = ds->queue;
 1869|       |
 1870|  1.50M|    if (!ds->in->seekable_cache)
  ------------------
  |  Branch (1870:9): [True: 1.50M, False: 0]
  ------------------
 1871|  1.50M|        return;
 1872|       |
 1873|      0|    bool new_eof = !dp;
 1874|      0|    bool update_ranges = queue->is_eof != new_eof;
 1875|      0|    queue->is_eof = new_eof;
 1876|       |
 1877|      0|    if (!dp || dp->keyframe) {
  ------------------
  |  Branch (1877:9): [True: 0, False: 0]
  |  Branch (1877:16): [True: 0, False: 0]
  ------------------
 1878|      0|        if (queue->keyframe_latest) {
  ------------------
  |  Branch (1878:13): [True: 0, False: 0]
  ------------------
 1879|      0|            double kf_min, kf_max;
 1880|      0|            compute_keyframe_times(queue->keyframe_latest, &kf_min, &kf_max);
 1881|       |
 1882|      0|            if (kf_min != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1882:17): [True: 0, False: 0]
  ------------------
 1883|      0|                add_index_entry(queue, queue->keyframe_latest, kf_min);
 1884|       |
 1885|       |                // Initialize the queue's start if it's unset.
 1886|      0|                if (queue->seek_start == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1886:21): [True: 0, False: 0]
  ------------------
 1887|      0|                    update_ranges = true;
 1888|      0|                    queue->seek_start = kf_min + ds->sh->seek_preroll;
 1889|      0|                }
 1890|      0|            }
 1891|       |
 1892|      0|            if (kf_max != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1892:17): [True: 0, False: 0]
  ------------------
 1893|      0|                (queue->seek_end == MP_NOPTS_VALUE || kf_max > queue->seek_end))
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1893:18): [True: 0, False: 0]
  |  Branch (1893:55): [True: 0, False: 0]
  ------------------
 1894|      0|            {
 1895|       |                // If the queue was past the current range's end even before
 1896|       |                // this update, it means _other_ streams are not there yet,
 1897|       |                // and the seek range doesn't need to be updated. This means
 1898|       |                // if the _old_ queue->seek_end was already after the range end,
 1899|       |                // then the new seek_end won't extend the range either.
 1900|      0|                if (queue->range->seek_end == MP_NOPTS_VALUE ||
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1900:21): [True: 0, False: 0]
  ------------------
 1901|      0|                    queue->seek_end <= queue->range->seek_end)
  ------------------
  |  Branch (1901:21): [True: 0, False: 0]
  ------------------
 1902|      0|                {
 1903|      0|                    update_ranges = true;
 1904|      0|                }
 1905|       |
 1906|      0|                queue->seek_end = kf_max;
 1907|      0|            }
 1908|      0|        }
 1909|       |
 1910|      0|        queue->keyframe_latest = dp;
 1911|      0|    }
 1912|       |
 1913|       |    // Adding a sparse packet never changes the seek range.
 1914|      0|    if (update_ranges && ds->eager) {
  ------------------
  |  Branch (1914:9): [True: 0, False: 0]
  |  Branch (1914:26): [True: 0, False: 0]
  ------------------
 1915|      0|        update_seek_ranges(queue->range);
 1916|      0|        attempt_range_joining(ds->in);
 1917|      0|    }
 1918|      0|}
demux.c:update_seek_ranges:
  595|   280k|{
  596|   280k|    range->seek_start = range->seek_end = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   280k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  597|   280k|    range->is_bof = true;
  598|   280k|    range->is_eof = true;
  599|       |
  600|   280k|    double min_start_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   280k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  601|   280k|    double max_end_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   280k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  602|       |
  603|   421k|    for (int n = 0; n < range->num_streams; n++) {
  ------------------
  |  Branch (603:21): [True: 322k, False: 98.9k]
  ------------------
  604|   322k|        struct demux_queue *queue = range->streams[n];
  605|       |
  606|   322k|        if (queue->ds->selected && queue->ds->eager) {
  ------------------
  |  Branch (606:13): [True: 181k, False: 141k]
  |  Branch (606:36): [True: 181k, False: 0]
  ------------------
  607|   181k|            if (queue->is_bof) {
  ------------------
  |  Branch (607:17): [True: 12.4k, False: 168k]
  ------------------
  608|  12.4k|                min_start_pts = MP_PTS_MIN(min_start_pts, queue->seek_start);
  ------------------
  |  |   63|  12.4k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|  24.8k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 12.4k]
  |  |  |  |  |  Branch (44:23): [True: 12.4k, False: 0]
  |  |  |  |  |  Branch (44:29): [True: 12.4k, False: 0]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 12.4k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  609|   168k|            } else {
  610|   168k|                range->seek_start =
  611|   168k|                    MP_PTS_MAX(range->seek_start, queue->seek_start);
  ------------------
  |  |   64|   168k|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|   337k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 168k]
  |  |  |  |  |  Branch (43:23): [True: 168k, False: 0]
  |  |  |  |  |  Branch (43:29): [True: 168k, False: 0]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 168k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  612|   168k|            }
  613|       |
  614|   181k|            if (queue->is_eof) {
  ------------------
  |  Branch (614:17): [True: 0, False: 181k]
  ------------------
  615|      0|                max_end_pts = MP_PTS_MAX(max_end_pts, queue->seek_end);
  ------------------
  |  |   64|      0|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:23): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:29): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  616|   181k|            } else {
  617|   181k|                range->seek_end = MP_PTS_MIN(range->seek_end, queue->seek_end);
  ------------------
  |  |   63|   181k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|   362k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 181k]
  |  |  |  |  |  Branch (44:23): [True: 181k, False: 0]
  |  |  |  |  |  Branch (44:29): [True: 181k, False: 0]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 181k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  618|   181k|            }
  619|       |
  620|   181k|            range->is_eof &= queue->is_eof;
  621|   181k|            range->is_bof &= queue->is_bof;
  622|       |
  623|   181k|            bool empty = queue->is_eof && !queue->head;
  ------------------
  |  Branch (623:26): [True: 0, False: 181k]
  |  Branch (623:43): [True: 0, False: 0]
  ------------------
  624|   181k|            if (queue->seek_start >= queue->seek_end && !empty &&
  ------------------
  |  Branch (624:17): [True: 181k, False: 0]
  |  Branch (624:57): [True: 181k, False: 0]
  ------------------
  625|   181k|                !(queue->seek_start == queue->seek_end &&
  ------------------
  |  Branch (625:19): [True: 181k, False: 0]
  ------------------
  626|   181k|                  queue->seek_start != MP_NOPTS_VALUE))
  ------------------
  |  |   38|   181k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (626:19): [True: 0, False: 181k]
  ------------------
  627|   181k|                goto broken;
  628|   181k|        }
  629|   322k|    }
  630|       |
  631|  98.9k|    if (range->is_eof)
  ------------------
  |  Branch (631:9): [True: 98.9k, False: 0]
  ------------------
  632|  98.9k|        range->seek_end = max_end_pts;
  633|  98.9k|    if (range->is_bof)
  ------------------
  |  Branch (633:9): [True: 98.9k, False: 0]
  ------------------
  634|  98.9k|        range->seek_start = min_start_pts;
  635|       |
  636|       |    // Sparse (subtitle) stream behavior is not very clearly defined, but
  637|       |    // usually we don't want it to restrict the range of other streams. For
  638|       |    // example, if there are subtitle packets at position 5 and 10 seconds, and
  639|       |    // the demuxer demuxed the other streams until position 7 seconds, the seek
  640|       |    // range end position is 7.
  641|       |    // Assume that reading a non-sparse (audio/video) packet gets all sparse
  642|       |    // packets that are needed before that non-sparse packet.
  643|       |    // This is incorrect in any of these cases:
  644|       |    //  - sparse streams only (it's unknown how to determine an accurate range)
  645|       |    //  - if sparse streams have non-keyframe packets (we set queue->last_pruned
  646|       |    //    to the start of the pruned keyframe range - we'd need the end or so)
  647|       |    // We also assume that ds->eager equals to a stream not being sparse
  648|       |    // (usually true, except if only sparse streams are selected).
  649|       |    // We also rely on the fact that the demuxer position will always be ahead
  650|       |    // of the seek_end for audio/video, because they need to prefetch at least
  651|       |    // 1 packet to detect the end of a keyframe range. This means that there's
  652|       |    // a relatively high guarantee to have all sparse (subtitle) packets within
  653|       |    // the seekable range.
  654|       |    // As a consequence, the code _never_ checks queue->seek_end for a sparse
  655|       |    // queue, as the end of it is implied by the highest PTS of a non-sparse
  656|       |    // stream (i.e. the latest demuxer position).
  657|       |    // On the other hand, if a sparse packet was pruned, and that packet has
  658|       |    // a higher PTS than seek_start for non-sparse queues, that packet is
  659|       |    // missing. So the range's seek_start needs to be adjusted accordingly.
  660|   223k|    for (int n = 0; n < range->num_streams; n++) {
  ------------------
  |  Branch (660:21): [True: 124k, False: 98.9k]
  ------------------
  661|   124k|        struct demux_queue *queue = range->streams[n];
  662|   124k|        if (queue->ds->selected && !queue->ds->eager &&
  ------------------
  |  Branch (662:13): [True: 0, False: 124k]
  |  Branch (662:36): [True: 0, False: 0]
  ------------------
  663|   124k|            queue->last_pruned != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|   124k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (663:13): [True: 0, False: 0]
  ------------------
  664|   124k|            range->seek_start != MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (664:13): [True: 0, False: 0]
  ------------------
  665|      0|        {
  666|       |            // (last_pruned is _exclusive_ to the seekable range, so add a small
  667|       |            // value to exclude it from the valid range.)
  668|      0|            range->seek_start =
  669|      0|                MP_PTS_MAX(range->seek_start, queue->last_pruned + 0.1);
  ------------------
  |  |   64|      0|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:23): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:29): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  670|      0|        }
  671|   124k|    }
  672|       |
  673|  98.9k|    if (range->seek_start >= range->seek_end && !(range->is_bof && range->is_eof))
  ------------------
  |  Branch (673:9): [True: 98.9k, False: 0]
  |  Branch (673:51): [True: 98.9k, False: 0]
  |  Branch (673:68): [True: 98.9k, False: 0]
  ------------------
  674|      0|        goto broken;
  675|       |
  676|  98.9k|    prune_metadata(range);
  677|  98.9k|    return;
  678|       |
  679|   181k|broken:
  680|   181k|    range->seek_start = range->seek_end = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   181k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  681|   181k|    prune_metadata(range);
  682|   181k|}
demux.c:prune_metadata:
  569|   280k|{
  570|   280k|    int first_needed = 0;
  571|       |
  572|   280k|    if (range->seek_start == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   280k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (572:9): [True: 280k, False: 0]
  ------------------
  573|   280k|        first_needed = range->num_metadata;
  574|   280k|    } else {
  575|      0|        for (int n = 0; n < range->num_metadata ; n++) {
  ------------------
  |  Branch (575:25): [True: 0, False: 0]
  ------------------
  576|      0|            if (range->metadata[n]->pts > range->seek_start)
  ------------------
  |  Branch (576:17): [True: 0, False: 0]
  ------------------
  577|      0|                break;
  578|      0|            first_needed = n;
  579|      0|        }
  580|      0|    }
  581|       |
  582|       |    // Always preserve the last entry.
  583|   280k|    first_needed = MPMIN(first_needed, range->num_metadata - 1);
  ------------------
  |  |   44|   280k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 280k, False: 0]
  |  |  ------------------
  ------------------
  584|       |
  585|       |    // (Could make this significantly more efficient for large first_needed,
  586|       |    // however that might be very rare and even then it might not matter.)
  587|   280k|    for (int n = 0; n < first_needed; n++) {
  ------------------
  |  Branch (587:21): [True: 0, False: 280k]
  ------------------
  588|      0|        talloc_free(range->metadata[0]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  589|      0|        MP_TARRAY_REMOVE_AT(range->metadata, range->num_metadata, 0);
  ------------------
  |  |  143|      0|    do {                                            \
  |  |  144|      0|        size_t at_ = (at);                          \
  |  |  145|      0|        assert(at_ <= (idxvar));                    \
  |  |  146|      0|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|      0|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|      0|        (idxvar)--;                                 \
  |  |  149|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  590|      0|    }
  591|   280k|}
demux.c:remove_head_packet:
  686|  1.42M|{
  687|  1.42M|    struct demux_packet *dp = queue->head;
  688|       |
  689|  1.42M|    mp_assert(queue->ds->reader_head != dp);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
  690|  1.42M|    if (queue->keyframe_first == dp)
  ------------------
  |  Branch (690:9): [True: 1.23M, False: 184k]
  ------------------
  691|  1.23M|        queue->keyframe_first = NULL;
  692|  1.42M|    if (queue->keyframe_latest == dp)
  ------------------
  |  Branch (692:9): [True: 0, False: 1.42M]
  ------------------
  693|      0|        queue->keyframe_latest = NULL;
  694|  1.42M|    queue->is_bof = false;
  695|       |
  696|  1.42M|    uint64_t end_pos = dp->next ? dp->next->cum_pos : queue->tail_cum_pos;
  ------------------
  |  Branch (696:24): [True: 1.40M, False: 18.6k]
  ------------------
  697|  1.42M|    queue->ds->in->total_bytes -= end_pos - dp->cum_pos;
  698|       |
  699|  1.42M|    if (queue->num_index && queue->index[queue->index0].pkt == dp) {
  ------------------
  |  Branch (699:9): [True: 0, False: 1.42M]
  |  Branch (699:29): [True: 0, False: 0]
  ------------------
  700|      0|        queue->index0 = (queue->index0 + 1) & QUEUE_INDEX_SIZE_MASK(queue);
  ------------------
  |  |  309|      0|#define QUEUE_INDEX_SIZE_MASK(queue) ((queue)->index_size - 1)
  ------------------
  701|      0|        queue->num_index -= 1;
  702|      0|    }
  703|       |
  704|  1.42M|    queue->head = dp->next;
  705|  1.42M|    if (!queue->head)
  ------------------
  |  Branch (705:9): [True: 18.6k, False: 1.40M]
  ------------------
  706|  18.6k|        queue->tail = NULL;
  707|       |
  708|  1.42M|    demux_packet_pool_push(queue->ds->in->packet_pool, dp);
  709|  1.42M|}
demux.c:prune_old_packets:
 2293|  2.86M|{
 2294|  2.86M|    mp_assert(in->current_range == in->ranges[in->num_ranges - 1]);
  ------------------
  |  |   41|  2.86M|#define mp_assert assert
  ------------------
 2295|       |
 2296|       |    // It's not clear what the ideal way to prune old packets is. For now, we
 2297|       |    // prune the oldest packet runs, as long as the total cache amount is too
 2298|       |    // big.
 2299|  4.28M|    while (1) {
  ------------------
  |  Branch (2299:12): [Folded - Ignored]
  ------------------
 2300|  4.28M|        uint64_t fw_bytes = 0;
 2301|  8.61M|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2301:25): [True: 4.32M, False: 4.28M]
  ------------------
 2302|  4.32M|            struct demux_stream *ds = in->streams[n]->ds;
 2303|  4.32M|            fw_bytes += get_forward_buffered_bytes(ds);
 2304|  4.32M|        }
 2305|  4.28M|        uint64_t max_avail = in->max_bytes_bw;
 2306|       |        // Backward cache (if enabled at all) can use unused forward cache.
 2307|       |        // Still leave 1 byte free, so the read_packet logic doesn't get stuck.
 2308|  4.28M|        if (max_avail && in->max_bytes > (fw_bytes + 1) && in->d_user->opts->donate_fw)
  ------------------
  |  Branch (2308:13): [True: 0, False: 4.28M]
  |  Branch (2308:26): [True: 0, False: 0]
  |  Branch (2308:60): [True: 0, False: 0]
  ------------------
 2309|      0|            max_avail += in->max_bytes - (fw_bytes + 1);
 2310|  4.28M|        if (in->total_bytes - fw_bytes <= max_avail)
  ------------------
  |  Branch (2310:13): [True: 2.86M, False: 1.42M]
  ------------------
 2311|  2.86M|            break;
 2312|       |
 2313|       |        // (Start from least recently used range.)
 2314|  1.42M|        struct demux_cached_range *range = in->ranges[0];
 2315|  1.42M|        double earliest_ts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2316|  1.42M|        struct demux_stream *earliest_stream = NULL;
 2317|       |
 2318|  1.43M|        for (int n = 0; n < range->num_streams; n++) {
  ------------------
  |  Branch (2318:25): [True: 1.43M, False: 0]
  ------------------
 2319|  1.43M|            struct demux_queue *queue = range->streams[n];
 2320|  1.43M|            struct demux_stream *ds = queue->ds;
 2321|       |
 2322|  1.43M|            if (queue->head && queue->head != ds->reader_head) {
  ------------------
  |  Branch (2322:17): [True: 1.42M, False: 8.91k]
  |  Branch (2322:32): [True: 1.42M, False: 46]
  ------------------
 2323|  1.42M|                struct demux_packet *dp = queue->head;
 2324|  1.42M|                double ts = queue->seek_start;
 2325|       |                // If the ts is NOPTS, the queue has no retainable packets, so
 2326|       |                // delete them all. This code is not run when there's enough
 2327|       |                // free space, so normally the queue gets the chance to build up.
 2328|  1.42M|                bool prune_always =
 2329|  1.42M|                    !in->seekable_cache || ts == MP_NOPTS_VALUE || !dp->keyframe;
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2329:21): [True: 1.42M, False: 0]
  |  Branch (2329:44): [True: 0, False: 0]
  |  Branch (2329:68): [True: 0, False: 0]
  ------------------
 2330|  1.42M|                if (prune_always || !earliest_stream || ts < earliest_ts) {
  ------------------
  |  Branch (2330:21): [True: 1.42M, False: 0]
  |  Branch (2330:37): [True: 0, False: 0]
  |  Branch (2330:57): [True: 0, False: 0]
  ------------------
 2331|  1.42M|                    earliest_ts = ts;
 2332|  1.42M|                    earliest_stream = ds;
 2333|  1.42M|                    if (prune_always)
  ------------------
  |  Branch (2333:25): [True: 1.42M, False: 0]
  ------------------
 2334|  1.42M|                        break;
 2335|  1.42M|                }
 2336|  1.42M|            }
 2337|  1.43M|        }
 2338|       |
 2339|       |        // In some cases (like when the seek index became huge), there aren't
 2340|       |        // any backwards packets, even if the total cache size is exceeded.
 2341|  1.42M|        if (!earliest_stream)
  ------------------
  |  Branch (2341:13): [True: 0, False: 1.42M]
  ------------------
 2342|      0|            break;
 2343|       |
 2344|  1.42M|        struct demux_stream *ds = earliest_stream;
 2345|  1.42M|        struct demux_queue *queue = range->streams[ds->index];
 2346|       |
 2347|  1.42M|        bool non_kf_prune = queue->head && !queue->head->keyframe;
  ------------------
  |  Branch (2347:29): [True: 1.42M, False: 0]
  |  Branch (2347:44): [True: 171k, False: 1.25M]
  ------------------
 2348|  1.42M|        bool kf_was_pruned = false;
 2349|       |
 2350|  2.84M|        while (queue->head && queue->head != ds->reader_head) {
  ------------------
  |  Branch (2350:16): [True: 2.82M, False: 18.6k]
  |  Branch (2350:31): [True: 1.42M, False: 1.40M]
  ------------------
 2351|  1.42M|            if (queue->head->keyframe) {
  ------------------
  |  Branch (2351:17): [True: 1.25M, False: 171k]
  ------------------
 2352|       |                // If the cache is seekable, only delete until up the next
 2353|       |                // keyframe. This is not always efficient, but ensures we
 2354|       |                // prune all streams fairly.
 2355|       |                // Also, if the first packet was _not_ a keyframe, we want it
 2356|       |                // to remove all preceding non-keyframe packets first, before
 2357|       |                // re-evaluating what to prune next.
 2358|  1.25M|                if ((kf_was_pruned || non_kf_prune) && in->seekable_cache)
  ------------------
  |  Branch (2358:22): [True: 0, False: 1.25M]
  |  Branch (2358:39): [True: 0, False: 1.25M]
  |  Branch (2358:56): [True: 0, False: 0]
  ------------------
 2359|      0|                    break;
 2360|  1.25M|                kf_was_pruned = true;
 2361|  1.25M|            }
 2362|       |
 2363|  1.42M|            remove_head_packet(queue);
 2364|  1.42M|        }
 2365|       |
 2366|       |        // Need to update the seekable time range.
 2367|  1.42M|        if (kf_was_pruned) {
  ------------------
  |  Branch (2367:13): [True: 1.25M, False: 171k]
  ------------------
 2368|  1.25M|            mp_assert(!queue->keyframe_first); // it was just deleted, supposedly
  ------------------
  |  |   41|  1.25M|#define mp_assert assert
  ------------------
 2369|       |
 2370|  1.25M|            queue->keyframe_first = queue->head;
 2371|       |            // (May happen if reader_head stopped pruning the range, and there's
 2372|       |            // no next range.)
 2373|  1.25M|            while (queue->keyframe_first && !queue->keyframe_first->keyframe)
  ------------------
  |  Branch (2373:20): [True: 1.24M, False: 12.4k]
  |  Branch (2373:45): [True: 7.00k, False: 1.23M]
  ------------------
 2374|  7.00k|                queue->keyframe_first = queue->keyframe_first->next;
 2375|       |
 2376|  1.25M|            if (queue->seek_start != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.25M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2376:17): [True: 1.23M, False: 12.4k]
  ------------------
 2377|  1.23M|                queue->last_pruned = queue->seek_start;
 2378|       |
 2379|  1.25M|            double kf_min;
 2380|  1.25M|            compute_keyframe_times(queue->keyframe_first, &kf_min, NULL);
 2381|       |
 2382|  1.25M|            bool update_range = true;
 2383|       |
 2384|  1.25M|            queue->seek_start = kf_min;
 2385|       |
 2386|  1.25M|            if (queue->seek_start != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  1.25M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2386:17): [True: 1.23M, False: 12.4k]
  ------------------
 2387|  1.23M|                queue->seek_start += ds->sh->seek_preroll;
 2388|       |
 2389|       |                // Don't need to update if the new start is still before the
 2390|       |                // range's start (or if the range was undefined anyway).
 2391|  1.23M|                if (range->seek_start == MP_NOPTS_VALUE ||
  ------------------
  |  |   38|  2.47M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2391:21): [True: 1.23M, False: 0]
  ------------------
 2392|  1.23M|                    queue->seek_start <= range->seek_start)
  ------------------
  |  Branch (2392:21): [True: 0, False: 0]
  ------------------
 2393|  1.23M|                {
 2394|  1.23M|                    update_range = false;
 2395|  1.23M|                }
 2396|  1.23M|            }
 2397|       |
 2398|  1.25M|            if (update_range)
  ------------------
  |  Branch (2398:17): [True: 12.4k, False: 1.23M]
  ------------------
 2399|  12.4k|                update_seek_ranges(range);
 2400|  1.25M|        }
 2401|       |
 2402|  1.42M|        if (range != in->current_range && range->seek_start == MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2402:13): [True: 0, False: 1.42M]
  |  Branch (2402:43): [True: 0, False: 0]
  ------------------
 2403|      0|            free_empty_cached_ranges(in);
 2404|  1.42M|    }
 2405|  2.86M|}
demux.c:back_demux_see_packets:
 1565|  1.50M|{
 1566|  1.50M|    struct demux_internal *in = ds->in;
 1567|       |
 1568|  1.50M|    if (!ds->selected || !in->back_demuxing || !ds->eager)
  ------------------
  |  Branch (1568:9): [True: 0, False: 1.50M]
  |  Branch (1568:26): [True: 1.50M, False: 0]
  |  Branch (1568:48): [True: 0, False: 0]
  ------------------
 1569|  1.50M|        return;
 1570|       |
 1571|      0|    mp_assert(!(ds->back_resuming && ds->back_restarting));
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1572|       |
 1573|      0|    if (!ds->global_correct_dts && !ds->global_correct_pos) {
  ------------------
  |  Branch (1573:9): [True: 0, False: 0]
  |  Branch (1573:36): [True: 0, False: 0]
  ------------------
 1574|      0|        MP_ERR(in, "Can't demux backward due to demuxer problems.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1575|      0|        error_on_backward_demuxing(in);
 1576|      0|        return;
 1577|      0|    }
 1578|       |
 1579|      0|    while (ds->back_resuming && ds->reader_head) {
  ------------------
  |  Branch (1579:12): [True: 0, False: 0]
  |  Branch (1579:33): [True: 0, False: 0]
  ------------------
 1580|      0|        struct demux_packet *head = ds->reader_head;
 1581|      0|        if ((ds->global_correct_dts && head->dts == ds->back_resume_dts) ||
  ------------------
  |  Branch (1581:14): [True: 0, False: 0]
  |  Branch (1581:40): [True: 0, False: 0]
  ------------------
 1582|      0|            (ds->global_correct_pos && head->pos == ds->back_resume_pos))
  ------------------
  |  Branch (1582:14): [True: 0, False: 0]
  |  Branch (1582:40): [True: 0, False: 0]
  ------------------
 1583|      0|        {
 1584|      0|            ds->back_resuming = false;
 1585|      0|            ds->need_wakeup = true;
 1586|      0|            wakeup_ds(ds); // probably
 1587|      0|            break;
 1588|      0|        }
 1589|      0|        advance_reader_head(ds);
 1590|      0|    }
 1591|       |
 1592|      0|    if (ds->back_restarting)
  ------------------
  |  Branch (1592:9): [True: 0, False: 0]
  ------------------
 1593|      0|        find_backward_restart_pos(ds);
 1594|      0|}
demux.c:advance_reader_head:
 2581|  1.42M|{
 2582|  1.42M|    struct demux_packet *pkt = ds->reader_head;
 2583|  1.42M|    if (!pkt)
  ------------------
  |  Branch (2583:9): [True: 0, False: 1.42M]
  ------------------
 2584|      0|        return NULL;
 2585|       |
 2586|  1.42M|    ds->reader_head = pkt->next;
 2587|       |
 2588|  1.42M|    ds->last_ret_pos = pkt->pos;
 2589|  1.42M|    ds->last_ret_dts = pkt->dts;
 2590|       |
 2591|  1.42M|    return pkt;
 2592|  1.42M|}
demux.c:ds_clear_reader_state:
  808|   295k|{
  809|   295k|    ds_clear_reader_queue_state(ds);
  810|       |
  811|   295k|    ds->base_ts = ds->last_br_ts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  812|   295k|    ds->last_br_bytes = 0;
  813|   295k|    ds->bitrate = -1;
  814|   295k|    ds->skip_to_keyframe = false;
  815|   295k|    ds->attached_picture_added = false;
  816|   295k|    ds->last_ret_pos = -1;
  817|   295k|    ds->last_ret_dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  818|   295k|    ds->force_read_until = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  819|       |
  820|   295k|    if (clear_back_state) {
  ------------------
  |  Branch (820:9): [True: 295k, False: 0]
  ------------------
  821|   295k|        ds->back_restart_pos = -1;
  822|   295k|        ds->back_restart_dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  823|   295k|        ds->back_restart_eof = false;
  824|   295k|        ds->back_restart_next = ds->in->back_demuxing;
  825|   295k|        ds->back_restarting = ds->in->back_demuxing && ds->eager;
  ------------------
  |  Branch (825:31): [True: 0, False: 295k]
  |  Branch (825:56): [True: 0, False: 0]
  ------------------
  826|   295k|        ds->back_seek_pos = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  827|   295k|        ds->back_resume_pos = -1;
  828|   295k|        ds->back_resume_dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|   295k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  829|   295k|        ds->back_resuming = false;
  830|   295k|        ds->back_range_started = false;
  831|   295k|        ds->back_range_count = 0;
  832|   295k|        ds->back_range_preroll = 0;
  833|   295k|    }
  834|   295k|}
demux.c:ds_clear_reader_queue_state:
  800|   295k|{
  801|   295k|    ds->reader_head = NULL;
  802|   295k|    ds->eof = false;
  803|   295k|    ds->need_wakeup = true;
  804|   295k|}
demux.c:demux_thread:
 2550|  4.11k|{
 2551|  4.11k|    struct demux_internal *in = pctx;
 2552|  4.11k|    mp_thread_set_name("demux");
 2553|  4.11k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  4.11k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2554|       |
 2555|  4.11k|    stats_register_thread_cputime(in->stats, "thread");
 2556|       |
 2557|  2.11M|    while (!in->thread_terminate) {
  ------------------
  |  Branch (2557:12): [True: 2.10M, False: 4.11k]
  ------------------
 2558|  2.10M|        if (thread_work(in))
  ------------------
  |  Branch (2558:13): [True: 1.49M, False: 614k]
  ------------------
 2559|  1.49M|            continue;
 2560|   614k|        mp_cond_signal(&in->wakeup);
 2561|   614k|        mp_cond_timedwait_until(&in->wakeup, &in->lock, in->next_cache_update);
 2562|   614k|    }
 2563|       |
 2564|  4.11k|    if (in->shutdown_async) {
  ------------------
  |  Branch (2564:9): [True: 4.11k, False: 0]
  ------------------
 2565|  4.11k|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  4.11k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2566|  4.11k|        demux_shutdown(in);
 2567|  4.11k|        mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  4.11k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2568|  4.11k|        in->shutdown_async = false;
 2569|  4.11k|        if (in->wakeup_cb)
  ------------------
  |  Branch (2569:13): [True: 4.11k, False: 0]
  ------------------
 2570|  4.11k|            in->wakeup_cb(in->wakeup_cb_ctx);
 2571|  4.11k|    }
 2572|       |
 2573|  4.11k|    stats_unregister_thread(in->stats, "thread");
 2574|       |
 2575|  4.11k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  4.11k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2576|  4.11k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  4.11k|#define MP_THREAD_RETURN() return NULL
  ------------------
 2577|  4.11k|}
demux.c:dequeue_packet:
 2626|  1.76M|{
 2627|  1.76M|    struct demux_internal *in = ds->in;
 2628|       |
 2629|  1.76M|    if (!ds->selected)
  ------------------
  |  Branch (2629:9): [True: 20, False: 1.76M]
  ------------------
 2630|     20|        return -1;
 2631|  1.76M|    if (in->blocked)
  ------------------
  |  Branch (2631:9): [True: 0, False: 1.76M]
  ------------------
 2632|      0|        return 0;
 2633|       |
 2634|  1.76M|    if (ds->sh->attached_picture) {
  ------------------
  |  Branch (2634:9): [True: 0, False: 1.76M]
  ------------------
 2635|      0|        ds->eof = true;
 2636|      0|        if (ds->attached_picture_added)
  ------------------
  |  Branch (2636:13): [True: 0, False: 0]
  ------------------
 2637|      0|            return -1;
 2638|      0|        ds->attached_picture_added = true;
 2639|      0|        struct demux_packet *pkt = demux_copy_packet(in->packet_pool,
 2640|      0|                                                     ds->sh->attached_picture);
 2641|      0|        MP_HANDLE_OOM(pkt);
  ------------------
  |  |  176|      0|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|      0|        void *oom_p_ = (x);     \
  |  |  178|      0|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  179|      0|            abort();            \
  |  |  180|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 2642|      0|        pkt->stream = ds->sh->index;
 2643|      0|        *res = pkt;
 2644|      0|        return 1;
 2645|      0|    }
 2646|       |
 2647|  1.76M|    if (!in->reading && !in->eof) {
  ------------------
  |  Branch (2647:9): [True: 872k, False: 890k]
  |  Branch (2647:25): [True: 668k, False: 204k]
  ------------------
 2648|   668k|        in->reading = true; // enable demuxer thread prefetching
 2649|   668k|        mp_cond_signal(&in->wakeup);
 2650|   668k|    }
 2651|       |
 2652|  1.76M|    ds->force_read_until = min_pts;
 2653|       |
 2654|  1.76M|    if (ds->back_resuming || ds->back_restarting) {
  ------------------
  |  Branch (2654:9): [True: 8, False: 1.76M]
  |  Branch (2654:30): [True: 0, False: 1.76M]
  ------------------
 2655|      0|        mp_assert(in->back_demuxing);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 2656|      0|        return 0;
 2657|      0|    }
 2658|       |
 2659|  1.76M|    bool eof = !ds->reader_head && ds->eof;
  ------------------
  |  Branch (2659:16): [True: 340k, False: 1.42M]
  |  Branch (2659:36): [True: 84.8k, False: 255k]
  ------------------
 2660|       |
 2661|  1.76M|    if (in->back_demuxing) {
  ------------------
  |  Branch (2661:9): [True: 0, False: 1.76M]
  ------------------
 2662|       |        // Subtitles not supported => EOF.
 2663|      0|        if (!ds->eager)
  ------------------
  |  Branch (2663:13): [True: 0, False: 0]
  ------------------
 2664|      0|            return -1;
 2665|       |
 2666|       |        // Next keyframe (or EOF) was reached => step back.
 2667|      0|        if (ds->back_range_started && !ds->back_range_count &&
  ------------------
  |  Branch (2667:13): [True: 0, False: 0]
  |  Branch (2667:39): [True: 0, False: 0]
  ------------------
 2668|      0|            ((ds->reader_head && ds->reader_head->keyframe) || eof))
  ------------------
  |  Branch (2668:15): [True: 0, False: 0]
  |  Branch (2668:34): [True: 0, False: 0]
  |  Branch (2668:64): [True: 0, False: 0]
  ------------------
 2669|      0|        {
 2670|      0|            ds->back_restarting = true;
 2671|      0|            ds->back_restart_eof = false;
 2672|      0|            ds->back_restart_next = false;
 2673|       |
 2674|      0|            find_backward_restart_pos(ds);
 2675|       |
 2676|      0|            if (ds->back_restarting)
  ------------------
  |  Branch (2676:17): [True: 0, False: 0]
  ------------------
 2677|      0|                return 0;
 2678|      0|        }
 2679|       |
 2680|      0|        eof = ds->back_range_count < 0;
 2681|      0|    }
 2682|       |
 2683|  1.76M|    ds->need_wakeup = !ds->reader_head;
 2684|  1.76M|    if (!ds->reader_head || eof) {
  ------------------
  |  Branch (2684:9): [True: 340k, False: 1.42M]
  |  Branch (2684:29): [True: 0, False: 1.42M]
  ------------------
 2685|   340k|        if (!ds->eager) {
  ------------------
  |  Branch (2685:13): [True: 0, False: 340k]
  ------------------
 2686|       |            // Non-eager streams temporarily return EOF. If they returned 0,
 2687|       |            // the reader would have to wait for new packets, which does not
 2688|       |            // make sense due to the sparseness and passiveness of non-eager
 2689|       |            // streams.
 2690|       |            // Unless the min_pts feature is used: then EOF is only signaled
 2691|       |            // if read-ahead went above min_pts.
 2692|      0|            if (!lazy_stream_needs_wait(ds))
  ------------------
  |  Branch (2692:17): [True: 0, False: 0]
  ------------------
 2693|      0|                ds->eof = eof = true;
 2694|      0|        }
 2695|   340k|        return eof ? -1 : 0;
  ------------------
  |  Branch (2695:16): [True: 84.8k, False: 255k]
  ------------------
 2696|   340k|    }
 2697|       |
 2698|  1.42M|    struct demux_packet *pkt = advance_reader_head(ds);
 2699|  1.42M|    mp_assert(pkt);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
 2700|  1.42M|    pkt = read_packet_from_cache(in, pkt);
 2701|  1.42M|    if (!pkt)
  ------------------
  |  Branch (2701:9): [True: 0, False: 1.42M]
  ------------------
 2702|      0|        return 0;
 2703|       |
 2704|  1.42M|    if (in->back_demuxing) {
  ------------------
  |  Branch (2704:9): [True: 0, False: 1.42M]
  ------------------
 2705|      0|        if (pkt->keyframe) {
  ------------------
  |  Branch (2705:13): [True: 0, False: 0]
  ------------------
 2706|      0|            mp_assert(ds->back_range_count > 0);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 2707|      0|            ds->back_range_count -= 1;
 2708|      0|            if (ds->back_range_preroll >= 0)
  ------------------
  |  Branch (2708:17): [True: 0, False: 0]
  ------------------
 2709|      0|                ds->back_range_preroll -= 1;
 2710|      0|        }
 2711|       |
 2712|      0|        if (ds->back_range_preroll >= 0)
  ------------------
  |  Branch (2712:13): [True: 0, False: 0]
  ------------------
 2713|      0|            pkt->back_preroll = true;
 2714|       |
 2715|      0|        if (!ds->back_range_started) {
  ------------------
  |  Branch (2715:13): [True: 0, False: 0]
  ------------------
 2716|      0|            pkt->back_restart = true;
 2717|      0|            ds->back_range_started = true;
 2718|      0|        }
 2719|      0|    }
 2720|       |
 2721|  1.42M|    double ts = MP_PTS_OR_DEF(pkt->dts, pkt->pts);
  ------------------
  |  |   61|  1.42M|#define MP_PTS_OR_DEF(a, def) ((a) == MP_NOPTS_VALUE ? (def) : (a))
  |  |  ------------------
  |  |  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (61:32): [True: 14.4k, False: 1.40M]
  |  |  ------------------
  ------------------
 2722|  1.42M|    if (ts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2722:9): [True: 1.40M, False: 14.2k]
  ------------------
 2723|  1.40M|        ds->base_ts = ts;
 2724|       |
 2725|  1.42M|    if (pkt->keyframe && ts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  1.25M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2725:9): [True: 1.25M, False: 171k]
  |  Branch (2725:26): [True: 1.24M, False: 5.55k]
  ------------------
 2726|       |        // Update bitrate - only at keyframe points, because we use the
 2727|       |        // (possibly) reordered packet timestamps instead of realtime.
 2728|  1.24M|        double d = ts - ds->last_br_ts;
 2729|  1.24M|        if (ds->last_br_ts == MP_NOPTS_VALUE || d < 0) {
  ------------------
  |  |   38|  2.49M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2729:13): [True: 4.05k, False: 1.24M]
  |  Branch (2729:49): [True: 0, False: 1.24M]
  ------------------
 2730|  4.05k|            ds->bitrate = -1;
 2731|  4.05k|            ds->last_br_ts = ts;
 2732|  4.05k|            ds->last_br_bytes = 0;
 2733|  1.24M|        } else if (d >= 0.5) { // a window of least 500ms for UI purposes
  ------------------
  |  Branch (2733:20): [True: 49.4k, False: 1.19M]
  ------------------
 2734|  49.4k|            ds->bitrate = ds->last_br_bytes / d;
 2735|  49.4k|            ds->last_br_ts = ts;
 2736|  49.4k|            ds->last_br_bytes = 0;
 2737|  49.4k|        }
 2738|  1.24M|    }
 2739|  1.42M|    ds->last_br_bytes += pkt->len;
 2740|       |
 2741|       |    // This implies this function is actually called from "the" user thread.
 2742|  1.42M|    if (pkt->pos >= in->d_user->filepos)
  ------------------
  |  Branch (2742:9): [True: 1.32M, False: 101k]
  ------------------
 2743|  1.32M|        in->d_user->filepos = pkt->pos;
 2744|  1.42M|    in->d_user->filesize = in->stream_size;
 2745|       |
 2746|  1.42M|    pkt->pts = MP_ADD_PTS(pkt->pts, in->ts_offset);
  ------------------
  |  |   66|  1.42M|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 14.2k, False: 1.40M]
  |  |  ------------------
  ------------------
 2747|  1.42M|    pkt->dts = MP_ADD_PTS(pkt->dts, in->ts_offset);
  ------------------
  |  |   66|  1.42M|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 14.4k, False: 1.40M]
  |  |  ------------------
  ------------------
 2748|       |
 2749|  1.42M|    if (pkt->segmented) {
  ------------------
  |  Branch (2749:9): [True: 6.35k, False: 1.41M]
  ------------------
 2750|  6.35k|        pkt->start = MP_ADD_PTS(pkt->start, in->ts_offset);
  ------------------
  |  |   66|  6.35k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  6.35k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 6.35k]
  |  |  ------------------
  ------------------
 2751|  6.35k|        pkt->end = MP_ADD_PTS(pkt->end, in->ts_offset);
  ------------------
  |  |   66|  6.35k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  6.35k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 6.35k]
  |  |  ------------------
  ------------------
 2752|  6.35k|    }
 2753|       |
 2754|  1.42M|    prune_old_packets(in);
 2755|  1.42M|    *res = pkt;
 2756|  1.42M|    return 1;
 2757|  1.42M|}
demux.c:read_packet_from_cache:
 2599|  1.42M|{
 2600|  1.42M|    if (!pkt)
  ------------------
  |  Branch (2600:9): [True: 0, False: 1.42M]
  ------------------
 2601|      0|        return NULL;
 2602|       |
 2603|  1.42M|    if (pkt->is_cached) {
  ------------------
  |  Branch (2603:9): [True: 0, False: 1.42M]
  ------------------
 2604|      0|        mp_assert(in->cache);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 2605|      0|        struct demux_packet *meta = pkt;
 2606|      0|        pkt = demux_cache_read(in->cache, pkt->cached_data.pos);
 2607|      0|        if (pkt) {
  ------------------
  |  Branch (2607:13): [True: 0, False: 0]
  ------------------
 2608|      0|            demux_packet_copy_attribs(pkt, meta);
 2609|      0|        } else {
 2610|      0|            MP_ERR(in, "Failed to retrieve packet from cache.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2611|      0|        }
 2612|  1.42M|    } else {
 2613|       |        // The returned packet is mutated etc. and will be owned by the user.
 2614|  1.42M|        pkt = demux_copy_packet(in->packet_pool, pkt);
 2615|  1.42M|    }
 2616|       |
 2617|  1.42M|    return pkt;
 2618|  1.42M|}
demux.c:thread_work:
 2521|  2.31M|{
 2522|  2.31M|    if (m_config_cache_update(in->d_user->opts_cache))
  ------------------
  |  Branch (2522:9): [True: 0, False: 2.31M]
  ------------------
 2523|      0|        update_opts(in->d_user);
 2524|  2.31M|    if (in->tracks_switched) {
  ------------------
  |  Branch (2524:9): [True: 3.97k, False: 2.31M]
  ------------------
 2525|  3.97k|        execute_trackswitch(in);
 2526|  3.97k|        return true;
 2527|  3.97k|    }
 2528|  2.31M|    if (in->need_back_seek) {
  ------------------
  |  Branch (2528:9): [True: 0, False: 2.31M]
  ------------------
 2529|      0|        perform_backward_seek(in);
 2530|      0|        return true;
 2531|      0|    }
 2532|  2.31M|    if (in->back_any_need_recheck) {
  ------------------
  |  Branch (2532:9): [True: 0, False: 2.31M]
  ------------------
 2533|      0|        check_backward_seek(in);
 2534|      0|        return true;
 2535|      0|    }
 2536|  2.31M|    if (in->seeking) {
  ------------------
  |  Branch (2536:9): [True: 1.03k, False: 2.30M]
  ------------------
 2537|  1.03k|        execute_seek(in);
 2538|  1.03k|        return true;
 2539|  1.03k|    }
 2540|  2.30M|    if (read_packet(in))
  ------------------
  |  Branch (2540:9): [True: 1.63M, False: 676k]
  ------------------
 2541|  1.63M|        return true; // read_packet unlocked, so recheck conditions
 2542|   676k|    if (mp_time_ns() >= in->next_cache_update) {
  ------------------
  |  Branch (2542:9): [True: 75, False: 676k]
  ------------------
 2543|     75|        update_cache(in);
 2544|     75|        return true;
 2545|     75|    }
 2546|   676k|    return false;
 2547|   676k|}
demux.c:update_opts:
 2454|  21.5k|{
 2455|  21.5k|    struct demux_opts *opts = demuxer->opts;
 2456|  21.5k|    struct demux_internal *in = demuxer->in;
 2457|       |
 2458|  21.5k|    in->min_secs = opts->min_secs;
 2459|  21.5k|    in->hyst_secs = opts->hyst_secs;
 2460|  21.5k|    in->max_bytes = opts->max_bytes;
 2461|  21.5k|    in->max_bytes_bw = opts->max_bytes_bw;
 2462|       |
 2463|  21.5k|    int seekable = opts->seekable_cache;
 2464|  21.5k|    bool is_streaming = in->d_thread->is_streaming;
 2465|  21.5k|    bool use_cache = is_streaming;
 2466|  21.5k|    if (opts->enable_cache >= 0)
  ------------------
  |  Branch (2466:9): [True: 0, False: 21.5k]
  ------------------
 2467|      0|        use_cache = opts->enable_cache == 1;
 2468|       |
 2469|  21.5k|    if (use_cache) {
  ------------------
  |  Branch (2469:9): [True: 0, False: 21.5k]
  ------------------
 2470|      0|        in->min_secs = MPMAX(in->min_secs, opts->min_secs_cache);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2471|      0|        if (seekable < 0)
  ------------------
  |  Branch (2471:13): [True: 0, False: 0]
  ------------------
 2472|      0|            seekable = 1;
 2473|      0|    }
 2474|  21.5k|    in->seekable_cache = seekable == 1;
 2475|  21.5k|    in->using_network_cache_opts = is_streaming && use_cache;
  ------------------
  |  Branch (2475:36): [True: 0, False: 21.5k]
  |  Branch (2475:52): [True: 0, False: 0]
  ------------------
 2476|       |
 2477|  21.5k|    if (!in->seekable_cache)
  ------------------
  |  Branch (2477:9): [True: 21.5k, False: 0]
  ------------------
 2478|  21.5k|        in->max_bytes_bw = 0;
 2479|       |
 2480|  21.5k|    if (!in->can_cache) {
  ------------------
  |  Branch (2480:9): [True: 16.4k, False: 5.09k]
  ------------------
 2481|  16.4k|        in->seekable_cache = false;
 2482|  16.4k|        in->min_secs = 0;
 2483|  16.4k|        in->max_bytes = 1;
 2484|  16.4k|        in->max_bytes_bw = 0;
 2485|  16.4k|        in->using_network_cache_opts = false;
 2486|  16.4k|    }
 2487|       |
 2488|  21.5k|    if (in->seekable_cache && opts->disk_cache && !in->cache) {
  ------------------
  |  Branch (2488:9): [True: 0, False: 21.5k]
  |  Branch (2488:31): [True: 0, False: 0]
  |  Branch (2488:51): [True: 0, False: 0]
  ------------------
 2489|      0|        in->cache = demux_cache_create(in->global, in->log);
 2490|      0|        if (!in->cache)
  ------------------
  |  Branch (2490:13): [True: 0, False: 0]
  ------------------
 2491|      0|            MP_ERR(in, "Failed to create file cache.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2492|      0|    }
 2493|       |
 2494|       |    // The filename option really decides whether recording should be active.
 2495|       |    // So if the filename changes, act upon it.
 2496|  21.5k|    char *old = in->record_filename ? in->record_filename : "";
  ------------------
  |  Branch (2496:17): [True: 0, False: 21.5k]
  ------------------
 2497|  21.5k|    char *new = opts->record_file ? opts->record_file : "";
  ------------------
  |  Branch (2497:17): [True: 0, False: 21.5k]
  ------------------
 2498|  21.5k|    if (strcmp(old, new) != 0) {
  ------------------
  |  Branch (2498:9): [True: 0, False: 21.5k]
  ------------------
 2499|      0|        if (in->recorder) {
  ------------------
  |  Branch (2499:13): [True: 0, False: 0]
  ------------------
 2500|      0|            MP_WARN(in, "Stopping recording.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2501|      0|            mp_recorder_destroy(in->recorder);
 2502|      0|            in->recorder = NULL;
 2503|      0|        }
 2504|      0|        talloc_free(in->record_filename);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2505|      0|        in->record_filename = talloc_strdup(in, opts->record_file);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
 2506|       |        // Note: actual recording only starts once packets are read. It may be
 2507|       |        // important to delay creating in->recorder to that point, because the
 2508|       |        // demuxer might detect more streams until finding the first packet.
 2509|      0|        in->enable_recording = in->can_record;
 2510|      0|    }
 2511|       |
 2512|       |    // In case the cache was reduced in size.
 2513|  21.5k|    prune_old_packets(in);
 2514|       |
 2515|       |    // In case the seekable cache was disabled.
 2516|  21.5k|    free_empty_cached_ranges(in);
 2517|  21.5k|}
demux.c:execute_seek:
 2420|  63.3k|{
 2421|  63.3k|    int flags = in->seek_flags;
 2422|  63.3k|    double pts = in->seek_pts;
 2423|  63.3k|    in->eof = false;
 2424|  63.3k|    in->seeking = false;
 2425|  63.3k|    in->seeking_in_progress = pts;
 2426|  63.3k|    in->demux_ts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  63.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2427|  63.3k|    in->low_level_seeks += 1;
 2428|  63.3k|    in->after_seek = true;
 2429|  63.3k|    in->after_seek_to_start =
 2430|  63.3k|        !(flags & (SEEK_FORWARD | SEEK_FACTOR)) &&
  ------------------
  |  |   93|  63.3k|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
                      !(flags & (SEEK_FORWARD | SEEK_FACTOR)) &&
  ------------------
  |  |   92|  63.3k|#define SEEK_FACTOR   (1 << 1)      // argument is in range [0,1]
  ------------------
  |  Branch (2430:9): [True: 63.3k, False: 0]
  ------------------
 2431|  63.3k|        pts <= in->d_thread->start_time;
  ------------------
  |  Branch (2431:9): [True: 63.3k, False: 0]
  ------------------
 2432|       |
 2433|   143k|    for (int n = 0; n < in->num_streams; n++)
  ------------------
  |  Branch (2433:21): [True: 79.9k, False: 63.3k]
  ------------------
 2434|  79.9k|        in->streams[n]->ds->queue->last_pos_fixup = -1;
 2435|       |
 2436|  63.3k|    if (in->recorder)
  ------------------
  |  Branch (2436:9): [True: 0, False: 63.3k]
  ------------------
 2437|      0|        mp_recorder_mark_discontinuity(in->recorder);
 2438|       |
 2439|  63.3k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  63.3k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2440|       |
 2441|  63.3k|    MP_VERBOSE(in, "execute seek (to %f flags %d)\n", pts, flags);
  ------------------
  |  |   88|  63.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  63.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2442|       |
 2443|  63.3k|    if (in->d_thread->desc->seek)
  ------------------
  |  Branch (2443:9): [True: 63.2k, False: 107]
  ------------------
 2444|  63.2k|        in->d_thread->desc->seek(in->d_thread, pts, flags);
 2445|       |
 2446|  63.3k|    MP_VERBOSE(in, "seek done\n");
  ------------------
  |  |   88|  63.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  63.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2447|       |
 2448|  63.3k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  63.3k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2449|       |
 2450|  63.3k|    in->seeking_in_progress = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  63.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2451|  63.3k|}
demux.c:read_packet:
 2163|  2.30M|{
 2164|  2.30M|    bool was_reading = in->reading;
 2165|  2.30M|    in->reading = false;
 2166|       |
 2167|  2.30M|    if (!was_reading || in->blocked || demux_cancel_test(in->d_thread))
  ------------------
  |  Branch (2167:9): [True: 73.3k, False: 2.23M]
  |  Branch (2167:25): [True: 0, False: 2.23M]
  |  Branch (2167:40): [True: 0, False: 2.23M]
  ------------------
 2168|  73.3k|        return false;
 2169|       |
 2170|       |    // Check if we need to read a new packet. We do this if all queues are below
 2171|       |    // the minimum, or if a stream explicitly needs new packets. Also includes
 2172|       |    // safe-guards against packet queue overflow.
 2173|  2.23M|    bool read_more = false, prefetch_more = false, refresh_more = false;
 2174|  2.23M|    uint64_t total_fw_bytes = 0;
 2175|  4.63M|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2175:21): [True: 2.40M, False: 2.23M]
  ------------------
 2176|  2.40M|        struct demux_stream *ds = in->streams[n]->ds;
 2177|  2.40M|        if (ds->eager) {
  ------------------
  |  Branch (2177:13): [True: 2.40M, False: 0]
  ------------------
 2178|  2.40M|            read_more |= !ds->reader_head;
 2179|  2.40M|            if (in->back_demuxing)
  ------------------
  |  Branch (2179:17): [True: 0, False: 2.40M]
  ------------------
 2180|      0|                read_more |= ds->back_restarting || ds->back_resuming;
  ------------------
  |  Branch (2180:30): [True: 0, False: 0]
  |  Branch (2180:53): [True: 0, False: 0]
  ------------------
 2181|  2.40M|        } else {
 2182|      0|            if (lazy_stream_needs_wait(ds)) {
  ------------------
  |  Branch (2182:17): [True: 0, False: 0]
  ------------------
 2183|      0|                read_more = true;
 2184|      0|            } else {
 2185|      0|                mark_stream_eof(ds); // let playback continue
 2186|      0|            }
 2187|      0|        }
 2188|  2.40M|        refresh_more |= ds->refreshing;
 2189|  2.40M|        if (ds->eager && ds->queue->last_ts != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|  4.80M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2189:13): [True: 2.40M, False: 0]
  |  Branch (2189:26): [True: 2.06M, False: 337k]
  ------------------
 2190|  2.40M|            in->min_secs > 0 && ds->base_ts != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|  4.46M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (2190:13): [True: 2.06M, False: 2.22k]
  |  Branch (2190:33): [True: 2.06M, False: 0]
  ------------------
 2191|  2.40M|            ds->queue->last_ts >= ds->base_ts &&
  ------------------
  |  Branch (2191:13): [True: 2.06M, False: 0]
  ------------------
 2192|  2.40M|            !in->back_demuxing)
  ------------------
  |  Branch (2192:13): [True: 2.06M, False: 0]
  ------------------
 2193|  2.06M|        {
 2194|  2.06M|            if (ds->queue->last_ts - ds->base_ts <= in->hyst_secs)
  ------------------
  |  Branch (2194:17): [True: 8.79k, False: 2.05M]
  ------------------
 2195|  8.79k|                in->hyst_active = false;
 2196|  2.06M|            if (!in->hyst_active)
  ------------------
  |  Branch (2196:17): [True: 2.06M, False: 0]
  ------------------
 2197|  2.06M|                prefetch_more |= ds->queue->last_ts - ds->base_ts < in->min_secs;
 2198|  2.06M|        }
 2199|  2.40M|        total_fw_bytes += get_forward_buffered_bytes(ds);
 2200|  2.40M|    }
 2201|       |
 2202|  2.23M|    MP_TRACE(in, "bytes=%zd, read_more=%d prefetch_more=%d, refresh_more=%d\n",
  ------------------
  |  |   90|  2.23M|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.23M|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2203|  2.23M|             (size_t)total_fw_bytes, read_more, prefetch_more, refresh_more);
 2204|  2.23M|    if (total_fw_bytes >= in->max_bytes) {
  ------------------
  |  Branch (2204:9): [True: 0, False: 2.23M]
  ------------------
 2205|       |        // if we hit the limit just by prefetching, simply stop prefetching
 2206|      0|        if (!read_more) {
  ------------------
  |  Branch (2206:13): [True: 0, False: 0]
  ------------------
 2207|      0|            in->hyst_active = !!in->hyst_secs;
 2208|      0|            return false;
 2209|      0|        }
 2210|      0|        if (!in->warned_queue_overflow) {
  ------------------
  |  Branch (2210:13): [True: 0, False: 0]
  ------------------
 2211|      0|            in->warned_queue_overflow = true;
 2212|      0|            MP_WARN(in, "Too many packets in the demuxer packet queues:\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2213|      0|            for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2213:29): [True: 0, False: 0]
  ------------------
 2214|      0|                struct demux_stream *ds = in->streams[n]->ds;
 2215|      0|                if (ds->selected) {
  ------------------
  |  Branch (2215:21): [True: 0, False: 0]
  ------------------
 2216|      0|                    size_t num_pkts = 0;
 2217|      0|                    for (struct demux_packet *dp = ds->reader_head;
 2218|      0|                         dp; dp = dp->next)
  ------------------
  |  Branch (2218:26): [True: 0, False: 0]
  ------------------
 2219|      0|                        num_pkts++;
 2220|      0|                    uint64_t fw_bytes = get_forward_buffered_bytes(ds);
 2221|      0|                    MP_WARN(in, "  %s/%d: %zd packets, %zd bytes%s%s\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2222|      0|                            stream_type_name(ds->type), n,
 2223|      0|                            num_pkts, (size_t)fw_bytes,
 2224|      0|                            ds->eager ? "" : " (lazy)",
 2225|      0|                            ds->refreshing ? " (refreshing)" : "");
 2226|      0|                }
 2227|      0|            }
 2228|      0|            if (in->back_demuxing)
  ------------------
  |  Branch (2228:17): [True: 0, False: 0]
  ------------------
 2229|      0|                MP_ERR(in, "Backward playback is likely stuck/broken now.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2230|      0|        }
 2231|      0|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2231:25): [True: 0, False: 0]
  ------------------
 2232|      0|            struct demux_stream *ds = in->streams[n]->ds;
 2233|      0|            if (!ds->reader_head)
  ------------------
  |  Branch (2233:17): [True: 0, False: 0]
  ------------------
 2234|      0|                mark_stream_eof(ds);
 2235|      0|        }
 2236|      0|        return false;
 2237|      0|    }
 2238|       |
 2239|  2.23M|    if (!read_more && !prefetch_more && !refresh_more) {
  ------------------
  |  Branch (2239:9): [True: 2.00M, False: 227k]
  |  Branch (2239:23): [True: 603k, False: 1.40M]
  |  Branch (2239:41): [True: 603k, False: 0]
  ------------------
 2240|   603k|        in->hyst_active = !!in->hyst_secs;
 2241|   603k|        return false;
 2242|   603k|    }
 2243|       |
 2244|  1.63M|    if (in->after_seek_to_start) {
  ------------------
  |  Branch (2244:9): [True: 65.1k, False: 1.56M]
  ------------------
 2245|   147k|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2245:25): [True: 82.7k, False: 65.1k]
  ------------------
 2246|  82.7k|            struct demux_stream *ds = in->streams[n]->ds;
 2247|  82.7k|            in->current_range->streams[n]->is_bof =
 2248|  82.7k|                ds->selected && !ds->refreshing;
  ------------------
  |  Branch (2248:17): [True: 82.7k, False: 0]
  |  Branch (2248:33): [True: 82.7k, False: 0]
  ------------------
 2249|  82.7k|        }
 2250|  65.1k|    }
 2251|       |
 2252|       |    // Actually read a packet. Drop the lock while doing so, because waiting
 2253|       |    // for disk or network I/O can take time.
 2254|  1.63M|    in->reading = true;
 2255|  1.63M|    in->after_seek = false;
 2256|  1.63M|    in->after_seek_to_start = false;
 2257|  1.63M|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  1.63M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2258|       |
 2259|  1.63M|    struct demuxer *demux = in->d_thread;
 2260|  1.63M|    struct demux_packet *pkt = NULL;
 2261|       |
 2262|  1.63M|    bool eof = true;
 2263|  1.63M|    if (demux->desc->read_packet && !demux_cancel_test(demux))
  ------------------
  |  Branch (2263:9): [True: 1.63M, False: 0]
  |  Branch (2263:37): [True: 1.63M, False: 0]
  ------------------
 2264|  1.63M|        eof = !demux->desc->read_packet(demux, &pkt);
 2265|       |
 2266|  1.63M|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  1.63M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2267|  1.63M|    update_cache(in);
 2268|       |
 2269|  1.63M|    if (pkt) {
  ------------------
  |  Branch (2269:9): [True: 1.42M, False: 209k]
  ------------------
 2270|  1.42M|        mp_assert(pkt->stream >= 0 && pkt->stream < in->num_streams);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
 2271|  1.42M|        add_packet_locked(in->streams[pkt->stream], pkt);
 2272|  1.42M|    }
 2273|       |
 2274|  1.63M|    if (!in->seeking) {
  ------------------
  |  Branch (2274:9): [True: 1.63M, False: 0]
  ------------------
 2275|  1.63M|        if (eof) {
  ------------------
  |  Branch (2275:13): [True: 65.1k, False: 1.56M]
  ------------------
 2276|   147k|            for (int n = 0; n < in->num_streams; n++)
  ------------------
  |  Branch (2276:29): [True: 82.7k, False: 65.1k]
  ------------------
 2277|  82.7k|                mark_stream_eof(in->streams[n]->ds);
 2278|       |            // If we had EOF previously, then don't wakeup (avoids wakeup loop)
 2279|  65.1k|            if (!in->eof) {
  ------------------
  |  Branch (2279:17): [True: 65.1k, False: 0]
  ------------------
 2280|  65.1k|                if (in->wakeup_cb)
  ------------------
  |  Branch (2280:21): [True: 2.97k, False: 62.2k]
  ------------------
 2281|  2.97k|                    in->wakeup_cb(in->wakeup_cb_ctx);
 2282|  65.1k|                mp_cond_signal(&in->wakeup);
 2283|  65.1k|                MP_VERBOSE(in, "EOF reached.\n");
  ------------------
  |  |   88|  65.1k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  65.1k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2284|  65.1k|            }
 2285|  65.1k|        }
 2286|  1.63M|        in->eof = eof;
 2287|  1.63M|        in->reading = !eof;
 2288|  1.63M|    }
 2289|  1.63M|    return true;
 2290|  1.63M|}
demux.c:mark_stream_eof:
 2141|  82.7k|{
 2142|  82.7k|    if (!ds->eof) {
  ------------------
  |  Branch (2142:9): [True: 82.7k, False: 0]
  ------------------
 2143|  82.7k|        ds->eof = true;
 2144|  82.7k|        adjust_seek_range_on_packet(ds, NULL);
 2145|  82.7k|        back_demux_see_packets(ds);
 2146|  82.7k|        wakeup_ds(ds);
 2147|  82.7k|    }
 2148|  82.7k|}
demux.c:lookup_timed_metadata:
 3116|   238k|{
 3117|   238k|    struct demux_cached_range *r = in->current_range;
 3118|       |
 3119|   238k|    if (!r || !r->num_metadata || pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3119:9): [True: 0, False: 238k]
  |  Branch (3119:15): [True: 238k, False: 0]
  |  Branch (3119:35): [True: 0, False: 0]
  ------------------
 3120|   238k|        return NULL;
 3121|       |
 3122|      0|    int start = 1;
 3123|      0|    int i = in->cached_metadata_index;
 3124|      0|    if (i >= 0 &&  i < r->num_metadata && r->metadata[i]->pts <= pts)
  ------------------
  |  Branch (3124:9): [True: 0, False: 0]
  |  Branch (3124:20): [True: 0, False: 0]
  |  Branch (3124:43): [True: 0, False: 0]
  ------------------
 3125|      0|        start = i + 1;
 3126|       |
 3127|      0|    in->cached_metadata_index = r->num_metadata - 1;
 3128|      0|    for (int n = start; n < r->num_metadata; n++) {
  ------------------
  |  Branch (3128:25): [True: 0, False: 0]
  ------------------
 3129|      0|        if (r->metadata[n]->pts >= pts) {
  ------------------
  |  Branch (3129:13): [True: 0, False: 0]
  ------------------
 3130|      0|            in->cached_metadata_index = n - 1;
 3131|      0|            break;
 3132|      0|        }
 3133|      0|    }
 3134|       |
 3135|      0|    return r->metadata[in->cached_metadata_index];
 3136|   238k|}
demux.c:update_final_metadata:
 3073|  21.5k|{
 3074|  21.5k|    mp_assert(demuxer == demuxer->in->d_user);
  ------------------
  |  |   41|  21.5k|#define mp_assert assert
  ------------------
 3075|  21.5k|    struct demux_internal *in = demuxer->in;
 3076|       |
 3077|  21.5k|    struct mp_tags *dyn_tags = NULL;
 3078|       |
 3079|       |    // Often useful for audio-only files, which have metadata in the audio track
 3080|       |    // metadata instead of the main metadata, but can also have cover art
 3081|       |    // metadata (which libavformat likes to treat as video streams).
 3082|  21.5k|    int astreams = 0;
 3083|  21.5k|    int astream_id = -1;
 3084|  21.5k|    int vstreams = 0;
 3085|  48.4k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3085:21): [True: 26.9k, False: 21.5k]
  ------------------
 3086|  26.9k|        struct sh_stream *sh = in->streams[n];
 3087|  26.9k|        if (sh->type == STREAM_VIDEO && !sh->attached_picture)
  ------------------
  |  Branch (3087:13): [True: 9.69k, False: 17.2k]
  |  Branch (3087:41): [True: 9.69k, False: 0]
  ------------------
 3088|  9.69k|            vstreams += 1;
 3089|  26.9k|        if (sh->type == STREAM_AUDIO) {
  ------------------
  |  Branch (3089:13): [True: 16.8k, False: 10.0k]
  ------------------
 3090|  16.8k|            astreams += 1;
 3091|  16.8k|            astream_id = n;
 3092|  16.8k|        }
 3093|  26.9k|    }
 3094|       |
 3095|       |    // Use the metadata_stream tags only if this really seems to be an audio-
 3096|       |    // only stream. Otherwise it will happen too often that "uninteresting"
 3097|       |    // stream metadata will trash the actual file tags.
 3098|  21.5k|    if (vstreams == 0 && astreams == 1 &&
  ------------------
  |  Branch (3098:9): [True: 11.8k, False: 9.69k]
  |  Branch (3098:26): [True: 10.1k, False: 1.67k]
  ------------------
 3099|  21.5k|        in->streams[astream_id] == in->metadata_stream)
  ------------------
  |  Branch (3099:9): [True: 10.1k, False: 0]
  ------------------
 3100|  10.1k|    {
 3101|  10.1k|        dyn_tags = in->metadata_stream->tags;
 3102|  10.1k|        if (tm && tm->from_stream)
  ------------------
  |  Branch (3102:13): [True: 0, False: 10.1k]
  |  Branch (3102:19): [True: 0, False: 0]
  ------------------
 3103|      0|            dyn_tags = tm->tags;
 3104|  10.1k|    }
 3105|       |
 3106|       |    // Global metadata updates.
 3107|  21.5k|    if (tm && !tm->from_stream)
  ------------------
  |  Branch (3107:9): [True: 0, False: 21.5k]
  |  Branch (3107:15): [True: 0, False: 0]
  ------------------
 3108|      0|        dyn_tags = tm->tags;
 3109|       |
 3110|  21.5k|    if (dyn_tags)
  ------------------
  |  Branch (3110:9): [True: 10.1k, False: 11.3k]
  ------------------
 3111|  10.1k|        mp_tags_merge(demuxer->metadata, dyn_tags);
 3112|  21.5k|}
demux.c:demux_update_replaygain:
 2957|  26.0k|{
 2958|  26.0k|    struct demux_internal *in = demuxer->in;
 2959|  58.2k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (2959:21): [True: 32.1k, False: 26.0k]
  ------------------
 2960|  32.1k|        struct sh_stream *sh = in->streams[n];
 2961|  32.1k|        if (sh->type == STREAM_AUDIO && !sh->codec->replaygain_data) {
  ------------------
  |  Branch (2961:13): [True: 18.7k, False: 13.3k]
  |  Branch (2961:41): [True: 18.7k, False: 0]
  ------------------
 2962|  18.7k|            struct replaygain_data *rg = decode_rgain(demuxer->log, sh->tags);
 2963|  18.7k|            if (!rg)
  ------------------
  |  Branch (2963:17): [True: 18.7k, False: 0]
  ------------------
 2964|  18.7k|                rg = decode_rgain(demuxer->log, demuxer->metadata);
 2965|  18.7k|            if (rg)
  ------------------
  |  Branch (2965:17): [True: 0, False: 18.7k]
  ------------------
 2966|      0|                sh->codec->replaygain_data = talloc_steal(in, rg);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 2967|  18.7k|        }
 2968|  32.1k|    }
 2969|  26.0k|}
demux.c:decode_rgain:
 2907|  37.5k|{
 2908|  37.5k|    struct replaygain_data rg = {0};
 2909|       |
 2910|       |    // Set values in *rg, using track gain as a fallback for album gain if the
 2911|       |    // latter is not present. This behavior matches that in demux/demux_lavf.c's
 2912|       |    // export_replaygain; if you change this, please make equivalent changes
 2913|       |    // there too.
 2914|  37.5k|    if (decode_gain(log, tags, "REPLAYGAIN_TRACK_GAIN", &rg.track_gain) >= 0 &&
  ------------------
  |  Branch (2914:9): [True: 0, False: 37.5k]
  ------------------
 2915|  37.5k|        decode_peak(log, tags, "REPLAYGAIN_TRACK_PEAK", &rg.track_peak) >= 0)
  ------------------
  |  Branch (2915:9): [True: 0, False: 0]
  ------------------
 2916|      0|    {
 2917|      0|        if (decode_gain(log, tags, "REPLAYGAIN_ALBUM_GAIN", &rg.album_gain) < 0 ||
  ------------------
  |  Branch (2917:13): [True: 0, False: 0]
  ------------------
 2918|      0|            decode_peak(log, tags, "REPLAYGAIN_ALBUM_PEAK", &rg.album_peak) < 0)
  ------------------
  |  Branch (2918:13): [True: 0, False: 0]
  ------------------
 2919|      0|        {
 2920|       |            // Album gain is undefined; fall back to track gain.
 2921|      0|            rg.album_gain = rg.track_gain;
 2922|      0|            rg.album_peak = rg.track_peak;
 2923|      0|        }
 2924|      0|        return talloc_dup(NULL, &rg);
  ------------------
  |  |   48|      0|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|      0|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2925|      0|    }
 2926|       |
 2927|  37.5k|    if (decode_gain(log, tags, "REPLAYGAIN_GAIN", &rg.track_gain) >= 0 &&
  ------------------
  |  Branch (2927:9): [True: 0, False: 37.5k]
  ------------------
 2928|  37.5k|        decode_peak(log, tags, "REPLAYGAIN_PEAK", &rg.track_peak) >= 0)
  ------------------
  |  Branch (2928:9): [True: 0, False: 0]
  ------------------
 2929|      0|    {
 2930|      0|        rg.album_gain = rg.track_gain;
 2931|      0|        rg.album_peak = rg.track_peak;
 2932|      0|        return talloc_dup(NULL, &rg);
  ------------------
  |  |   48|      0|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|      0|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2933|      0|    }
 2934|       |
 2935|       |    // The r128 replaygain tags declared in RFC 7845 for opus files. The tags
 2936|       |    // are generated with EBU-R128, which does not use peak meters. And the
 2937|       |    // values are stored as a Q7.8 fixed point number in dB.
 2938|  37.5k|    if (decode_gain(log, tags, "R128_TRACK_GAIN", &rg.track_gain) >= 0) {
  ------------------
  |  Branch (2938:9): [True: 0, False: 37.5k]
  ------------------
 2939|      0|        if (decode_gain(log, tags, "R128_ALBUM_GAIN", &rg.album_gain) < 0) {
  ------------------
  |  Branch (2939:13): [True: 0, False: 0]
  ------------------
 2940|       |            // Album gain is undefined; fall back to track gain.
 2941|      0|            rg.album_gain = rg.track_gain;
 2942|      0|        }
 2943|      0|        rg.track_gain /= 256.;
 2944|      0|        rg.album_gain /= 256.;
 2945|       |
 2946|       |        // Add 5dB to compensate for the different reference levels between
 2947|       |        // our reference of ReplayGain 2 (-18 LUFS) and EBU R128 (-23 LUFS).
 2948|      0|        rg.track_gain += 5.;
 2949|      0|        rg.album_gain += 5.;
 2950|      0|        return talloc_dup(NULL, &rg);
  ------------------
  |  |   48|      0|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|      0|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2951|      0|    }
 2952|       |
 2953|  37.5k|    return NULL;
 2954|  37.5k|}
demux.c:decode_gain:
 2869|   112k|{
 2870|   112k|    char *tag_val = NULL;
 2871|   112k|    float dec_val;
 2872|       |
 2873|   112k|    tag_val = mp_tags_get_str(tags, tag);
 2874|   112k|    if (!tag_val)
  ------------------
  |  Branch (2874:9): [True: 112k, False: 0]
  ------------------
 2875|   112k|        return -1;
 2876|       |
 2877|      0|    if (decode_float(tag_val, &dec_val) < 0) {
  ------------------
  |  Branch (2877:9): [True: 0, False: 0]
  ------------------
 2878|      0|        mp_msg(log, MSGL_ERR, "Invalid replaygain value\n");
 2879|      0|        return -1;
 2880|      0|    }
 2881|       |
 2882|      0|    *out = dec_val;
 2883|      0|    return 0;
 2884|      0|}
demux.c:demux_open:
 3395|  22.9k|{
 3396|  22.9k|    const int *check_levels = d_normal;
 3397|  22.9k|    const struct demuxer_desc *check_desc = NULL;
 3398|  22.9k|    struct mp_log *log = mp_log_new(NULL, global->log, "!demux");
 3399|  22.9k|    struct demuxer *demuxer = NULL;
 3400|  22.9k|    char *force_format = params ? params->force_format : NULL;
  ------------------
  |  Branch (3400:26): [True: 22.9k, False: 0]
  ------------------
 3401|       |
 3402|  22.9k|    struct parent_stream_info sinfo = {
 3403|  22.9k|        .seekable = stream->seekable,
 3404|  22.9k|        .is_network = stream->is_network,
 3405|  22.9k|        .is_streaming = stream->streaming,
 3406|  22.9k|        .stream_origin = stream->stream_origin,
 3407|  22.9k|        .cancel = cancel,
 3408|  22.9k|        .filename = talloc_strdup(NULL, stream->url),
  ------------------
  |  |   50|  22.9k|#define talloc_strdup                   ta_xstrdup
  ------------------
 3409|  22.9k|    };
 3410|       |
 3411|  22.9k|    if (!force_format)
  ------------------
  |  Branch (3411:9): [True: 22.9k, False: 0]
  ------------------
 3412|  22.9k|        force_format = stream->demuxer;
 3413|       |
 3414|  22.9k|    if (force_format && force_format[0] && !stream->is_directory) {
  ------------------
  |  Branch (3414:9): [True: 0, False: 22.9k]
  |  Branch (3414:25): [True: 0, False: 0]
  |  Branch (3414:44): [True: 0, False: 0]
  ------------------
 3415|      0|        check_levels = d_request;
 3416|      0|        if (force_format[0] == '+') {
  ------------------
  |  Branch (3416:13): [True: 0, False: 0]
  ------------------
 3417|      0|            force_format += 1;
 3418|      0|            check_levels = d_force;
 3419|      0|        }
 3420|      0|        for (int n = 0; demuxer_list[n]; n++) {
  ------------------
  |  Branch (3420:25): [True: 0, False: 0]
  ------------------
 3421|      0|            if (strcmp(demuxer_list[n]->name, force_format) == 0) {
  ------------------
  |  Branch (3421:17): [True: 0, False: 0]
  ------------------
 3422|      0|                check_desc = demuxer_list[n];
 3423|      0|                break;
 3424|      0|            }
 3425|      0|        }
 3426|      0|        if (!check_desc) {
  ------------------
  |  Branch (3426:13): [True: 0, False: 0]
  ------------------
 3427|      0|            mp_err(log, "Demuxer %s does not exist.\n", force_format);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
 3428|      0|            goto done;
 3429|      0|        }
 3430|      0|    }
 3431|       |
 3432|       |    // Test demuxers from first to last, one pass for each check_levels[] entry
 3433|  26.9k|    for (int pass = 0; check_levels[pass] != -1; pass++) {
  ------------------
  |  Branch (3433:24): [True: 25.0k, False: 1.85k]
  ------------------
 3434|  25.0k|        enum demux_check level = check_levels[pass];
 3435|  25.0k|        mp_verbose(log, "Trying demuxers for level=%s.\n", d_level(level));
  ------------------
  |  |   75|  25.0k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
 3436|   218k|        for (int n = 0; demuxer_list[n]; n++) {
  ------------------
  |  Branch (3436:25): [True: 214k, False: 3.94k]
  ------------------
 3437|   214k|            const struct demuxer_desc *desc = demuxer_list[n];
 3438|   214k|            if (!check_desc || desc == check_desc) {
  ------------------
  |  Branch (3438:17): [True: 214k, False: 0]
  |  Branch (3438:32): [True: 0, False: 0]
  ------------------
 3439|   214k|                demuxer = open_given_type(global, log, desc, stream, &sinfo,
 3440|   214k|                                          params, level);
 3441|   214k|                if (demuxer) {
  ------------------
  |  Branch (3441:21): [True: 21.1k, False: 193k]
  ------------------
 3442|  21.1k|                    talloc_steal(demuxer, log);
  ------------------
  |  |   38|  21.1k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  21.1k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 3443|  21.1k|                    log = NULL;
 3444|  21.1k|                    goto done;
 3445|  21.1k|                }
 3446|   214k|            }
 3447|   214k|        }
 3448|  25.0k|    }
 3449|       |
 3450|  22.9k|done:
 3451|  22.9k|    talloc_free(sinfo.filename);
  ------------------
  |  |   47|  22.9k|#define talloc_free                     ta_free
  ------------------
 3452|  22.9k|    talloc_free(log);
  ------------------
  |  |   47|  22.9k|#define talloc_free                     ta_free
  ------------------
 3453|  22.9k|    return demuxer;
 3454|  22.9k|}
demux.c:d_level:
 2844|   240k|{
 2845|   240k|    switch (level) {
  ------------------
  |  Branch (2845:13): [True: 0, False: 240k]
  ------------------
 2846|    436|    case DEMUX_CHECK_FORCE:  return "force";
  ------------------
  |  Branch (2846:5): [True: 436, False: 239k]
  ------------------
 2847|  26.4k|    case DEMUX_CHECK_UNSAFE: return "unsafe";
  ------------------
  |  Branch (2847:5): [True: 26.4k, False: 213k]
  ------------------
 2848|      0|    case DEMUX_CHECK_REQUEST:return "request";
  ------------------
  |  Branch (2848:5): [True: 0, False: 240k]
  ------------------
 2849|   213k|    case DEMUX_CHECK_NORMAL: return "normal";
  ------------------
  |  Branch (2849:5): [True: 213k, False: 26.8k]
  ------------------
 2850|   240k|    }
 2851|      0|    MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
 2852|      0|}
demux.c:open_given_type:
 3267|   215k|{
 3268|   215k|    if (mp_cancel_test(sinfo->cancel))
  ------------------
  |  Branch (3268:9): [True: 0, False: 215k]
  ------------------
 3269|      0|        return NULL;
 3270|       |
 3271|   215k|    struct demuxer *demuxer = talloc_ptrtype(NULL, demuxer);
  ------------------
  |  |   34|   215k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   215k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   215k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3272|   215k|    struct m_config_cache *opts_cache =
 3273|   215k|        m_config_cache_alloc(demuxer, global, &demux_conf);
 3274|   215k|    struct demux_opts *opts = opts_cache->opts;
 3275|   215k|    *demuxer = (struct demuxer) {
 3276|   215k|        .desc = desc,
 3277|   215k|        .stream = stream,
 3278|   215k|        .cancel = sinfo->cancel,
 3279|   215k|        .seekable = sinfo->seekable,
 3280|   215k|        .filepos = -1,
 3281|   215k|        .global = global,
 3282|   215k|        .log = mp_log_new(demuxer, log, desc->name),
 3283|   215k|        .packet_pool = demux_packet_pool_get(global),
 3284|   215k|        .glog = log,
 3285|   215k|        .filename = talloc_strdup(demuxer, sinfo->filename),
  ------------------
  |  |   50|   215k|#define talloc_strdup                   ta_xstrdup
  ------------------
 3286|   215k|        .is_network = sinfo->is_network,
 3287|   215k|        .is_streaming = sinfo->is_streaming,
 3288|   215k|        .stream_origin = sinfo->stream_origin,
 3289|   215k|        .access_references = opts->access_references,
 3290|   215k|        .opts = opts,
 3291|   215k|        .opts_cache = opts_cache,
 3292|   215k|        .events = DEMUX_EVENT_ALL,
 3293|   215k|        .duration = -1,
 3294|   215k|    };
 3295|       |
 3296|   215k|    struct demux_internal *in = demuxer->in = talloc_ptrtype(demuxer, in);
  ------------------
  |  |   34|   215k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   215k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   215k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3297|   215k|    *in = (struct demux_internal){
 3298|   215k|        .global = global,
 3299|   215k|        .log = demuxer->log,
 3300|   215k|        .packet_pool = demux_packet_pool_get(global),
 3301|   215k|        .stats = stats_ctx_create(in, global, "demuxer"),
 3302|   215k|        .can_cache = params && params->is_top_level,
  ------------------
  |  Branch (3302:22): [True: 215k, False: 0]
  |  Branch (3302:32): [True: 85.8k, False: 129k]
  ------------------
 3303|   215k|        .can_record = params && params->stream_record,
  ------------------
  |  Branch (3303:23): [True: 215k, False: 0]
  |  Branch (3303:33): [True: 85.8k, False: 129k]
  ------------------
 3304|   215k|        .d_thread = talloc(demuxer, struct demuxer),
  ------------------
  |  |   26|   215k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|   215k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   215k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3305|   215k|        .d_user = demuxer,
 3306|   215k|        .after_seek = true, // (assumed identical to initial demuxer state)
 3307|   215k|        .after_seek_to_start = true,
 3308|   215k|        .highest_av_pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|   215k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3309|   215k|        .seeking_in_progress = MP_NOPTS_VALUE,
  ------------------
  |  |   38|   215k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3310|   215k|        .demux_ts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|   215k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3311|   215k|        .owns_stream = !params->external_stream,
 3312|   215k|    };
 3313|   215k|    mp_mutex_init(&in->lock);
 3314|   215k|    mp_cond_init(&in->wakeup);
 3315|       |
 3316|   215k|    *in->d_thread = *demuxer;
 3317|       |
 3318|   215k|    in->d_thread->metadata = talloc_zero(in->d_thread, struct mp_tags);
  ------------------
  |  |   27|   215k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   215k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   215k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3319|       |
 3320|   215k|    mp_dbg(log, "Trying demuxer: %s (force-level: %s)\n",
  ------------------
  |  |   76|   215k|#define mp_dbg(log, ...)        mp_msg(log, MSGL_DEBUG, __VA_ARGS__)
  ------------------
 3321|   215k|           desc->name, d_level(check));
 3322|       |
 3323|   215k|    if (stream)
  ------------------
  |  Branch (3323:9): [True: 214k, False: 436]
  ------------------
 3324|   214k|        stream_seek(stream, 0);
 3325|       |
 3326|   215k|    in->d_thread->params = params; // temporary during open()
 3327|   215k|    int ret = demuxer->desc->open(in->d_thread, check);
 3328|   215k|    if (ret >= 0) {
  ------------------
  |  Branch (3328:9): [True: 21.5k, False: 193k]
  ------------------
 3329|  21.5k|        in->d_thread->params = NULL;
 3330|  21.5k|        if (in->d_thread->filetype)
  ------------------
  |  Branch (3330:13): [True: 20.6k, False: 878]
  ------------------
 3331|  20.6k|            mp_verbose(log, "Detected file format: %s (%s)\n",
  ------------------
  |  |   75|  20.6k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
 3332|  21.5k|                       in->d_thread->filetype, desc->desc);
 3333|    878|        else
 3334|    878|            mp_verbose(log, "Detected file format: %s\n", desc->desc);
  ------------------
  |  |   75|    878|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
 3335|  21.5k|        if (!in->d_thread->seekable)
  ------------------
  |  Branch (3335:13): [True: 0, False: 21.5k]
  ------------------
 3336|      0|            mp_verbose(log, "Stream is not seekable.\n");
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
 3337|  21.5k|        if (!in->d_thread->seekable && opts->force_seekable) {
  ------------------
  |  Branch (3337:13): [True: 0, False: 21.5k]
  |  Branch (3337:40): [True: 0, False: 0]
  ------------------
 3338|      0|            mp_warn(log, "Not seekable, but enabling seeking on user request.\n");
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
 3339|      0|            in->d_thread->seekable = true;
 3340|      0|            in->d_thread->partially_seekable = true;
 3341|      0|        }
 3342|  21.5k|        demux_init_cuesheet(in->d_thread);
 3343|  21.5k|        demux_init_ccs(demuxer, opts);
 3344|  21.5k|        demux_convert_tags_charset(in->d_thread);
 3345|  21.5k|        demux_copy(in->d_user, in->d_thread);
 3346|  21.5k|        in->duration = in->d_thread->duration;
 3347|  21.5k|        demuxer_sort_chapters(demuxer);
 3348|  21.5k|        in->events = DEMUX_EVENT_ALL;
 3349|       |
 3350|  21.5k|        struct demuxer *sub = NULL;
 3351|  21.5k|        if (!(params && params->disable_timeline)) {
  ------------------
  |  Branch (3351:15): [True: 21.5k, False: 0]
  |  Branch (3351:25): [True: 0, False: 21.5k]
  ------------------
 3352|  21.5k|            struct timeline *tl = timeline_load(global, log, demuxer);
 3353|  21.5k|            if (tl) {
  ------------------
  |  Branch (3353:17): [True: 436, False: 21.1k]
  ------------------
 3354|    436|                struct demuxer_params params2 = {0};
 3355|    436|                params2.timeline = tl;
 3356|    436|                params2.is_top_level = params && params->is_top_level;
  ------------------
  |  Branch (3356:40): [True: 436, False: 0]
  |  Branch (3356:50): [True: 436, False: 0]
  ------------------
 3357|    436|                params2.stream_record = params && params->stream_record;
  ------------------
  |  Branch (3357:41): [True: 436, False: 0]
  |  Branch (3357:51): [True: 436, False: 0]
  ------------------
 3358|    436|                sub =
 3359|    436|                    open_given_type(global, log, &demuxer_desc_timeline,
 3360|    436|                                    NULL, sinfo, &params2, DEMUX_CHECK_FORCE);
 3361|    436|                if (sub) {
  ------------------
  |  Branch (3361:21): [True: 436, False: 0]
  ------------------
 3362|    436|                    in->can_cache = false;
 3363|    436|                    in->can_record = false;
 3364|    436|                } else {
 3365|      0|                    timeline_destroy(tl);
 3366|      0|                }
 3367|    436|            }
 3368|  21.5k|        }
 3369|       |
 3370|  21.5k|        switch_to_fresh_cache_range(in);
 3371|       |
 3372|  21.5k|        update_opts(demuxer);
 3373|       |
 3374|  21.5k|        demux_update(demuxer, MP_NOPTS_VALUE);
  ------------------
  |  |   38|  21.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3375|       |
 3376|  21.5k|        demuxer = sub ? sub : demuxer;
  ------------------
  |  Branch (3376:19): [True: 436, False: 21.1k]
  ------------------
 3377|  21.5k|        return demuxer;
 3378|  21.5k|    }
 3379|       |
 3380|   193k|    demuxer->stream = NULL;
 3381|   193k|    demux_free(demuxer);
 3382|   193k|    return NULL;
 3383|   215k|}
demux.c:demux_init_cuesheet:
 3177|  21.5k|{
 3178|  21.5k|    if (demuxer->num_chapters)
  ------------------
  |  Branch (3178:9): [True: 467, False: 21.0k]
  ------------------
 3179|    467|        return;
 3180|       |
 3181|  21.0k|    struct sh_stream *sh = demuxer->in->metadata_stream;
 3182|  21.0k|    char *cue = mp_tags_get_str(demuxer->metadata, "cuesheet");
 3183|  21.0k|    if (!cue && sh)
  ------------------
  |  Branch (3183:9): [True: 21.0k, False: 0]
  |  Branch (3183:17): [True: 19.8k, False: 1.24k]
  ------------------
 3184|  19.8k|        cue = mp_tags_get_str(sh->tags, "cuesheet");
 3185|  21.0k|    if (!cue)
  ------------------
  |  Branch (3185:9): [True: 21.0k, False: 0]
  ------------------
 3186|  21.0k|        return;
 3187|       |
 3188|      0|    struct cue_file *f = mp_parse_cue(bstr0(cue));
 3189|      0|    if (f) {
  ------------------
  |  Branch (3189:9): [True: 0, False: 0]
  ------------------
 3190|      0|        if (mp_check_embedded_cue(f) < 0) {
  ------------------
  |  Branch (3190:13): [True: 0, False: 0]
  ------------------
 3191|      0|            MP_WARN(demuxer, "Embedded cue sheet references more than one file. "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3192|      0|                    "Ignoring it.\n");
 3193|      0|        } else {
 3194|      0|            for (int n = 0; n < f->num_tracks; n++) {
  ------------------
  |  Branch (3194:29): [True: 0, False: 0]
  ------------------
 3195|      0|                struct cue_track *t = &f->tracks[n];
 3196|      0|                int idx = demuxer_add_chapter(demuxer, "", t->start, -1);
 3197|      0|                mp_tags_merge(demuxer->chapters[idx].metadata, t->tags);
 3198|      0|            }
 3199|      0|        }
 3200|      0|        talloc_free(f);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 3201|      0|    }
 3202|      0|}
demux.c:demux_init_ccs:
 3225|  21.5k|{
 3226|  21.5k|    struct demux_internal *in = demuxer->in;
 3227|  21.5k|    if (!opts->create_ccs)
  ------------------
  |  Branch (3227:9): [True: 21.5k, False: 0]
  ------------------
 3228|  21.5k|        return;
 3229|      0|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 3230|      0|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3230:21): [True: 0, False: 0]
  ------------------
 3231|      0|        struct sh_stream *sh = in->streams[n];
 3232|      0|        if (sh->type == STREAM_VIDEO && !sh->attached_picture)
  ------------------
  |  Branch (3232:13): [True: 0, False: 0]
  |  Branch (3232:41): [True: 0, False: 0]
  ------------------
 3233|      0|            demuxer_get_cc_track_locked(sh);
 3234|      0|    }
 3235|      0|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 3236|      0|}
demux.c:demux_convert_tags_charset:
 4664|  21.5k|{
 4665|  21.5k|    struct demux_internal *in = demuxer->in;
 4666|       |
 4667|  21.5k|    char *cp = demuxer->opts->meta_cp;
 4668|  21.5k|    if (!cp || mp_charset_is_utf8(cp))
  ------------------
  |  Branch (4668:9): [True: 0, False: 21.5k]
  |  Branch (4668:16): [True: 0, False: 21.5k]
  ------------------
 4669|      0|        return;
 4670|       |
 4671|  21.5k|    char *data = talloc_strdup(NULL, "");
  ------------------
  |  |   50|  21.5k|#define talloc_strdup                   ta_xstrdup
  ------------------
 4672|  21.5k|    visit_meta(demuxer, &data, visit_detect);
 4673|       |
 4674|  21.5k|    in->meta_charset = (char *)mp_charset_guess(in, in->log, bstr0(data), cp, 0);
 4675|  21.5k|    if (in->meta_charset && !mp_charset_is_utf8(in->meta_charset)) {
  ------------------
  |  Branch (4675:9): [True: 21.5k, False: 0]
  |  Branch (4675:29): [True: 623, False: 20.9k]
  ------------------
 4676|    623|        MP_INFO(demuxer, "Using tag charset: %s\n", in->meta_charset);
  ------------------
  |  |   87|    623|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    623|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 4677|    623|        visit_meta(demuxer, demuxer, visit_convert);
 4678|    623|    }
 4679|       |
 4680|  21.5k|    talloc_free(data);
  ------------------
  |  |   47|  21.5k|#define talloc_free                     ta_free
  ------------------
 4681|  21.5k|}
demux.c:visit_meta:
 4618|  22.1k|{
 4619|  22.1k|    struct demux_internal *in = demuxer->in;
 4620|       |
 4621|  50.0k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (4621:21): [True: 27.8k, False: 22.1k]
  ------------------
 4622|  27.8k|        struct sh_stream *sh = in->streams[n];
 4623|       |
 4624|  27.8k|        visit(ctx, sh, &sh->title);
 4625|  27.8k|        visit_tags(ctx, visit, sh->tags);
 4626|  27.8k|    }
 4627|       |
 4628|   151k|    for (int n = 0; n < demuxer->num_chapters; n++)
  ------------------
  |  Branch (4628:21): [True: 129k, False: 22.1k]
  ------------------
 4629|   129k|        visit_tags(ctx, visit, demuxer->chapters[n].metadata);
 4630|       |
 4631|  22.1k|    visit_tags(ctx, visit, demuxer->metadata);
 4632|  22.1k|}
demux.c:visit_tags:
 4611|   179k|{
 4612|   313k|    for (int n = 0; n < (tags ? tags->num_keys : 0); n++)
  ------------------
  |  Branch (4612:21): [True: 134k, False: 179k]
  |  Branch (4612:26): [True: 313k, False: 0]
  ------------------
 4613|   134k|        visit(ctx, tags, &tags->values[n]);
 4614|   179k|}
demux.c:visit_detect:
 4636|  94.4k|{
 4637|  94.4k|    char **all = ctx;
 4638|       |
 4639|  94.4k|    if (*s)
  ------------------
  |  Branch (4639:9): [True: 67.5k, False: 26.9k]
  ------------------
 4640|  67.5k|        *all = talloc_asprintf_append_buffer(*all, "%s\n", *s);
  ------------------
  |  |   64|  67.5k|#define talloc_asprintf_append_buffer   ta_talloc_asprintf_append_buffer
  ------------------
 4641|  94.4k|}
demux.c:visit_convert:
 4644|  67.5k|{
 4645|  67.5k|    struct demuxer *demuxer = ctx;
 4646|  67.5k|    struct demux_internal *in = demuxer->in;
 4647|       |
 4648|  67.5k|    if (!*s)
  ------------------
  |  Branch (4648:9): [True: 967, False: 66.5k]
  ------------------
 4649|    967|        return;
 4650|       |
 4651|  66.5k|    bstr data = bstr0(*s);
 4652|  66.5k|    bstr conv = mp_iconv_to_utf8(in->log, data, in->meta_charset,
 4653|  66.5k|                                 MP_ICONV_VERBOSE);
 4654|  66.5k|    if (conv.start && conv.start != data.start) {
  ------------------
  |  Branch (4654:9): [True: 66.5k, False: 0]
  |  Branch (4654:23): [True: 63.6k, False: 2.88k]
  ------------------
 4655|  63.6k|        char *ns = conv.start; // 0-termination is guaranteed
 4656|       |        // (The old string might not be an alloc, but if it is, it's a talloc
 4657|       |        // child, and will not leak, even if it stays allocated uselessly.)
 4658|  63.6k|        *s = ns;
 4659|  63.6k|        talloc_steal(ta, *s);
  ------------------
  |  |   38|  63.6k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  63.6k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 4660|  63.6k|    }
 4661|  66.5k|}
demux.c:demux_copy:
 2973|  21.5k|{
 2974|       |    // Note that we do as shallow copies as possible. We expect the data
 2975|       |    // that is not-copied (only referenced) to be immutable.
 2976|       |    // This implies e.g. that no chapters are added after initialization.
 2977|  21.5k|    dst->chapters = src->chapters;
 2978|  21.5k|    dst->num_chapters = src->num_chapters;
 2979|  21.5k|    dst->editions = src->editions;
 2980|  21.5k|    dst->num_editions = src->num_editions;
 2981|  21.5k|    dst->edition = src->edition;
 2982|  21.5k|    dst->attachments = src->attachments;
 2983|  21.5k|    dst->num_attachments = src->num_attachments;
 2984|  21.5k|    dst->matroska_data = src->matroska_data;
 2985|  21.5k|    dst->playlist = src->playlist;
 2986|  21.5k|    dst->seekable = src->seekable;
 2987|  21.5k|    dst->partially_seekable = src->partially_seekable;
 2988|  21.5k|    dst->filetype = src->filetype;
 2989|  21.5k|    dst->ts_resets_possible = src->ts_resets_possible;
 2990|  21.5k|    dst->fully_read = src->fully_read;
 2991|  21.5k|    dst->start_time = src->start_time;
 2992|  21.5k|    dst->duration = src->duration;
 2993|  21.5k|    dst->is_network = src->is_network;
 2994|  21.5k|    dst->is_streaming = src->is_streaming;
 2995|  21.5k|    dst->stream_origin = src->stream_origin;
 2996|  21.5k|    dst->priv = src->priv;
 2997|  21.5k|    dst->metadata = mp_tags_dup(dst, src->metadata);
 2998|  21.5k|}
demux.c:demuxer_sort_chapters:
 4099|  21.5k|{
 4100|  21.5k|    if (demuxer->num_chapters) {
  ------------------
  |  Branch (4100:9): [True: 467, False: 21.0k]
  ------------------
 4101|    467|        qsort(demuxer->chapters, demuxer->num_chapters,
 4102|    467|            sizeof(struct demux_chapter), chapter_compare);
 4103|    467|    }
 4104|  21.5k|}
demux.c:chapter_compare:
 4087|   272k|{
 4088|   272k|    struct demux_chapter *c1 = (void *)p1;
 4089|   272k|    struct demux_chapter *c2 = (void *)p2;
 4090|       |
 4091|   272k|    if (c1->pts > c2->pts)
  ------------------
  |  Branch (4091:9): [True: 0, False: 272k]
  ------------------
 4092|      0|        return 1;
 4093|   272k|    else if (c1->pts < c2->pts)
  ------------------
  |  Branch (4093:14): [True: 264k, False: 8.05k]
  ------------------
 4094|   264k|        return -1;
 4095|  8.05k|    return c1->original_index > c2->original_index ? 1 :-1; // never equal
  ------------------
  |  Branch (4095:12): [True: 0, False: 8.05k]
  ------------------
 4096|   272k|}
demux.c:switch_to_fresh_cache_range:
 3774|  83.9k|{
 3775|  83.9k|    if (!in->seekable_cache && in->current_range) {
  ------------------
  |  Branch (3775:9): [True: 83.9k, False: 0]
  |  Branch (3775:32): [True: 62.3k, False: 21.5k]
  ------------------
 3776|  62.3k|        clear_cached_range(in, in->current_range);
 3777|  62.3k|        return;
 3778|  62.3k|    }
 3779|       |
 3780|  21.5k|    struct demux_cached_range *range = talloc_ptrtype(NULL, range);
  ------------------
  |  |   34|  21.5k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  21.5k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  21.5k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3781|  21.5k|    *range = (struct demux_cached_range){
 3782|  21.5k|        .seek_start = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  21.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3783|  21.5k|        .seek_end = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  21.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 3784|  21.5k|    };
 3785|  21.5k|    MP_TARRAY_APPEND(in, in->ranges, in->num_ranges, range);
  ------------------
  |  |  105|  21.5k|    do {                                            \
  |  |  106|  21.5k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  21.5k|    do {                                            \
  |  |  |  |   97|  21.5k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  21.5k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  21.5k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  21.5k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 21.5k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  21.5k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  21.5k|    do {                                                        \
  |  |  |  |  |  |   89|  21.5k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  21.5k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  21.5k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  21.5k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  21.5k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  21.5k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  21.5k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  21.5k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  21.5k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  21.5k|        (idxvar)++;                                 \
  |  |  109|  21.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3786|  21.5k|    add_missing_streams(in, range);
 3787|       |
 3788|  21.5k|    switch_current_range(in, range);
 3789|  21.5k|}
demux.c:switch_current_range:
 3538|  21.5k|{
 3539|  21.5k|    struct demux_cached_range *old = in->current_range;
 3540|  21.5k|    mp_assert(old != range);
  ------------------
  |  |   41|  21.5k|#define mp_assert assert
  ------------------
 3541|       |
 3542|  21.5k|    set_current_range(in, range);
 3543|       |
 3544|  21.5k|    if (old) {
  ------------------
  |  Branch (3544:9): [True: 0, False: 21.5k]
  ------------------
 3545|       |        // Remove packets which can't be used when seeking back to the range.
 3546|      0|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3546:25): [True: 0, False: 0]
  ------------------
 3547|      0|            struct demux_queue *queue = old->streams[n];
 3548|       |
 3549|       |            // Remove all packets which cannot be involved in seeking.
 3550|      0|            while (queue->head && !queue->head->keyframe)
  ------------------
  |  Branch (3550:20): [True: 0, False: 0]
  |  Branch (3550:35): [True: 0, False: 0]
  ------------------
 3551|      0|                remove_head_packet(queue);
 3552|      0|        }
 3553|       |
 3554|       |        // Exclude weird corner cases that break resuming.
 3555|      0|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3555:25): [True: 0, False: 0]
  ------------------
 3556|      0|            struct demux_stream *ds = in->streams[n]->ds;
 3557|       |            // This is needed to resume or join the range at all.
 3558|      0|            if (ds->selected && !(ds->global_correct_dts ||
  ------------------
  |  Branch (3558:17): [True: 0, False: 0]
  |  Branch (3558:35): [True: 0, False: 0]
  ------------------
 3559|      0|                                  ds->global_correct_pos))
  ------------------
  |  Branch (3559:35): [True: 0, False: 0]
  ------------------
 3560|      0|            {
 3561|      0|                MP_VERBOSE(in, "discarding unseekable range due to stream %d\n", n);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3562|      0|                clear_cached_range(in, old);
 3563|      0|                break;
 3564|      0|            }
 3565|      0|        }
 3566|      0|    }
 3567|       |
 3568|       |    // Set up reading from new range (as well as writing to it).
 3569|  48.4k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3569:21): [True: 26.9k, False: 21.5k]
  ------------------
 3570|  26.9k|        struct demux_stream *ds = in->streams[n]->ds;
 3571|       |
 3572|  26.9k|        ds->queue = range->streams[n];
 3573|  26.9k|        ds->refreshing = false;
 3574|  26.9k|        ds->eof = false;
 3575|  26.9k|    }
 3576|       |
 3577|       |    // No point in keeping any junk (especially if old current_range is empty).
 3578|  21.5k|    free_empty_cached_ranges(in);
 3579|       |
 3580|       |    // The change detection doesn't work across ranges.
 3581|  21.5k|    in->force_metadata_update = true;
 3582|  21.5k|}
demux.c:set_current_range:
  555|  21.5k|{
  556|  21.5k|    in->current_range = range;
  557|       |
  558|       |    // Move to in->ranges[in->num_ranges-1] (for LRU sorting/invariant)
  559|  21.5k|    for (int n = 0; n < in->num_ranges; n++) {
  ------------------
  |  Branch (559:21): [True: 21.5k, False: 0]
  ------------------
  560|  21.5k|        if (in->ranges[n] == range) {
  ------------------
  |  Branch (560:13): [True: 21.5k, False: 0]
  ------------------
  561|  21.5k|            MP_TARRAY_REMOVE_AT(in->ranges, in->num_ranges, n);
  ------------------
  |  |  143|  21.5k|    do {                                            \
  |  |  144|  21.5k|        size_t at_ = (at);                          \
  |  |  145|  21.5k|        assert(at_ <= (idxvar));                    \
  |  |  146|  21.5k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  21.5k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  21.5k|        (idxvar)--;                                 \
  |  |  149|  21.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  562|  21.5k|            break;
  563|  21.5k|        }
  564|  21.5k|    }
  565|  21.5k|    MP_TARRAY_APPEND(in, in->ranges, in->num_ranges, range);
  ------------------
  |  |  105|  21.5k|    do {                                            \
  |  |  106|  21.5k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  21.5k|    do {                                            \
  |  |  |  |   97|  21.5k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  21.5k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  21.5k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  21.5k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 21.5k]
  |  |  |  |  ------------------
  |  |  |  |   99|  21.5k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  21.5k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  21.5k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  21.5k|        (idxvar)++;                                 \
  |  |  109|  21.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  566|  21.5k|}
demux.c:clear_reader_state:
  839|   277k|{
  840|   383k|    for (int n = 0; n < in->num_streams; n++)
  ------------------
  |  Branch (840:21): [True: 105k, False: 277k]
  ------------------
  841|   105k|        ds_clear_reader_state(in->streams[n]->ds, clear_back_state);
  842|   277k|    in->warned_queue_overflow = false;
  843|   277k|    in->d_user->filepos = -1; // implicitly synchronized
  844|   277k|    in->blocked = false;
  845|   277k|    in->need_back_seek = false;
  846|   277k|}
demux.c:clear_cached_range:
  750|   105k|{
  751|   238k|    for (int n = 0; n < range->num_streams; n++)
  ------------------
  |  Branch (751:21): [True: 132k, False: 105k]
  ------------------
  752|   132k|        clear_queue(range->streams[n]);
  753|       |
  754|   105k|    for (int n = 0; n < range->num_metadata; n++)
  ------------------
  |  Branch (754:21): [True: 0, False: 105k]
  ------------------
  755|      0|        talloc_free(range->metadata[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  756|   105k|    range->num_metadata = 0;
  757|       |
  758|   105k|    update_seek_ranges(range);
  759|   105k|}
demux.c:free_empty_cached_ranges:
  764|   663k|{
  765|   663k|    while (1) {
  ------------------
  |  Branch (765:12): [Folded - Ignored]
  ------------------
  766|   663k|        struct demux_cached_range *worst = NULL;
  767|       |
  768|   663k|        int end = in->num_ranges - 1;
  769|       |
  770|       |        // (Not set during early init or late destruction.)
  771|   663k|        if (in->current_range) {
  ------------------
  |  Branch (771:13): [True: 227k, False: 436k]
  ------------------
  772|   227k|            mp_assert(in->current_range && in->num_ranges > 0);
  ------------------
  |  |   41|   227k|#define mp_assert assert
  ------------------
  773|   227k|            mp_assert(in->current_range == in->ranges[in->num_ranges - 1]);
  ------------------
  |  |   41|   227k|#define mp_assert assert
  ------------------
  774|   227k|            end -= 1;
  775|   227k|        }
  776|       |
  777|   684k|        for (int n = end; n >= 0; n--) {
  ------------------
  |  Branch (777:27): [True: 21.5k, False: 663k]
  ------------------
  778|  21.5k|            struct demux_cached_range *range = in->ranges[n];
  779|  21.5k|            if (range->seek_start == MP_NOPTS_VALUE || !in->seekable_cache) {
  ------------------
  |  |   38|  43.0k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (779:17): [True: 21.5k, False: 0]
  |  Branch (779:56): [True: 0, False: 0]
  ------------------
  780|  21.5k|                clear_cached_range(in, range);
  781|  21.5k|                MP_TARRAY_REMOVE_AT(in->ranges, in->num_ranges, n);
  ------------------
  |  |  143|  21.5k|    do {                                            \
  |  |  144|  21.5k|        size_t at_ = (at);                          \
  |  |  145|  21.5k|        assert(at_ <= (idxvar));                    \
  |  |  146|  21.5k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  21.5k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  21.5k|        (idxvar)--;                                 \
  |  |  149|  21.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  782|  48.4k|                for (int i = 0; i < range->num_streams; i++)
  ------------------
  |  Branch (782:33): [True: 26.9k, False: 21.5k]
  ------------------
  783|  26.9k|                    talloc_free(range->streams[i]);
  ------------------
  |  |   47|  26.9k|#define talloc_free                     ta_free
  ------------------
  784|  21.5k|                talloc_free(range);
  ------------------
  |  |   47|  21.5k|#define talloc_free                     ta_free
  ------------------
  785|  21.5k|            } else {
  786|      0|                if (!worst || (range->seek_end - range->seek_start <
  ------------------
  |  Branch (786:21): [True: 0, False: 0]
  |  Branch (786:31): [True: 0, False: 0]
  ------------------
  787|      0|                               worst->seek_end - worst->seek_start))
  788|      0|                    worst = range;
  789|      0|            }
  790|  21.5k|        }
  791|       |
  792|   663k|        if (in->num_ranges <= MAX_SEEK_RANGES || !worst)
  ------------------
  |  |   33|  1.32M|#define MAX_SEEK_RANGES 10
  ------------------
  |  Branch (792:13): [True: 663k, False: 0]
  |  Branch (792:50): [True: 0, False: 0]
  ------------------
  793|   663k|            break;
  794|       |
  795|      0|        clear_cached_range(in, worst);
  796|      0|    }
  797|   663k|}
demux.c:queue_seek:
 3811|  62.3k|{
 3812|  62.3k|    if (seek_pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  62.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3812:9): [True: 0, False: 62.3k]
  ------------------
 3813|      0|        return false;
 3814|       |
 3815|  62.3k|    MP_VERBOSE(in, "queuing seek to %f%s\n", seek_pts,
  ------------------
  |  |   88|  62.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   124k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 62.3k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3816|  62.3k|               in->seeking ? " (cascade)" : "");
 3817|       |
 3818|  62.3k|    bool require_cache = flags & SEEK_CACHED;
  ------------------
  |  |   95|  62.3k|#define SEEK_CACHED   (1 << 3)      // allow packet cache seeks only
  ------------------
 3819|  62.3k|    flags &= ~(unsigned)SEEK_CACHED;
  ------------------
  |  |   95|  62.3k|#define SEEK_CACHED   (1 << 3)      // allow packet cache seeks only
  ------------------
 3820|       |
 3821|  62.3k|    bool set_backwards = flags & SEEK_SATAN;
  ------------------
  |  |   96|  62.3k|#define SEEK_SATAN    (1 << 4)      // enable backward demuxing
  ------------------
 3822|  62.3k|    flags &= ~(unsigned)SEEK_SATAN;
  ------------------
  |  |   96|  62.3k|#define SEEK_SATAN    (1 << 4)      // enable backward demuxing
  ------------------
 3823|       |
 3824|  62.3k|    bool block = flags & SEEK_BLOCK;
  ------------------
  |  |   98|  62.3k|#define SEEK_BLOCK    (1 << 6)      // upon successfully queued seek, block readers
  ------------------
 3825|  62.3k|    flags &= ~(unsigned)SEEK_BLOCK;
  ------------------
  |  |   98|  62.3k|#define SEEK_BLOCK    (1 << 6)      // upon successfully queued seek, block readers
  ------------------
 3826|       |
 3827|  62.3k|    struct demux_cached_range *cache_target =
 3828|  62.3k|        find_cache_seek_range(in, seek_pts, flags);
 3829|       |
 3830|  62.3k|    if (!cache_target) {
  ------------------
  |  Branch (3830:9): [True: 62.3k, False: 0]
  ------------------
 3831|  62.3k|        if (require_cache) {
  ------------------
  |  Branch (3831:13): [True: 0, False: 62.3k]
  ------------------
 3832|      0|            MP_VERBOSE(in, "Cached seek not possible.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3833|      0|            return false;
 3834|      0|        }
 3835|  62.3k|        if (!in->d_thread->seekable) {
  ------------------
  |  Branch (3835:13): [True: 0, False: 62.3k]
  ------------------
 3836|      0|            MP_WARN(in, "Cannot seek in this file.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3837|      0|            return false;
 3838|      0|        }
 3839|  62.3k|    }
 3840|       |
 3841|  62.3k|    in->eof = false;
 3842|  62.3k|    in->reading = false;
 3843|  62.3k|    in->back_demuxing = set_backwards;
 3844|       |
 3845|  62.3k|    clear_reader_state(in, clear_back_state);
 3846|       |
 3847|  62.3k|    in->blocked = block;
 3848|       |
 3849|  62.3k|    if (cache_target) {
  ------------------
  |  Branch (3849:9): [True: 0, False: 62.3k]
  ------------------
 3850|      0|        execute_cache_seek(in, cache_target, seek_pts, flags);
 3851|  62.3k|    } else {
 3852|  62.3k|        switch_to_fresh_cache_range(in);
 3853|       |
 3854|  62.3k|        in->seeking = true;
 3855|  62.3k|        in->seek_flags = flags;
 3856|  62.3k|        in->seek_pts = seek_pts;
 3857|  62.3k|    }
 3858|       |
 3859|   141k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3859:21): [True: 78.9k, False: 62.3k]
  ------------------
 3860|  78.9k|        struct demux_stream *ds = in->streams[n]->ds;
 3861|       |
 3862|  78.9k|        if (in->back_demuxing) {
  ------------------
  |  Branch (3862:13): [True: 0, False: 78.9k]
  ------------------
 3863|      0|            if (ds->back_seek_pos == MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3863:17): [True: 0, False: 0]
  ------------------
 3864|      0|                ds->back_seek_pos = seek_pts;
 3865|       |            // Process possibly cached packets.
 3866|      0|            back_demux_see_packets(in->streams[n]->ds);
 3867|      0|        }
 3868|       |
 3869|  78.9k|        wakeup_ds(ds);
 3870|  78.9k|    }
 3871|       |
 3872|  62.3k|    if (!in->threading && in->seeking)
  ------------------
  |  Branch (3872:9): [True: 62.3k, False: 0]
  |  Branch (3872:27): [True: 62.3k, False: 0]
  ------------------
 3873|  62.3k|        execute_seek(in);
 3874|       |
 3875|  62.3k|    return true;
 3876|  62.3k|}
demux.c:update_stream_selection_state:
  866|   189k|{
  867|   189k|    ds->eof = false;
  868|   189k|    ds->refreshing = false;
  869|       |
  870|       |    // We still have to go over the whole stream list to update ds->eager for
  871|       |    // other streams too, because they depend on other stream's selections.
  872|       |
  873|   189k|    bool any_av_streams = false;
  874|   189k|    bool any_streams = false;
  875|       |
  876|   453k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (876:21): [True: 263k, False: 189k]
  ------------------
  877|   263k|        struct demux_stream *s = in->streams[n]->ds;
  878|       |
  879|   263k|        s->still_image = s->sh->still_image;
  880|   263k|        s->eager = s->selected && !s->sh->attached_picture;
  ------------------
  |  Branch (880:20): [True: 117k, False: 146k]
  |  Branch (880:35): [True: 117k, False: 0]
  ------------------
  881|   263k|        if (s->eager && !s->still_image)
  ------------------
  |  Branch (881:13): [True: 117k, False: 146k]
  |  Branch (881:25): [True: 117k, False: 0]
  ------------------
  882|   117k|            any_av_streams |= s->type != STREAM_SUB;
  883|   263k|        any_streams |= s->selected;
  884|   263k|    }
  885|       |
  886|       |    // Subtitles are only eagerly read if there are no other eagerly read
  887|       |    // streams.
  888|   189k|    if (any_av_streams) {
  ------------------
  |  Branch (888:9): [True: 99.8k, False: 89.4k]
  ------------------
  889|   251k|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (889:25): [True: 151k, False: 99.8k]
  ------------------
  890|   151k|            struct demux_stream *s = in->streams[n]->ds;
  891|       |
  892|   151k|            if (s->type == STREAM_SUB)
  ------------------
  |  Branch (892:17): [True: 0, False: 151k]
  ------------------
  893|      0|                s->eager = false;
  894|   151k|        }
  895|  99.8k|    }
  896|       |
  897|   189k|    if (!any_streams)
  ------------------
  |  Branch (897:9): [True: 89.4k, False: 99.8k]
  ------------------
  898|  89.4k|        in->blocked = false;
  899|       |
  900|   189k|    ds_clear_reader_state(ds, true);
  901|       |
  902|       |    // Make sure any stream reselection or addition is reflected in the seek
  903|       |    // ranges, and also get rid of data that is not needed anymore (or
  904|       |    // rather, which can't be kept consistent). This has to happen after we've
  905|       |    // updated all the subtle state (like s->eager).
  906|   351k|    for (int n = 0; n < in->num_ranges; n++) {
  ------------------
  |  Branch (906:21): [True: 162k, False: 189k]
  ------------------
  907|   162k|        struct demux_cached_range *range = in->ranges[n];
  908|       |
  909|   162k|        if (!ds->selected)
  ------------------
  |  Branch (909:13): [True: 78.9k, False: 83.3k]
  ------------------
  910|  78.9k|            clear_queue(range->streams[ds->index]);
  911|       |
  912|   162k|        update_seek_ranges(range);
  913|   162k|    }
  914|       |
  915|   189k|    free_empty_cached_ranges(in);
  916|       |
  917|   189k|    wakeup_ds(ds);
  918|   189k|}
demux.c:refresh_track:
 3972|  83.3k|{
 3973|  83.3k|    struct demux_stream *ds = stream->ds;
 3974|  83.3k|    ref_pts = MP_ADD_PTS(ref_pts, -in->ts_offset);
  ------------------
  |  |   66|  83.3k|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|  83.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 78.7k, False: 4.65k]
  |  |  ------------------
  ------------------
 3975|       |
 3976|  83.3k|    if (in->back_demuxing)
  ------------------
  |  Branch (3976:9): [True: 0, False: 83.3k]
  ------------------
 3977|      0|        ds->back_seek_pos = ref_pts;
 3978|       |    // Avoid refresh seek for video streams except when immediately after a seek
 3979|       |    // to ensure a correct seek position.
 3980|  83.3k|    bool avoid_refresh = false;
 3981|   179k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3981:21): [True: 118k, False: 60.8k]
  ------------------
 3982|   118k|        struct demux_stream *ds_n = in->streams[n]->ds;
 3983|   118k|        if (ds_n->type == STREAM_VIDEO && ds_n->selected) {
  ------------------
  |  Branch (3983:13): [True: 39.2k, False: 79.1k]
  |  Branch (3983:43): [True: 22.5k, False: 16.7k]
  ------------------
 3984|  22.5k|            avoid_refresh = true;
 3985|  22.5k|            break;
 3986|  22.5k|        }
 3987|   118k|    }
 3988|  83.3k|    avoid_refresh = avoid_refresh && !(in->after_seek && !in->after_seek_to_start);
  ------------------
  |  Branch (3988:21): [True: 22.5k, False: 60.8k]
  |  Branch (3988:40): [True: 9.58k, False: 12.9k]
  |  Branch (3988:58): [True: 0, False: 9.58k]
  ------------------
 3989|       |    // Allow refresh seek for non-video streams, even if no packets have
 3990|       |    // ever been read yet or after seeking. This is necessary because:
 3991|       |    // - A-V sync targets may come from different demuxers, so enabling an external
 3992|       |    //   audio track for the first time can cause desync since a seek is not performed.
 3993|       |    // - If cache is enabled and a seek causes some new data to be cached, the demuxer
 3994|       |    //   is sought to the end of cache after cache joining. Switching track immediately
 3995|       |    //   after this also causes the same problem.
 3996|  83.3k|    if (!in->after_seek || (ds->type != STREAM_VIDEO && !avoid_refresh)) {
  ------------------
  |  Branch (3996:9): [True: 60.4k, False: 22.9k]
  |  Branch (3996:29): [True: 14.1k, False: 8.78k]
  |  Branch (3996:57): [True: 13.3k, False: 808]
  ------------------
 3997|  73.7k|        MP_VERBOSE(in, "refresh track %d (%s)\n", stream->index,
  ------------------
  |  |   88|  73.7k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  73.7k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3998|  73.7k|                   stream_type_name(ds->type));
 3999|  73.7k|        initiate_refresh_seek(in, ds, ref_pts);
 4000|  73.7k|    }
 4001|  83.3k|}
demux.c:initiate_refresh_seek:
 3900|  73.7k|{
 3901|  73.7k|    struct demuxer *demux = in->d_thread;
 3902|  73.7k|    bool seekable = demux->desc->seek && demux->seekable &&
  ------------------
  |  Branch (3902:21): [True: 73.7k, False: 0]
  |  Branch (3902:42): [True: 73.7k, False: 0]
  ------------------
 3903|  73.7k|                    !demux->partially_seekable;
  ------------------
  |  Branch (3903:21): [True: 73.7k, False: 0]
  ------------------
 3904|       |
 3905|  73.7k|    bool normal_seek = true;
 3906|  73.7k|    bool refresh_possible = true;
 3907|   175k|    for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3907:21): [True: 102k, False: 73.7k]
  ------------------
 3908|   102k|        struct demux_stream *ds = in->streams[n]->ds;
 3909|       |
 3910|   102k|        if (!ds->selected)
  ------------------
  |  Branch (3910:13): [True: 16.7k, False: 85.4k]
  ------------------
 3911|  16.7k|            continue;
 3912|       |
 3913|  85.4k|        if (ds->type == STREAM_VIDEO || ds->type == STREAM_AUDIO)
  ------------------
  |  Branch (3913:13): [True: 12.9k, False: 72.5k]
  |  Branch (3913:41): [True: 72.5k, False: 0]
  ------------------
 3914|  85.4k|            start_ts = MP_PTS_MIN(start_ts, ds->base_ts);
  ------------------
  |  |   63|  85.4k|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|   170k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 85.4k]
  |  |  |  |  |  Branch (44:23): [True: 84.4k, False: 1.03k]
  |  |  |  |  |  Branch (44:29): [True: 85.4k, False: 0]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 84.4k, False: 1.03k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3915|       |
 3916|       |        // If there were no other streams selected, we can use a normal seek.
 3917|  85.4k|        normal_seek &= stream == ds;
 3918|       |
 3919|  85.4k|        refresh_possible &= ds->queue->correct_dts || ds->queue->correct_pos;
  ------------------
  |  Branch (3919:29): [True: 85.4k, False: 0]
  |  Branch (3919:55): [True: 0, False: 0]
  ------------------
 3920|  85.4k|    }
 3921|       |
 3922|  73.7k|    if (start_ts == MP_NOPTS_VALUE || !seekable)
  ------------------
  |  |   38|   147k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3922:9): [True: 72.7k, False: 1.03k]
  |  Branch (3922:39): [True: 0, False: 1.03k]
  ------------------
 3923|  72.7k|        return;
 3924|       |
 3925|  1.03k|    if (!normal_seek) {
  ------------------
  |  Branch (3925:9): [True: 0, False: 1.03k]
  ------------------
 3926|      0|        if (!refresh_possible) {
  ------------------
  |  Branch (3926:13): [True: 0, False: 0]
  ------------------
 3927|      0|            MP_VERBOSE(in, "can't issue refresh seek\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3928|      0|            return;
 3929|      0|        }
 3930|       |
 3931|      0|        for (int n = 0; n < in->num_streams; n++) {
  ------------------
  |  Branch (3931:25): [True: 0, False: 0]
  ------------------
 3932|      0|            struct demux_stream *ds = in->streams[n]->ds;
 3933|       |
 3934|      0|            bool correct_pos = ds->queue->correct_pos;
 3935|      0|            bool correct_dts = ds->queue->correct_dts;
 3936|       |
 3937|       |            // We need to re-read all packets anyway, so discard the buffered
 3938|       |            // data. (In theory, we could keep the packets, and be able to use
 3939|       |            // it for seeking if partially read streams are deselected again,
 3940|       |            // but this causes other problems like queue overflows when
 3941|       |            // selecting a new stream.)
 3942|      0|            ds_clear_reader_queue_state(ds);
 3943|      0|            clear_queue(ds->queue);
 3944|       |
 3945|       |            // Streams which didn't have any packets yet will return all packets,
 3946|       |            // other streams return packets only starting from the last position.
 3947|      0|            if (ds->selected && (ds->last_ret_pos != -1 ||
  ------------------
  |  Branch (3947:17): [True: 0, False: 0]
  |  Branch (3947:34): [True: 0, False: 0]
  ------------------
 3948|      0|                                 ds->last_ret_dts != MP_NOPTS_VALUE))
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3948:34): [True: 0, False: 0]
  ------------------
 3949|      0|            {
 3950|      0|                ds->refreshing = true;
 3951|      0|                ds->queue->correct_dts = correct_dts;
 3952|      0|                ds->queue->correct_pos = correct_pos;
 3953|      0|                ds->queue->last_pos = ds->last_ret_pos;
 3954|      0|                ds->queue->last_dts = ds->last_ret_dts;
 3955|      0|            }
 3956|       |
 3957|      0|            update_seek_ranges(in->current_range);
 3958|      0|        }
 3959|       |
 3960|      0|        start_ts -= 1.0; // small offset to get correct overlap
 3961|      0|    }
 3962|       |
 3963|  1.03k|    MP_VERBOSE(in, "refresh seek to %f\n", start_ts);
  ------------------
  |  |   88|  1.03k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.03k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3964|  1.03k|    in->seeking = true;
 3965|  1.03k|    in->seek_flags = SEEK_HR;
  ------------------
  |  |   97|  1.03k|#define SEEK_HR       (1 << 5)      // hr-seek (this is a weak hint only)
  ------------------
 3966|  1.03k|    in->seek_pts = start_ts;
 3967|  1.03k|}
demux.c:execute_trackswitch:
 2408|   160k|{
 2409|   160k|    in->tracks_switched = false;
 2410|       |
 2411|   160k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   160k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2412|       |
 2413|   160k|    if (in->d_thread->desc->switched_tracks)
  ------------------
  |  Branch (2413:9): [True: 160k, False: 225]
  ------------------
 2414|   160k|        in->d_thread->desc->switched_tracks(in->d_thread);
 2415|       |
 2416|   160k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   160k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2417|   160k|}
demux.c:wakeup_ds:
  852|  1.77M|{
  853|  1.77M|    if (ds->need_wakeup) {
  ------------------
  |  Branch (853:9): [True: 363k, False: 1.41M]
  ------------------
  854|   363k|        if (ds->wakeup_cb) {
  ------------------
  |  Branch (854:13): [True: 9.92k, False: 353k]
  ------------------
  855|  9.92k|            ds->wakeup_cb(ds->wakeup_cb_ctx);
  856|   353k|        } else if (ds->in->wakeup_cb) {
  ------------------
  |  Branch (856:20): [True: 5.70k, False: 347k]
  ------------------
  857|  5.70k|            ds->in->wakeup_cb(ds->in->wakeup_cb_ctx);
  858|  5.70k|        }
  859|   363k|        ds->need_wakeup = false;
  860|   363k|        mp_cond_signal(&ds->in->wakeup);
  861|   363k|    }
  862|  1.77M|}
demux.c:update_cache:
 4161|  1.65M|{
 4162|  1.65M|    struct demuxer *demuxer = in->d_thread;
 4163|  1.65M|    struct stream *stream = demuxer->stream;
 4164|       |
 4165|  1.65M|    int64_t now = mp_time_ns();
 4166|  1.65M|    int64_t diff = now - in->last_speed_query;
 4167|  1.65M|    bool do_update = diff >= MP_TIME_S_TO_NS(1) || !in->last_speed_query;
  ------------------
  |  |   59|  3.30M|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (4167:22): [True: 21.6k, False: 1.63M]
  |  Branch (4167:52): [True: 9, False: 1.63M]
  ------------------
 4168|       |
 4169|       |    // Don't lock while querying the stream.
 4170|  1.65M|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  1.65M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 4171|       |
 4172|  1.65M|    int64_t stream_size = -1;
 4173|  1.65M|    struct mp_tags *stream_metadata = NULL;
 4174|  1.65M|    if (stream) {
  ------------------
  |  Branch (4174:9): [True: 1.58M, False: 71.4k]
  ------------------
 4175|  1.58M|        if (do_update)
  ------------------
  |  Branch (4175:13): [True: 19.7k, False: 1.56M]
  ------------------
 4176|  19.7k|            stream_size = stream_get_size(stream);
 4177|  1.58M|        stream_control(stream, STREAM_CTRL_GET_METADATA, &stream_metadata);
 4178|  1.58M|    }
 4179|       |
 4180|  1.65M|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  1.65M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 4181|       |
 4182|  1.65M|    update_bytes_read(in);
 4183|       |
 4184|  1.65M|    if (do_update)
  ------------------
  |  Branch (4184:9): [True: 21.6k, False: 1.63M]
  ------------------
 4185|  21.6k|        in->stream_size = stream_size;
 4186|  1.65M|    if (stream_metadata) {
  ------------------
  |  Branch (4186:9): [True: 0, False: 1.65M]
  ------------------
 4187|      0|        add_timed_metadata(in, stream_metadata, NULL, MP_NOPTS_VALUE);
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 4188|      0|        talloc_free(stream_metadata);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 4189|      0|    }
 4190|       |
 4191|  1.65M|    in->next_cache_update = INT64_MAX;
 4192|       |
 4193|  1.65M|    if (do_update) {
  ------------------
  |  Branch (4193:9): [True: 21.6k, False: 1.63M]
  ------------------
 4194|  21.6k|        uint64_t bytes = in->cache_unbuffered_read_bytes;
 4195|  21.6k|        in->cache_unbuffered_read_bytes = 0;
 4196|  21.6k|        in->last_speed_query = now;
 4197|  21.6k|        double speed = bytes / (diff / (double)MP_TIME_S_TO_NS(1));
  ------------------
  |  |   59|  21.6k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
 4198|  21.6k|        in->bytes_per_second = 0.5 * in->speed_query_prev_sample +
 4199|  21.6k|                               0.5 * speed;
 4200|  21.6k|        in->speed_query_prev_sample = speed;
 4201|  21.6k|    }
 4202|       |    // The idea is to update as long as there is "activity".
 4203|  1.65M|    if (in->bytes_per_second)
  ------------------
  |  Branch (4203:9): [True: 1.49M, False: 155k]
  ------------------
 4204|  1.49M|        in->next_cache_update = now + MP_TIME_S_TO_NS(1) + MP_TIME_US_TO_NS(1);
  ------------------
  |  |   59|  1.49M|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
                      in->next_cache_update = now + MP_TIME_S_TO_NS(1) + MP_TIME_US_TO_NS(1);
  ------------------
  |  |   61|  1.49M|#define MP_TIME_US_TO_NS(us) ((us) * INT64_C(1000))
  ------------------
 4205|  1.65M|}
demux.c:dumper_close:
 4208|   215k|{
 4209|   215k|    if (in->dumper)
  ------------------
  |  Branch (4209:9): [True: 0, False: 215k]
  ------------------
 4210|      0|        mp_recorder_destroy(in->dumper);
 4211|   215k|    in->dumper = NULL;
 4212|   215k|    if (in->dumper_status == CONTROL_TRUE)
  ------------------
  |  |   69|   215k|#define CONTROL_TRUE 1
  ------------------
  |  Branch (4212:9): [True: 0, False: 215k]
  ------------------
 4213|      0|        in->dumper_status = CONTROL_FALSE; // make abort equal to success
  ------------------
  |  |   70|      0|#define CONTROL_FALSE 0
  ------------------
 4214|   215k|}
demux.c:find_cache_seek_range:
 3654|  62.3k|{
 3655|       |    // Note about queued low level seeks: in->seeking can be true here, and it
 3656|       |    // might come from a previous resume seek to the current range. If we end
 3657|       |    // up seeking into the current range (i.e. just changing time offset), the
 3658|       |    // seek needs to continue. Otherwise, we override the queued seek anyway.
 3659|  62.3k|    if ((flags & SEEK_FACTOR) || !in->seekable_cache)
  ------------------
  |  |   92|  62.3k|#define SEEK_FACTOR   (1 << 1)      // argument is in range [0,1]
  ------------------
  |  Branch (3659:9): [True: 0, False: 62.3k]
  |  Branch (3659:34): [True: 62.3k, False: 0]
  ------------------
 3660|  62.3k|        return NULL;
 3661|       |
 3662|      0|    struct demux_cached_range *res = NULL;
 3663|       |
 3664|      0|    for (int n = 0; n < in->num_ranges; n++) {
  ------------------
  |  Branch (3664:21): [True: 0, False: 0]
  ------------------
 3665|      0|        struct demux_cached_range *r = in->ranges[n];
 3666|      0|        if (r->seek_start != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (3666:13): [True: 0, False: 0]
  ------------------
 3667|      0|            MP_VERBOSE(in, "cached range %d: %f <-> %f (bof=%d, eof=%d)\n",
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3668|      0|                       n, r->seek_start, r->seek_end, r->is_bof, r->is_eof);
 3669|       |
 3670|      0|            if ((pts >= r->seek_start || r->is_bof) &&
  ------------------
  |  Branch (3670:18): [True: 0, False: 0]
  |  Branch (3670:42): [True: 0, False: 0]
  ------------------
 3671|      0|                (pts <= r->seek_end || r->is_eof))
  ------------------
  |  Branch (3671:18): [True: 0, False: 0]
  |  Branch (3671:40): [True: 0, False: 0]
  ------------------
 3672|      0|            {
 3673|      0|                MP_VERBOSE(in, "...using this range for in-cache seek.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 3674|      0|                res = r;
 3675|      0|                break;
 3676|      0|            }
 3677|      0|        }
 3678|      0|    }
 3679|       |
 3680|      0|    return res;
 3681|  62.3k|}
demux.c:compute_keyframe_times:
 1833|  1.25M|{
 1834|  1.25M|    struct demux_packet *start = pkt;
 1835|  1.25M|    double min = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.25M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 1836|  1.25M|    double max = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.25M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 1837|       |
 1838|  2.49M|    while (pkt) {
  ------------------
  |  Branch (1838:12): [True: 2.47M, False: 14.4k]
  ------------------
 1839|  2.47M|        if (pkt->keyframe && pkt != start)
  ------------------
  |  Branch (1839:13): [True: 2.47M, False: 513]
  |  Branch (1839:30): [True: 1.23M, False: 1.23M]
  ------------------
 1840|  1.23M|            break;
 1841|       |
 1842|  1.23M|        double ts = MP_PTS_OR_DEF(pkt->pts, pkt->dts);
  ------------------
  |  |   61|  1.23M|#define MP_PTS_OR_DEF(a, def) ((a) == MP_NOPTS_VALUE ? (def) : (a))
  |  |  ------------------
  |  |  |  |   38|  1.23M|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (61:32): [True: 82, False: 1.23M]
  |  |  ------------------
  ------------------
 1843|  1.23M|        if (pkt->segmented && ((pkt->start != MP_NOPTS_VALUE && ts < pkt->start) ||
  ------------------
  |  |   38|    544|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1843:13): [True: 272, False: 1.23M]
  |  Branch (1843:33): [True: 272, False: 0]
  |  Branch (1843:65): [True: 9, False: 263]
  ------------------
 1844|    272|                               (pkt->end != MP_NOPTS_VALUE && ts > pkt->end)))
  ------------------
  |  |   38|    526|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1844:33): [True: 263, False: 0]
  |  Branch (1844:63): [True: 0, False: 263]
  ------------------
 1845|      9|            ts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|      9|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 1846|       |
 1847|  1.23M|        min = MP_PTS_MIN(min, ts);
  ------------------
  |  |   63|  1.23M|#define MP_PTS_MIN(a, b) MPMIN(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   44|  2.47M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (44:22): [True: 0, False: 1.23M]
  |  |  |  |  |  Branch (44:23): [True: 1.23M, False: 513]
  |  |  |  |  |  Branch (44:29): [True: 82, False: 1.23M]
  |  |  |  |  |  Branch (44:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (44:41): [True: 1.23M, False: 513]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1848|  1.23M|        max = MP_PTS_MAX(max, ts);
  ------------------
  |  |   64|  1.23M|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|  2.47M|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 1.23M]
  |  |  |  |  |  Branch (43:23): [True: 1.23M, False: 513]
  |  |  |  |  |  Branch (43:29): [True: 82, False: 1.23M]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 82, False: 1.23M]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1849|       |
 1850|  1.23M|        pkt = pkt->next;
 1851|  1.23M|    }
 1852|       |
 1853|  1.25M|    if (out_kf_min)
  ------------------
  |  Branch (1853:9): [True: 1.25M, False: 0]
  ------------------
 1854|  1.25M|        *out_kf_min = min;
 1855|  1.25M|    if (out_kf_max)
  ------------------
  |  Branch (1855:9): [True: 0, False: 1.25M]
  ------------------
 1856|      0|        *out_kf_max = max;
 1857|  1.25M|    return pkt;
 1858|  1.25M|}
demux.c:update_bytes_read:
 4138|  72.3M|{
 4139|  72.3M|    struct demuxer *demuxer = in->d_thread;
 4140|       |
 4141|  72.3M|    int64_t new = in->slave_unbuffered_read_bytes;
 4142|  72.3M|    in->slave_unbuffered_read_bytes = 0;
 4143|       |
 4144|  72.3M|    int64_t new_seeks = 0;
 4145|       |
 4146|  72.3M|    struct stream *stream = demuxer->stream;
 4147|  72.3M|    if (stream) {
  ------------------
  |  Branch (4147:9): [True: 72.2M, False: 72.7k]
  ------------------
 4148|  72.2M|        new += stream->total_unbuffered_read_bytes;
 4149|  72.2M|        stream->total_unbuffered_read_bytes = 0;
 4150|  72.2M|        new_seeks += stream->total_stream_seeks;
 4151|  72.2M|        stream->total_stream_seeks = 0;
 4152|  72.2M|    }
 4153|       |
 4154|  72.3M|    in->cache_unbuffered_read_bytes += new;
 4155|  72.3M|    in->hack_unbuffered_read_bytes += new;
 4156|  72.3M|    in->byte_level_seeks += new_seeks;
 4157|  72.3M|}
demux.c:get_forward_buffered_bytes:
  457|  8.32M|{
  458|  8.32M|    if (!ds->reader_head)
  ------------------
  |  Branch (458:9): [True: 451k, False: 7.87M]
  ------------------
  459|   451k|        return 0;
  460|  7.87M|    return ds->queue->tail_cum_pos - ds->reader_head->cum_pos;
  461|  8.32M|}
demux.c:get_demux_sub_opts:
 4684|  75.5k|{
 4685|  75.5k|    if (!demuxer_list[index])
  ------------------
  |  Branch (4685:9): [True: 5.81k, False: 69.7k]
  ------------------
 4686|  5.81k|        return false;
 4687|  69.7k|    *sub = demuxer_list[index]->options;
 4688|  69.7k|    return true;
 4689|  75.5k|}

demux_cue.c:try_open_file:
  248|  24.4k|{
  249|  24.4k|    if (!demuxer->access_references)
  ------------------
  |  Branch (249:9): [True: 0, False: 24.4k]
  ------------------
  250|      0|        return -1;
  251|       |
  252|  24.4k|    struct stream *s = demuxer->stream;
  253|  24.4k|    if (check >= DEMUX_CHECK_UNSAFE) {
  ------------------
  |  Branch (253:9): [True: 24.4k, False: 0]
  ------------------
  254|  24.4k|        char probe[PROBE_SIZE];
  255|  24.4k|        int len = stream_read_peek(s, probe, sizeof(probe));
  256|  24.4k|        if (len < 1 || !mp_probe_cue((bstr){probe, len}))
  ------------------
  |  Branch (256:13): [True: 84, False: 24.4k]
  |  Branch (256:24): [True: 24.3k, False: 52]
  ------------------
  257|  24.4k|            return -1;
  258|  24.4k|    }
  259|     52|    struct priv *p = talloc_zero(demuxer, struct priv);
  ------------------
  |  |   27|     52|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|     52|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|     52|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  260|     52|    demuxer->priv = p;
  261|     52|    demuxer->fully_read = true;
  262|     52|    bstr data = stream_read_complete(s, p, 1000000);
  263|     52|    if (data.start == NULL)
  ------------------
  |  Branch (263:9): [True: 0, False: 52]
  ------------------
  264|      0|        return -1;
  265|       |
  266|     52|    struct demux_opts *opts = mp_get_config_group(p, demuxer->global, &demux_conf);
  267|     52|    const char *charset = mp_charset_guess(p, demuxer->log, data, opts->meta_cp, 0);
  268|     52|    if (charset && !mp_charset_is_utf8(charset)) {
  ------------------
  |  Branch (268:9): [True: 52, False: 0]
  |  Branch (268:20): [True: 36, False: 16]
  ------------------
  269|     36|        MP_INFO(demuxer, "Using CUE charset: %s\n", charset);
  ------------------
  |  |   87|     36|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     36|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  270|     36|        bstr utf8 = mp_iconv_to_utf8(demuxer->log, data, charset, MP_ICONV_VERBOSE);
  271|     36|        if (utf8.start && utf8.start != data.start) {
  ------------------
  |  Branch (271:13): [True: 36, False: 0]
  |  Branch (271:27): [True: 36, False: 0]
  ------------------
  272|     36|            ta_steal(data.start, utf8.start);
  ------------------
  |  |  100|     36|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  ------------------
  273|     36|            data = utf8;
  274|     36|        }
  275|     36|    }
  276|     52|    talloc_free(opts);
  ------------------
  |  |   47|     52|#define talloc_free                     ta_free
  ------------------
  277|       |
  278|     52|    p->f = mp_parse_cue(data);
  279|     52|    talloc_steal(p, p->f);
  ------------------
  |  |   38|     52|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|     52|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  280|     52|    if (!p->f) {
  ------------------
  |  Branch (280:9): [True: 49, False: 3]
  ------------------
  281|     49|        MP_ERR(demuxer, "error parsing input file!\n");
  ------------------
  |  |   85|     49|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     49|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  282|     49|        return -1;
  283|     49|    }
  284|       |
  285|      3|    demux_close_stream(demuxer);
  286|       |
  287|      3|    mp_tags_merge(demuxer->metadata, p->f->tags);
  288|      3|    return 0;
  289|     52|}
demux_cue.c:build_timeline:
  140|      3|{
  141|      3|    struct priv *p = tl->demuxer->priv;
  142|       |
  143|      3|    void *ctx = talloc_new(NULL);
  ------------------
  |  |   40|      3|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      3|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  144|       |
  145|      3|    add_source(tl, tl->demuxer);
  146|       |
  147|      3|    struct cue_track *tracks = NULL;
  148|      3|    size_t track_count = 0;
  149|       |
  150|      3|    for (size_t n = 0; n < p->f->num_tracks; n++) {
  ------------------
  |  Branch (150:24): [True: 0, False: 3]
  ------------------
  151|      0|        struct cue_track *track = &p->f->tracks[n];
  152|      0|        if (track->filename) {
  ------------------
  |  Branch (152:13): [True: 0, False: 0]
  ------------------
  153|      0|            MP_TARRAY_APPEND(ctx, tracks, track_count, *track);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  154|      0|        } else {
  155|      0|            MP_WARN(tl->demuxer, "No file specified for track entry %zd. "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  156|      0|                    "It will be removed\n", n + 1);
  157|      0|        }
  158|      0|    }
  159|       |
  160|      3|    if (track_count == 0) {
  ------------------
  |  Branch (160:9): [True: 3, False: 0]
  ------------------
  161|      3|        MP_ERR(tl, "CUE: no tracks found!\n");
  ------------------
  |  |   85|      3|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      3|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  162|      3|        goto out;
  163|      3|    }
  164|       |
  165|       |    // Remove duplicate file entries. This might be too sophisticated, since
  166|       |    // CUE files usually use either separate files for every single track, or
  167|       |    // only one file for all tracks.
  168|       |
  169|      0|    char **files = 0;
  170|      0|    size_t file_count = 0;
  171|       |
  172|      0|    for (size_t n = 0; n < track_count; n++) {
  ------------------
  |  Branch (172:24): [True: 0, False: 0]
  ------------------
  173|      0|        struct cue_track *track = &tracks[n];
  174|      0|        track->source = -1;
  175|      0|        for (size_t file = 0; file < file_count; file++) {
  ------------------
  |  Branch (175:31): [True: 0, False: 0]
  ------------------
  176|      0|            if (strcmp(files[file], track->filename) == 0) {
  ------------------
  |  Branch (176:17): [True: 0, False: 0]
  ------------------
  177|      0|                track->source = file;
  178|      0|                break;
  179|      0|            }
  180|      0|        }
  181|      0|        if (track->source == -1) {
  ------------------
  |  Branch (181:13): [True: 0, False: 0]
  ------------------
  182|      0|            file_count++;
  183|      0|            files = talloc_realloc(ctx, files, char *, file_count);
  ------------------
  |  |   33|      0|#define talloc_realloc                  ta_xrealloc
  |  |  ------------------
  |  |  |  |  144|      0|    (type *)ta_xrealloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count))
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  184|      0|            files[file_count - 1] = track->filename;
  185|      0|            track->source = file_count - 1;
  186|      0|        }
  187|      0|    }
  188|       |
  189|      0|    for (size_t i = 0; i < file_count; i++) {
  ------------------
  |  Branch (189:24): [True: 0, False: 0]
  ------------------
  190|      0|        if (!open_source(tl, files[i]))
  ------------------
  |  Branch (190:13): [True: 0, False: 0]
  ------------------
  191|      0|            goto out;
  192|      0|    }
  193|       |
  194|      0|    struct timeline_part *timeline = talloc_array_ptrtype(tl, timeline,
  ------------------
  |  |   36|      0|#define talloc_array_ptrtype            ta_xnew_array_ptrtype
  |  |  ------------------
  |  |  |  |  140|      0|#define ta_xnew_array_ptrtype(...)      ta_oom_g(ta_new_array_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  195|      0|                                                          track_count + 1);
  196|      0|    struct demux_chapter *chapters = talloc_array_ptrtype(tl, chapters,
  ------------------
  |  |   36|      0|#define talloc_array_ptrtype            ta_xnew_array_ptrtype
  |  |  ------------------
  |  |  |  |  140|      0|#define ta_xnew_array_ptrtype(...)      ta_oom_g(ta_new_array_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  197|      0|                                                          track_count);
  198|      0|    double starttime = 0;
  199|      0|    for (int i = 0; i < track_count; i++) {
  ------------------
  |  Branch (199:21): [True: 0, False: 0]
  ------------------
  200|      0|        struct demuxer *source = tl->sources[1 + tracks[i].source];
  201|      0|        double duration;
  202|      0|        if (i + 1 < track_count && tracks[i].source == tracks[i + 1].source) {
  ------------------
  |  Branch (202:13): [True: 0, False: 0]
  |  Branch (202:36): [True: 0, False: 0]
  ------------------
  203|      0|            duration = tracks[i + 1].start - tracks[i].start;
  204|      0|        } else {
  205|      0|            duration = source->duration;
  206|       |            // Two cases: 1) last track of a single-file cue, or 2) any track of
  207|       |            // a multi-file cue. We need to do this for 1) only because the
  208|       |            // timeline needs to be terminated with the length of the last
  209|       |            // track.
  210|      0|            duration -= tracks[i].start;
  211|      0|        }
  212|      0|        if (duration < 0) {
  ------------------
  |  Branch (212:13): [True: 0, False: 0]
  ------------------
  213|      0|            MP_WARN(tl, "CUE: Can't get duration of source file!\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  214|       |            // xxx: do something more reasonable
  215|      0|            duration = 0.0;
  216|      0|        }
  217|      0|        timeline[i] = (struct timeline_part) {
  218|      0|            .start = starttime,
  219|      0|            .end = starttime + duration,
  220|      0|            .source_start = tracks[i].start,
  221|      0|            .source = source,
  222|      0|        };
  223|      0|        chapters[i] = (struct demux_chapter) {
  224|      0|            .pts = timeline[i].start,
  225|      0|            .metadata = mp_tags_dup(tl, tracks[i].tags),
  226|      0|        };
  227|      0|        starttime = timeline[i].end;
  228|      0|    }
  229|       |
  230|      0|    struct timeline_par *par = talloc_ptrtype(tl, par);
  ------------------
  |  |   34|      0|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|      0|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  231|      0|    *par = (struct timeline_par){
  232|      0|        .parts = timeline,
  233|      0|        .num_parts = track_count,
  234|      0|        .track_layout = timeline[0].source,
  235|      0|    };
  236|       |
  237|      0|    tl->chapters = chapters;
  238|      0|    tl->num_chapters = track_count;
  239|      0|    MP_TARRAY_APPEND(tl, tl->pars, tl->num_pars, par);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  240|      0|    tl->meta = par->track_layout;
  241|      0|    tl->format = "cue";
  242|       |
  243|      3|out:
  244|      3|    talloc_free(ctx);
  ------------------
  |  |   47|      3|#define talloc_free                     ta_free
  ------------------
  245|      3|}
demux_cue.c:add_source:
   49|      3|{
   50|      3|    MP_TARRAY_APPEND(tl, tl->sources, tl->num_sources, d);
  ------------------
  |  |  105|      3|    do {                                            \
  |  |  106|      3|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      3|    do {                                            \
  |  |  |  |   97|      3|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      3|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      3|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      3|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 3, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      3|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      3|    do {                                                        \
  |  |  |  |  |  |   89|      3|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      3|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      3|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      3|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      3|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      3|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      3|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      3|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      3|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      3|        (idxvar)++;                                 \
  |  |  109|      3|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   51|      3|}

demux_disc.c:d_open:
  313|  25.0k|{
  314|  25.0k|    struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);
  ------------------
  |  |   27|  25.0k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  25.0k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  25.0k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  315|       |
  316|  25.0k|    if (check != DEMUX_CHECK_FORCE)
  ------------------
  |  Branch (316:9): [True: 25.0k, False: 0]
  ------------------
  317|  25.0k|        return -1;
  318|       |
  319|      0|    struct demuxer_params params = {
  320|      0|        .force_format = "+lavf",
  321|      0|        .external_stream = demuxer->stream,
  322|      0|        .stream_flags = demuxer->stream_origin,
  323|      0|    };
  324|       |
  325|      0|    struct stream *cur = demuxer->stream;
  326|      0|    const char *sname = "";
  327|      0|    if (cur->info)
  ------------------
  |  Branch (327:9): [True: 0, False: 0]
  ------------------
  328|      0|        sname = cur->info->name;
  329|       |
  330|      0|    p->is_cdda = strcmp(sname, "cdda") == 0;
  331|      0|    p->is_dvd = strcmp(sname, "dvdnav") == 0 ||
  ------------------
  |  Branch (331:17): [True: 0, False: 0]
  ------------------
  332|      0|                strcmp(sname, "ifo_dvdnav") == 0;
  ------------------
  |  Branch (332:17): [True: 0, False: 0]
  ------------------
  333|       |
  334|      0|    if (p->is_cdda)
  ------------------
  |  Branch (334:9): [True: 0, False: 0]
  ------------------
  335|      0|        params.force_format = "+rawaudio";
  336|       |
  337|      0|    char *t = NULL;
  338|      0|    stream_control(demuxer->stream, STREAM_CTRL_GET_DISC_NAME, &t);
  339|      0|    if (t) {
  ------------------
  |  Branch (339:9): [True: 0, False: 0]
  ------------------
  340|      0|        mp_tags_set_str(demuxer->metadata, "TITLE", t);
  341|      0|        talloc_free(t);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  342|      0|    }
  343|       |
  344|       |    // Initialize the playback time. We need to read _some_ data to get the
  345|       |    // correct stream-layer time (at least with libdvdnav).
  346|      0|    stream_read_peek(demuxer->stream, &(char){0}, 1);
  347|      0|    reset_pts(demuxer);
  348|       |
  349|      0|    p->slave = demux_open_url("-", &params, demuxer->cancel, demuxer->global);
  350|      0|    if (!p->slave)
  ------------------
  |  Branch (350:9): [True: 0, False: 0]
  ------------------
  351|      0|        return -1;
  352|       |
  353|       |    // Can be seekable even if the stream isn't.
  354|      0|    demuxer->seekable = true;
  355|       |
  356|      0|    add_dvd_streams(demuxer);
  357|      0|    add_streams(demuxer);
  358|      0|    add_stream_chapters(demuxer);
  359|      0|    add_stream_editions(demuxer);
  360|       |
  361|      0|    double len;
  362|      0|    if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) >= 1)
  ------------------
  |  Branch (362:9): [True: 0, False: 0]
  ------------------
  363|      0|        demuxer->duration = len;
  364|       |
  365|      0|    unsigned title;
  366|      0|    if (stream_control(demuxer->stream, STREAM_CTRL_GET_CURRENT_TITLE, &title) >= 1)
  ------------------
  |  Branch (366:9): [True: 0, False: 0]
  ------------------
  367|      0|        demuxer->edition = title;
  368|       |
  369|      0|    return 0;
  370|      0|}
demux_disc.c:d_close:
  373|  25.0k|{
  374|  25.0k|    struct priv *p = demuxer->priv;
  375|  25.0k|    demux_free(p->slave);
  376|  25.0k|}

demux_edl.c:try_open_file:
  624|  25.0k|{
  625|  25.0k|    if (!demuxer->access_references)
  ------------------
  |  Branch (625:9): [True: 0, False: 25.0k]
  ------------------
  626|      0|        return -1;
  627|       |
  628|  25.0k|    struct priv *p = talloc_zero(demuxer, struct priv);
  ------------------
  |  |   27|  25.0k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  25.0k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  25.0k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  629|  25.0k|    demuxer->priv = p;
  630|  25.0k|    demuxer->fully_read = true;
  631|       |
  632|  25.0k|    struct stream *s = demuxer->stream;
  633|  25.0k|    if (s->info && strcmp(s->info->name, "edl") == 0) {
  ------------------
  |  Branch (633:9): [True: 25.0k, False: 0]
  |  Branch (633:20): [True: 0, False: 25.0k]
  ------------------
  634|      0|        p->data = bstr0(s->path);
  635|      0|        return 0;
  636|      0|    }
  637|  25.0k|    if (check >= DEMUX_CHECK_UNSAFE) {
  ------------------
  |  Branch (637:9): [True: 25.0k, False: 0]
  ------------------
  638|  25.0k|        char header[sizeof(HEADER) - 1];
  639|  25.0k|        int len = stream_read_peek(s, header, sizeof(header));
  640|  25.0k|        if (len != strlen(HEADER) || memcmp(header, HEADER, len) != 0)
  ------------------
  |  |   38|  25.0k|#define HEADER "# mpv EDL v0\n"
  ------------------
                      if (len != strlen(HEADER) || memcmp(header, HEADER, len) != 0)
  ------------------
  |  |   38|  24.7k|#define HEADER "# mpv EDL v0\n"
  ------------------
  |  Branch (640:13): [True: 265, False: 24.7k]
  |  Branch (640:38): [True: 24.2k, False: 570]
  ------------------
  641|  24.4k|            return -1;
  642|  25.0k|    }
  643|    570|    p->data = stream_read_complete(s, demuxer, 1000000);
  644|    570|    if (p->data.start == NULL)
  ------------------
  |  Branch (644:9): [True: 0, False: 570]
  ------------------
  645|      0|        return -1;
  646|    570|    bstr_eatstart0(&p->data, HEADER);
  ------------------
  |  |   38|    570|#define HEADER "# mpv EDL v0\n"
  ------------------
  647|    570|    demux_close_stream(demuxer);
  648|    570|    return 0;
  649|    570|}
demux_edl.c:build_mpv_edl_timeline:
  588|    570|{
  589|    570|    struct priv *p = tl->demuxer->priv;
  590|       |
  591|    570|    struct tl_root *root = parse_edl(p->data, tl->log);
  592|    570|    if (!root) {
  ------------------
  |  Branch (592:9): [True: 8, False: 562]
  ------------------
  593|      8|        MP_ERR(tl, "Error in EDL.\n");
  ------------------
  |  |   85|      8|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      8|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  594|      8|        return;
  595|      8|    }
  596|       |
  597|    562|    bool all_dash = true;
  598|    562|    bool all_no_clip = true;
  599|    562|    bool all_single = true;
  600|       |
  601|    998|    for (int n = 0; n < root->num_pars; n++) {
  ------------------
  |  Branch (601:21): [True: 562, False: 436]
  ------------------
  602|    562|        struct tl_parts *parts = root->pars[n];
  603|    562|        fix_filenames(parts, tl->demuxer->filename);
  604|    562|        struct timeline_par *par = build_timeline(tl, root, parts);
  605|    562|        if (!par)
  ------------------
  |  Branch (605:13): [True: 126, False: 436]
  ------------------
  606|    126|            break;
  607|    436|        all_dash &= par->dash;
  608|    436|        all_no_clip &= par->no_clip;
  609|    436|        all_single &= par->num_parts == 1;
  610|    436|    }
  611|       |
  612|    562|    if (all_dash) {
  ------------------
  |  Branch (612:9): [True: 126, False: 436]
  ------------------
  613|    126|        tl->format = "dash";
  614|    436|    } else if (all_no_clip && all_single) {
  ------------------
  |  Branch (614:16): [True: 0, False: 436]
  |  Branch (614:31): [True: 0, False: 0]
  ------------------
  615|      0|        tl->format = "multi";
  616|    436|    } else {
  617|    436|        tl->format = "edl";
  618|    436|    }
  619|       |
  620|    562|    talloc_free(root);
  ------------------
  |  |   47|    562|#define talloc_free                     ta_free
  ------------------
  621|    562|}
demux_edl.c:parse_edl:
  174|    570|{
  175|    570|    struct tl_root *root = talloc_zero(NULL, struct tl_root);
  ------------------
  |  |   27|    570|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|    570|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    570|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  176|    570|    root->tags = talloc_zero(root, struct mp_tags);
  ------------------
  |  |   27|    570|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|    570|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    570|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  177|    570|    struct tl_parts *tl = add_part(root);
  178|   352k|    while (str.len) {
  ------------------
  |  Branch (178:12): [True: 351k, False: 562]
  ------------------
  179|   351k|        if (bstr_eatstart0(&str, "#")) {
  ------------------
  |  Branch (179:13): [True: 3.05k, False: 348k]
  ------------------
  180|  3.05k|            bstr_split_tok(str, "\n", &(bstr){0}, &str);
  181|  3.05k|            continue;
  182|  3.05k|        }
  183|   348k|        if (bstr_eatstart0(&str, "\n") || bstr_eatstart0(&str, ";"))
  ------------------
  |  Branch (183:13): [True: 274k, False: 74.7k]
  |  Branch (183:43): [True: 629, False: 74.1k]
  ------------------
  184|   274k|            continue;
  185|  74.1k|        bool is_header = bstr_eatstart0(&str, "!");
  186|  74.1k|        struct parse_ctx ctx = { .log = log };
  187|  74.1k|        int nparam = 0;
  188|  75.2k|        while (1) {
  ------------------
  |  Branch (188:16): [Folded - Ignored]
  ------------------
  189|  75.2k|            bstr name, val;
  190|       |            // Check if it's of the form "name=..."
  191|  75.2k|            int next = bstrcspn(str, "=%,;\n");
  192|  75.2k|            if (next > 0 && next < str.len && str.start[next] == '=') {
  ------------------
  |  Branch (192:17): [True: 75.2k, False: 35]
  |  Branch (192:29): [True: 74.6k, False: 545]
  |  Branch (192:47): [True: 962, False: 73.7k]
  ------------------
  193|    962|                name = bstr_splice(str, 0, next);
  194|    962|                str = bstr_cut(str, next + 1);
  195|  74.3k|            } else if (is_header) {
  ------------------
  |  Branch (195:24): [True: 0, False: 74.3k]
  ------------------
  196|      0|                const char *names[] = {"type"}; // implied name
  197|      0|                name = bstr0(nparam < 1 ? names[nparam] : "-");
  ------------------
  |  Branch (197:30): [True: 0, False: 0]
  ------------------
  198|  74.3k|            } else {
  199|  74.3k|                const char *names[] = {"file", "start", "length"}; // implied name
  200|  74.3k|                name = bstr0(nparam < 3 ? names[nparam] : "-");
  ------------------
  |  Branch (200:30): [True: 74.2k, False: 40]
  ------------------
  201|  74.3k|            }
  202|  75.2k|            if (bstr_eatstart0(&str, "%")) {
  ------------------
  |  Branch (202:17): [True: 0, False: 75.2k]
  ------------------
  203|      0|                int len = bstrtoll(str, &str, 0);
  204|      0|                if (!bstr_startswith0(str, "%") || (len > str.len - 1))
  ------------------
  |  Branch (204:21): [True: 0, False: 0]
  |  Branch (204:52): [True: 0, False: 0]
  ------------------
  205|      0|                    goto error;
  206|      0|                val = bstr_splice(str, 1, len + 1);
  207|      0|                str = bstr_cut(str, len + 1);
  208|  75.2k|            } else {
  209|  75.2k|                next = bstrcspn(str, ",;\n");
  210|  75.2k|                val = bstr_splice(str, 0, next);
  211|  75.2k|                str = bstr_cut(str, next);
  212|  75.2k|            }
  213|  75.2k|            if (ctx.num_params >= NUM_MAX_PARAMS) {
  ------------------
  |  |   72|  75.2k|#define NUM_MAX_PARAMS 20
  ------------------
  |  Branch (213:17): [True: 0, False: 75.2k]
  ------------------
  214|      0|                mp_err(log, "Too many parameters, ignoring '%.*s'.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  215|      0|                       BSTR_P(name));
  216|  75.2k|            } else {
  217|  75.2k|                ctx.param_names[ctx.num_params] = name;
  218|  75.2k|                ctx.param_vals[ctx.num_params] = val;
  219|  75.2k|                ctx.num_params += 1;
  220|  75.2k|            }
  221|  75.2k|            nparam++;
  222|  75.2k|            if (!bstr_eatstart0(&str, ","))
  ------------------
  |  Branch (222:17): [True: 74.1k, False: 1.11k]
  ------------------
  223|  74.1k|                break;
  224|  75.2k|        }
  225|  74.1k|        if (is_header) {
  ------------------
  |  Branch (225:13): [True: 0, False: 74.1k]
  ------------------
  226|      0|            bstr f_type = get_param(&ctx, "type");
  227|      0|            if (bstr_equals0(f_type, "mp4_dash")) {
  ------------------
  |  Branch (227:17): [True: 0, False: 0]
  ------------------
  228|      0|                tl->dash = true;
  229|      0|                tl->init_fragment_url = get_param0(&ctx, tl, "init");
  230|      0|            } else if (bstr_equals0(f_type, "no_clip")) {
  ------------------
  |  Branch (230:24): [True: 0, False: 0]
  ------------------
  231|      0|                tl->no_clip = true;
  232|      0|            } else if (bstr_equals0(f_type, "new_stream")) {
  ------------------
  |  Branch (232:24): [True: 0, False: 0]
  ------------------
  233|       |                // (Special case: ignore "redundant" headers at the start for
  234|       |                // general symmetry.)
  235|      0|                if (root->num_pars > 1 || tl->num_parts)
  ------------------
  |  Branch (235:21): [True: 0, False: 0]
  |  Branch (235:43): [True: 0, False: 0]
  ------------------
  236|      0|                    tl = add_part(root);
  237|      0|            } else if (bstr_equals0(f_type, "no_chapters")) {
  ------------------
  |  Branch (237:24): [True: 0, False: 0]
  ------------------
  238|      0|                tl->disable_chapters = true;
  239|      0|            } else if (bstr_equals0(f_type, "track_meta")) {
  ------------------
  |  Branch (239:24): [True: 0, False: 0]
  ------------------
  240|      0|                int index = get_param_int(&ctx, "index", -1);
  241|      0|                struct sh_stream *sh = index < 0 && tl->num_sh_meta
  ------------------
  |  Branch (241:40): [True: 0, False: 0]
  |  Branch (241:53): [True: 0, False: 0]
  ------------------
  242|      0|                    ? tl->sh_meta[tl->num_sh_meta - 1]
  243|      0|                    : get_meta(tl, index);
  244|      0|                sh->lang = get_param0(&ctx, sh, "lang");
  245|      0|                sh->title = get_param0(&ctx, sh, "title");
  246|      0|                sh->hls_bitrate = get_param_int(&ctx, "byterate", 0) * 8;
  247|      0|                bstr flags = get_param(&ctx, "flags");
  248|      0|                bstr flag;
  249|      0|                while (bstr_split_tok(flags, "+", &flag, &flags) || flag.len) {
  ------------------
  |  Branch (249:24): [True: 0, False: 0]
  |  Branch (249:69): [True: 0, False: 0]
  ------------------
  250|      0|                    if (bstr_equals0(flag, "default")) {
  ------------------
  |  Branch (250:25): [True: 0, False: 0]
  ------------------
  251|      0|                        sh->default_track = true;
  252|      0|                    } else if (bstr_equals0(flag, "forced")) {
  ------------------
  |  Branch (252:32): [True: 0, False: 0]
  ------------------
  253|      0|                        sh->forced_track = true;
  254|      0|                    } else {
  255|      0|                        mp_warn(log, "Unknown flag: '%.*s'\n", BSTR_P(flag));
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (73:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  256|      0|                    }
  257|      0|                }
  258|      0|            } else if (bstr_equals0(f_type, "delay_open")) {
  ------------------
  |  Branch (258:24): [True: 0, False: 0]
  ------------------
  259|      0|                struct sh_stream *sh = get_meta(tl, tl->num_sh_meta);
  260|      0|                bstr mt = get_param(&ctx, "media_type");
  261|      0|                if (bstr_equals0(mt, "video")) {
  ------------------
  |  Branch (261:21): [True: 0, False: 0]
  ------------------
  262|      0|                    sh->type = sh->codec->type = STREAM_VIDEO;
  263|      0|                } else if (bstr_equals0(mt, "audio")) {
  ------------------
  |  Branch (263:28): [True: 0, False: 0]
  ------------------
  264|      0|                    sh->type = sh->codec->type = STREAM_AUDIO;
  265|      0|                } else if (bstr_equals0(mt, "sub")) {
  ------------------
  |  Branch (265:28): [True: 0, False: 0]
  ------------------
  266|      0|                    sh->type = sh->codec->type = STREAM_SUB;
  267|      0|                } else {
  268|      0|                    mp_err(log, "Invalid or missing !delay_open media type.\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  269|      0|                    goto error;
  270|      0|                }
  271|      0|                sh->codec->codec = get_param0(&ctx, sh, "codec");
  272|      0|                if (!sh->codec->codec)
  ------------------
  |  Branch (272:21): [True: 0, False: 0]
  ------------------
  273|      0|                    sh->codec->codec = "null";
  274|      0|                sh->codec->disp_w = get_param_int(&ctx, "w", 0);
  275|      0|                sh->codec->disp_h = get_param_int(&ctx, "h", 0);
  276|      0|                sh->codec->fps = get_param_int(&ctx, "fps", 0);
  277|      0|                sh->codec->samplerate = get_param_int(&ctx, "samplerate", 0);
  278|      0|                tl->delay_open = true;
  279|      0|            } else if (bstr_equals0(f_type, "global_tags")) {
  ------------------
  |  Branch (279:24): [True: 0, False: 0]
  ------------------
  280|      0|                for (int n = 0; n < ctx.num_params; n++) {
  ------------------
  |  Branch (280:33): [True: 0, False: 0]
  ------------------
  281|      0|                    mp_tags_set_bstr(root->tags, ctx.param_names[n],
  282|      0|                                     ctx.param_vals[n]);
  283|      0|                }
  284|      0|                ctx.num_params = 0;
  285|      0|            } else {
  286|      0|                mp_err(log, "Unknown header: '%.*s'\n", BSTR_P(f_type));
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  287|      0|                goto error;
  288|      0|            }
  289|  74.1k|        } else {
  290|  74.1k|            struct tl_part p = { .length = -1 };
  291|  74.1k|            p.filename = get_param0(&ctx, tl, "file");
  292|  74.1k|            if (!p.filename || !p.filename[0]) {
  ------------------
  |  Branch (292:17): [True: 0, False: 74.1k]
  |  Branch (292:32): [True: 2, False: 74.1k]
  ------------------
  293|      2|                mp_err(log, "Missing filename in segment.'\n");
  ------------------
  |  |   72|      2|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  294|      2|                goto error;
  295|      2|            }
  296|  74.1k|            p.offset_set = get_param_time(&ctx, "start", &p.offset);
  297|  74.1k|            get_param_time(&ctx, "length", &p.length);
  298|  74.1k|            bstr ts = get_param(&ctx, "timestamps");
  299|  74.1k|            if (bstr_equals0(ts, "chapters")) {
  ------------------
  |  Branch (299:17): [True: 0, False: 74.1k]
  ------------------
  300|      0|                p.chapter_ts = true;
  301|  74.1k|            } else if (ts.start && !bstr_equals0(ts, "seconds")) {
  ------------------
  |  Branch (301:24): [True: 0, False: 74.1k]
  |  Branch (301:36): [True: 0, False: 0]
  ------------------
  302|      0|                mp_warn(log, "Unknown timestamp type: '%.*s'\n", BSTR_P(ts));
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (73:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  303|      0|            }
  304|  74.1k|            p.title = get_param0(&ctx, tl, "title");
  305|  74.1k|            bstr layout = get_param(&ctx, "layout");
  306|  74.1k|            if (layout.start) {
  ------------------
  |  Branch (306:17): [True: 0, False: 74.1k]
  ------------------
  307|      0|                if (bstr_equals0(layout, "this")) {
  ------------------
  |  Branch (307:21): [True: 0, False: 0]
  ------------------
  308|      0|                    p.is_layout = true;
  309|      0|                } else {
  310|      0|                    mp_warn(log, "Unknown layout param: '%.*s'\n", BSTR_P(layout));
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (73:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  311|      0|                }
  312|      0|            }
  313|  74.1k|            MP_TARRAY_APPEND(tl, tl->parts, tl->num_parts, p);
  ------------------
  |  |  105|  74.1k|    do {                                            \
  |  |  106|  74.1k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  74.1k|    do {                                            \
  |  |  |  |   97|  74.1k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  74.1k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  74.1k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  74.1k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.97k, False: 71.1k]
  |  |  |  |  ------------------
  |  |  |  |   99|  74.1k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.97k|    do {                                                        \
  |  |  |  |  |  |   89|  2.97k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.97k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.97k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.97k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.97k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.97k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.97k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  74.1k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  74.1k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  74.1k|        (idxvar)++;                                 \
  |  |  109|  74.1k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  314|  74.1k|        }
  315|  74.1k|        if (ctx.error)
  ------------------
  |  Branch (315:13): [True: 6, False: 74.1k]
  ------------------
  316|      6|            goto error;
  317|  75.1k|        for (int n = 0; n < ctx.num_params; n++) {
  ------------------
  |  Branch (317:25): [True: 998, False: 74.1k]
  ------------------
  318|    998|            mp_warn(log, "Unknown or duplicate parameter: '%.*s'\n",
  ------------------
  |  |   73|  1.99k|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (73:56): [True: 998, False: 0]
  |  |  ------------------
  ------------------
  319|    998|                    BSTR_P(ctx.param_names[n]));
  320|    998|        }
  321|  74.1k|    }
  322|    562|    mp_assert(root->num_pars);
  ------------------
  |  |   41|    562|#define mp_assert assert
  ------------------
  323|  1.12k|    for (int n = 0; n < root->num_pars; n++) {
  ------------------
  |  Branch (323:21): [True: 562, False: 562]
  ------------------
  324|    562|        if (root->pars[n]->num_parts < 1) {
  ------------------
  |  Branch (324:13): [True: 0, False: 562]
  ------------------
  325|      0|            mp_err(log, "EDL specifies no segments.'\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  326|      0|            goto error;
  327|      0|        }
  328|    562|    }
  329|    562|    return root;
  330|      8|error:
  331|      8|    mp_err(log, "EDL parsing failed.\n");
  ------------------
  |  |   72|      8|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  332|      8|    talloc_free(root);
  ------------------
  |  |   47|      8|#define talloc_free                     ta_free
  ------------------
  333|      8|    return NULL;
  334|    562|}
demux_edl.c:add_part:
  149|    570|{
  150|    570|    struct tl_parts *tl = talloc_zero(root, struct tl_parts);
  ------------------
  |  |   27|    570|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|    570|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    570|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  151|    570|    MP_TARRAY_APPEND(root, root->pars, root->num_pars, tl);
  ------------------
  |  |  105|    570|    do {                                            \
  |  |  106|    570|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    570|    do {                                            \
  |  |  |  |   97|    570|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    570|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    570|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    570|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 570, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|    570|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    570|    do {                                                        \
  |  |  |  |  |  |   89|    570|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    570|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    570|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    570|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    570|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    570|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    570|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    570|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    570|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    570|        (idxvar)++;                                 \
  |  |  109|    570|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  152|    570|    return tl;
  153|    570|}
demux_edl.c:get_param:
   86|   444k|{
   87|   444k|    bstr bname = bstr0(name);
   88|   449k|    for (int n = 0; n < ctx->num_params; n++) {
  ------------------
  |  Branch (88:21): [True: 79.1k, False: 370k]
  ------------------
   89|  79.1k|        if (bstr_equals(ctx->param_names[n], bname)) {
  ------------------
  |  Branch (89:13): [True: 74.2k, False: 4.92k]
  ------------------
   90|  74.2k|            bstr res = ctx->param_vals[n];
   91|  74.2k|            int count = ctx->num_params;
   92|  74.2k|            MP_TARRAY_REMOVE_AT(ctx->param_names, count, n);
  ------------------
  |  |  143|  74.2k|    do {                                            \
  |  |  144|  74.2k|        size_t at_ = (at);                          \
  |  |  145|  74.2k|        assert(at_ <= (idxvar));                    \
  |  |  146|  74.2k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  74.2k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  74.2k|        (idxvar)--;                                 \
  |  |  149|  74.2k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   93|  74.2k|            count = ctx->num_params;
   94|  74.2k|            MP_TARRAY_REMOVE_AT(ctx->param_vals, count, n);
  ------------------
  |  |  143|  74.2k|    do {                                            \
  |  |  144|  74.2k|        size_t at_ = (at);                          \
  |  |  145|  74.2k|        assert(at_ <= (idxvar));                    \
  |  |  146|  74.2k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  74.2k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  74.2k|        (idxvar)--;                                 \
  |  |  149|  74.2k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   95|  74.2k|            ctx->num_params -= 1;
   96|  74.2k|            if (!res.start)
  ------------------
  |  Branch (96:17): [True: 0, False: 74.2k]
  ------------------
   97|      0|                res = bstr0("");  // keep guarantees
   98|  74.2k|            return res;
   99|  74.2k|        }
  100|  79.1k|    }
  101|   370k|    return (bstr){0};
  102|   444k|}
demux_edl.c:get_param0:
  106|   148k|{
  107|   148k|    return bstrdup0(ta_ctx, get_param(ctx, name));
  108|   148k|}
demux_edl.c:get_param_time:
  132|   148k|{
  133|   148k|    bstr val = get_param(ctx, name);
  134|   148k|    if (val.start) {
  ------------------
  |  Branch (134:9): [True: 109, False: 148k]
  ------------------
  135|    109|        bstr rest;
  136|    109|        double time = bstrtod(val, &rest);
  137|    109|        if (!val.len || rest.len || !isfinite(time)) {
  ------------------
  |  Branch (137:13): [True: 0, False: 109]
  |  Branch (137:25): [True: 8, False: 101]
  |  Branch (137:37): [True: 0, False: 101]
  ------------------
  138|      8|            MP_ERR(ctx, "Invalid time string: '%.*s'\n", BSTR_P(val));
  ------------------
  |  |   85|      8|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     16|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 8, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  139|      8|            ctx->error = true;
  140|      8|            return false;
  141|      8|        }
  142|    101|        *t = time;
  143|    101|        return true;
  144|    109|    }
  145|   148k|    return false;
  146|   148k|}
demux_edl.c:fix_filenames:
  569|    562|{
  570|    562|    bstr proto = mp_split_proto(bstr0(source_path), NULL);
  571|       |    // Don't adjust self-expanding protocols
  572|    562|    if (!bstrcasecmp0(proto, "memory") || !bstrcasecmp0(proto, "lavf") ||
  ------------------
  |  Branch (572:9): [True: 562, False: 0]
  |  Branch (572:43): [True: 0, False: 0]
  ------------------
  573|    562|        !bstrcasecmp0(proto, "hex") || !bstrcasecmp0(proto, "edl"))
  ------------------
  |  Branch (573:9): [True: 0, False: 0]
  |  Branch (573:40): [True: 0, False: 0]
  ------------------
  574|    562|    {
  575|    562|        return;
  576|    562|    }
  577|      0|    struct bstr dirname = mp_dirname(source_path);
  578|      0|    for (int n = 0; n < parts->num_parts; n++) {
  ------------------
  |  Branch (578:21): [True: 0, False: 0]
  ------------------
  579|      0|        struct tl_part *part = &parts->parts[n];
  580|      0|        if (!mp_is_url(bstr0(part->filename))) {
  ------------------
  |  Branch (580:13): [True: 0, False: 0]
  ------------------
  581|      0|            part->filename =
  582|      0|                mp_path_join_bstr(parts, dirname, bstr0(part->filename));
  583|      0|        }
  584|      0|    }
  585|      0|}
demux_edl.c:build_timeline:
  403|    562|{
  404|    562|    struct timeline_par *tl = talloc_zero(root, struct timeline_par);
  ------------------
  |  |   27|    562|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|    562|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    562|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  405|    562|    MP_TARRAY_APPEND(root, root->pars, root->num_pars, tl);
  ------------------
  |  |  105|    562|    do {                                            \
  |  |  106|    562|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    562|    do {                                            \
  |  |  |  |   97|    562|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    562|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    562|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    562|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 562, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|    562|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    562|    do {                                                        \
  |  |  |  |  |  |   89|    562|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    562|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    562|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    562|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    562|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    562|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    562|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    562|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    562|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    562|        (idxvar)++;                                 \
  |  |  109|    562|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  406|       |
  407|    562|    tl->track_layout = NULL;
  408|    562|    tl->dash = parts->dash;
  409|    562|    tl->no_clip = parts->no_clip;
  410|    562|    tl->delay_open = parts->delay_open;
  411|       |
  412|       |    // There is no copy function for sh_stream, so just steal it.
  413|    562|    for (int n = 0; n < parts->num_sh_meta; n++) {
  ------------------
  |  Branch (413:21): [True: 0, False: 562]
  ------------------
  414|      0|        MP_TARRAY_APPEND(tl, tl->sh_meta, tl->num_sh_meta,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  415|      0|                         talloc_steal(tl, parts->sh_meta[n]));
  416|      0|        parts->sh_meta[n] = NULL;
  417|      0|    }
  418|    562|    parts->num_sh_meta = 0;
  419|       |
  420|    562|    if (parts->init_fragment_url && parts->init_fragment_url[0]) {
  ------------------
  |  Branch (420:9): [True: 0, False: 562]
  |  Branch (420:37): [True: 0, False: 0]
  ------------------
  421|      0|        MP_VERBOSE(root, "Opening init fragment...\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  422|      0|        stream_t *s = stream_create(parts->init_fragment_url,
  423|      0|                                    STREAM_READ | root->stream_origin,
  ------------------
  |  |   41|      0|#define STREAM_READ               0
  ------------------
  424|      0|                                    root->cancel, root->global);
  425|      0|        if (s) {
  ------------------
  |  Branch (425:13): [True: 0, False: 0]
  ------------------
  426|      0|            root->is_network |= s->is_network;
  427|      0|            root->is_streaming |= s->streaming;
  428|      0|            tl->init_fragment = stream_read_complete(s, tl, 1000000);
  429|      0|        }
  430|      0|        free_stream(s);
  431|      0|        if (!tl->init_fragment.len) {
  ------------------
  |  Branch (431:13): [True: 0, False: 0]
  ------------------
  432|      0|            MP_ERR(root, "Could not read init fragment.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  433|      0|            goto error;
  434|      0|        }
  435|      0|        struct demuxer_params params = {
  436|      0|            .init_fragment = tl->init_fragment,
  437|      0|            .stream_flags = root->stream_origin,
  438|      0|        };
  439|      0|        tl->track_layout = demux_open_url("memory://", &params, root->cancel,
  440|      0|                                          root->global);
  441|      0|        if (!tl->track_layout) {
  ------------------
  |  Branch (441:13): [True: 0, False: 0]
  ------------------
  442|      0|            MP_ERR(root, "Could not demux init fragment.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  443|      0|            goto error;
  444|      0|        }
  445|      0|        MP_TARRAY_APPEND(root, root->sources, root->num_sources, tl->track_layout);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  446|      0|    }
  447|       |
  448|    562|    tl->parts = talloc_array_ptrtype(tl, tl->parts, parts->num_parts);
  ------------------
  |  |   36|    562|#define talloc_array_ptrtype            ta_xnew_array_ptrtype
  |  |  ------------------
  |  |  |  |  140|    562|#define ta_xnew_array_ptrtype(...)      ta_oom_g(ta_new_array_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    562|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  449|    562|    double starttime = 0;
  450|  70.7k|    for (int n = 0; n < parts->num_parts; n++) {
  ------------------
  |  Branch (450:21): [True: 70.3k, False: 436]
  ------------------
  451|  70.3k|        struct tl_part *part = &parts->parts[n];
  452|  70.3k|        struct demuxer *source = NULL;
  453|       |
  454|  70.3k|        if (tl->dash) {
  ------------------
  |  Branch (454:13): [True: 0, False: 70.3k]
  ------------------
  455|      0|            part->offset = starttime;
  456|      0|            if (part->length <= 0)
  ------------------
  |  Branch (456:17): [True: 0, False: 0]
  ------------------
  457|      0|                MP_WARN(root, "Segment %d has unknown duration.\n", n);
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  458|      0|            if (part->offset_set)
  ------------------
  |  Branch (458:17): [True: 0, False: 0]
  ------------------
  459|      0|                MP_WARN(root, "Offsets are ignored.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  460|       |
  461|      0|            if (!tl->track_layout)
  ------------------
  |  Branch (461:17): [True: 0, False: 0]
  ------------------
  462|      0|                tl->track_layout = open_source(root, tl, part->filename);
  463|  70.3k|        } else if (tl->delay_open) {
  ------------------
  |  Branch (463:20): [True: 0, False: 70.3k]
  ------------------
  464|      0|            if (n == 0 && !part->offset_set) {
  ------------------
  |  Branch (464:17): [True: 0, False: 0]
  |  Branch (464:27): [True: 0, False: 0]
  ------------------
  465|      0|                part->offset = starttime;
  466|      0|                part->offset_set = true;
  467|      0|            }
  468|      0|            if (part->chapter_ts || (part->length < 0 && !tl->no_clip)) {
  ------------------
  |  Branch (468:17): [True: 0, False: 0]
  |  Branch (468:38): [True: 0, False: 0]
  |  Branch (468:58): [True: 0, False: 0]
  ------------------
  469|      0|                MP_ERR(root, "Invalid specification for delay_open stream.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  470|      0|                goto error;
  471|      0|            }
  472|  70.3k|        } else {
  473|  70.3k|            MP_VERBOSE(root, "Opening segment %d...\n", n);
  ------------------
  |  |   88|  70.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  70.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  474|       |
  475|  70.3k|            source = open_source(root, tl, part->filename);
  476|  70.3k|            if (!source)
  ------------------
  |  Branch (476:17): [True: 126, False: 70.2k]
  ------------------
  477|    126|                goto error;
  478|       |
  479|  70.2k|            resolve_timestamps(part, source);
  480|       |
  481|  70.2k|            double end_time = source->duration;
  482|  70.2k|            if (end_time >= 0)
  ------------------
  |  Branch (482:17): [True: 18.1k, False: 52.0k]
  ------------------
  483|  18.1k|                end_time += source->start_time;
  484|       |
  485|       |            // Unknown length => use rest of the file. If duration is unknown, make
  486|       |            // something up.
  487|  70.2k|            if (part->length < 0) {
  ------------------
  |  Branch (487:17): [True: 70.2k, False: 0]
  ------------------
  488|  70.2k|                if (end_time < 0) {
  ------------------
  |  Branch (488:21): [True: 52.0k, False: 18.1k]
  ------------------
  489|  52.0k|                    MP_WARN(root, "EDL: source file '%s' has unknown duration.\n",
  ------------------
  |  |   86|  52.0k|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  52.0k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  490|  52.0k|                            part->filename);
  491|  52.0k|                    end_time = 1;
  492|  52.0k|                }
  493|  70.2k|                part->length = end_time - part->offset;
  494|  70.2k|            } else if (end_time >= 0) {
  ------------------
  |  Branch (494:24): [True: 0, False: 0]
  ------------------
  495|      0|                double end_part = part->offset + part->length;
  496|      0|                if (end_part > end_time) {
  ------------------
  |  Branch (496:21): [True: 0, False: 0]
  ------------------
  497|      0|                    MP_WARN(root, "EDL: entry %d uses %f "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  498|      0|                            "seconds, but file has only %f seconds.\n",
  499|      0|                            n, end_part, end_time);
  500|      0|                }
  501|      0|            }
  502|       |
  503|  70.2k|            if (!parts->disable_chapters) {
  ------------------
  |  Branch (503:17): [True: 70.2k, False: 0]
  ------------------
  504|       |                // Add a chapter between each file.
  505|  70.2k|                struct demux_chapter ch = {
  506|  70.2k|                    .pts = starttime,
  507|  70.2k|                    .metadata = talloc_zero(tl, struct mp_tags),
  ------------------
  |  |   27|  70.2k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  70.2k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  70.2k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  508|  70.2k|                };
  509|  70.2k|                mp_tags_set_str(ch.metadata, "title",
  510|  70.2k|                                part->title ? part->title : part->filename);
  ------------------
  |  Branch (510:33): [True: 0, False: 70.2k]
  ------------------
  511|  70.2k|                MP_TARRAY_APPEND(root, root->chapters, root->num_chapters, ch);
  ------------------
  |  |  105|  70.2k|    do {                                            \
  |  |  106|  70.2k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  70.2k|    do {                                            \
  |  |  |  |   97|  70.2k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  70.2k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  70.2k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  70.2k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.80k, False: 67.4k]
  |  |  |  |  ------------------
  |  |  |  |   99|  70.2k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.80k|    do {                                                        \
  |  |  |  |  |  |   89|  2.80k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.80k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.80k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.80k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.80k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.80k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.80k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  70.2k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  70.2k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  70.2k|        (idxvar)++;                                 \
  |  |  109|  70.2k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  512|       |
  513|       |                // Also copy the source file's chapters for the relevant parts
  514|  70.2k|                copy_chapters(&root->chapters, &root->num_chapters, source,
  515|  70.2k|                              part->offset, part->length, starttime);
  516|  70.2k|            }
  517|  70.2k|        }
  518|       |
  519|  70.2k|        tl->parts[n] = (struct timeline_part) {
  520|  70.2k|            .start = starttime,
  521|  70.2k|            .end = starttime + part->length,
  522|  70.2k|            .source_start = part->offset,
  523|  70.2k|            .source = source,
  524|  70.2k|            .url = talloc_strdup(tl, part->filename),
  ------------------
  |  |   50|  70.2k|#define talloc_strdup                   ta_xstrdup
  ------------------
  525|  70.2k|        };
  526|       |
  527|  70.2k|        starttime = tl->parts[n].end;
  528|       |
  529|  70.2k|        if (source && !tl->track_layout && part->is_layout)
  ------------------
  |  Branch (529:13): [True: 70.2k, False: 0]
  |  Branch (529:23): [True: 70.2k, False: 0]
  |  Branch (529:44): [True: 0, False: 70.2k]
  ------------------
  530|      0|            tl->track_layout = source;
  531|       |
  532|  70.2k|        tl->num_parts++;
  533|  70.2k|    }
  534|       |
  535|    436|    if (tl->no_clip && tl->num_parts > 1)
  ------------------
  |  Branch (535:9): [True: 0, False: 436]
  |  Branch (535:24): [True: 0, False: 0]
  ------------------
  536|    436|        MP_WARN(root, "Multiple parts with no_clip. Undefined behavior ahead.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  537|       |
  538|    436|    if (!tl->track_layout) {
  ------------------
  |  Branch (538:9): [True: 436, False: 0]
  ------------------
  539|       |        // Use a heuristic to select the "broadest" part as layout.
  540|  63.0k|        for (int n = 0; n < parts->num_parts; n++) {
  ------------------
  |  Branch (540:25): [True: 62.6k, False: 436]
  ------------------
  541|  62.6k|            struct demuxer *s = tl->parts[n].source;
  542|  62.6k|            if (!s)
  ------------------
  |  Branch (542:17): [True: 0, False: 62.6k]
  ------------------
  543|      0|                continue;
  544|  62.6k|            if (!tl->track_layout ||
  ------------------
  |  Branch (544:17): [True: 436, False: 62.2k]
  ------------------
  545|  62.6k|                demux_get_num_stream(s) > demux_get_num_stream(tl->track_layout))
  ------------------
  |  Branch (545:17): [True: 382, False: 61.8k]
  ------------------
  546|    818|                tl->track_layout = s;
  547|  62.6k|        }
  548|    436|    }
  549|       |
  550|    436|    if (!tl->track_layout && !tl->delay_open)
  ------------------
  |  Branch (550:9): [True: 0, False: 436]
  |  Branch (550:30): [True: 0, False: 0]
  ------------------
  551|      0|        goto error;
  552|    436|    if (!root->meta)
  ------------------
  |  Branch (552:9): [True: 436, False: 0]
  ------------------
  553|    436|        root->meta = tl->track_layout;
  554|       |
  555|       |    // Not very sane, since demuxer fields are supposed to be treated read-only
  556|       |    // from outside, but happens to work in this case, so who cares.
  557|    436|    if (root->meta)
  ------------------
  |  Branch (557:9): [True: 436, False: 0]
  ------------------
  558|    436|        mp_tags_merge(root->meta->metadata, edl_root->tags);
  559|       |
  560|    436|    mp_assert(tl->num_parts == parts->num_parts);
  ------------------
  |  |   41|    436|#define mp_assert assert
  ------------------
  561|    436|    return tl;
  562|       |
  563|    126|error:
  564|    126|    root->num_pars = 0;
  565|    126|    return NULL;
  566|    436|}
demux_edl.c:open_source:
  338|  70.3k|{
  339|  3.07M|    for (int n = 0; n < tl->num_parts; n++) {
  ------------------
  |  Branch (339:21): [True: 3.05M, False: 16.1k]
  ------------------
  340|  3.05M|        struct demuxer *d = tl->parts[n].source;
  341|  3.05M|        if (d && d->filename && strcmp(d->filename, filename) == 0)
  ------------------
  |  Branch (341:13): [True: 3.05M, False: 0]
  |  Branch (341:18): [True: 3.05M, False: 0]
  |  Branch (341:33): [True: 54.1k, False: 3.00M]
  ------------------
  342|  54.1k|            return d;
  343|  3.05M|    }
  344|  16.1k|    struct demuxer_params params = {
  345|  16.1k|        .init_fragment = tl->init_fragment,
  346|  16.1k|        .stream_flags = root->stream_origin,
  347|  16.1k|    };
  348|  16.1k|    struct demuxer *d = demux_open_url(filename, &params, root->cancel,
  349|  16.1k|                                       root->global);
  350|  16.1k|    if (d) {
  ------------------
  |  Branch (350:9): [True: 16.0k, False: 126]
  ------------------
  351|  16.0k|        MP_TARRAY_APPEND(root, root->sources, root->num_sources, d);
  ------------------
  |  |  105|  16.0k|    do {                                            \
  |  |  106|  16.0k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  16.0k|    do {                                            \
  |  |  |  |   97|  16.0k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  16.0k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  16.0k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  16.0k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.25k, False: 13.7k]
  |  |  |  |  ------------------
  |  |  |  |   99|  16.0k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.25k|    do {                                                        \
  |  |  |  |  |  |   89|  2.25k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.25k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.25k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.25k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.25k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.25k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.25k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  16.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  16.0k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  16.0k|        (idxvar)++;                                 \
  |  |  109|  16.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  352|  16.0k|    } else {
  353|    126|        MP_ERR(root, "EDL: Could not open source file '%s'.\n", filename);
  ------------------
  |  |   85|    126|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    126|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  354|    126|    }
  355|  16.1k|    return d;
  356|  70.3k|}
demux_edl.c:resolve_timestamps:
  384|  70.2k|{
  385|  70.2k|    if (part->chapter_ts) {
  ------------------
  |  Branch (385:9): [True: 0, False: 70.2k]
  ------------------
  386|      0|        double start = demuxer_chapter_time(demuxer, part->offset);
  387|      0|        double length = part->length;
  388|      0|        double end = length;
  389|      0|        if (end >= 0)
  ------------------
  |  Branch (389:13): [True: 0, False: 0]
  ------------------
  390|      0|            end = demuxer_chapter_time(demuxer, part->offset + part->length);
  391|      0|        if (end >= 0 && start >= 0)
  ------------------
  |  Branch (391:13): [True: 0, False: 0]
  |  Branch (391:25): [True: 0, False: 0]
  ------------------
  392|      0|            length = end - start;
  393|      0|        part->offset = start;
  394|      0|        part->length = length;
  395|      0|    }
  396|  70.2k|    if (!part->offset_set)
  ------------------
  |  Branch (396:9): [True: 70.2k, False: 0]
  ------------------
  397|  70.2k|        part->offset = demuxer->start_time;
  398|  70.2k|}
demux_edl.c:copy_chapters:
  370|  70.2k|{
  371|  70.2k|    for (int n = 0; n < src->num_chapters; n++) {
  ------------------
  |  Branch (371:21): [True: 0, False: 70.2k]
  ------------------
  372|      0|        double time = demuxer_chapter_time(src, n);
  373|      0|        if (time >= start && time <= start + len) {
  ------------------
  |  Branch (373:13): [True: 0, False: 0]
  |  Branch (373:30): [True: 0, False: 0]
  ------------------
  374|      0|            struct demux_chapter ch = {
  375|      0|                .pts = dest_offset + time - start,
  376|      0|                .metadata = mp_tags_dup(*chapters, src->chapters[n].metadata),
  377|      0|            };
  378|      0|            MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  379|      0|        }
  380|      0|    }
  381|  70.2k|}

demux_lavf.c:demux_open_lavf:
  972|  24.4k|{
  973|  24.4k|    AVFormatContext *avfc = NULL;
  974|  24.4k|    AVDictionaryEntry *t = NULL;
  975|  24.4k|    float analyze_duration = 0;
  976|  24.4k|    lavf_priv_t *priv = talloc_zero(NULL, lavf_priv_t);
  ------------------
  |  |   27|  24.4k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  24.4k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  24.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  977|  24.4k|    AVDictionary *dopts = NULL;
  978|       |
  979|  24.4k|    demuxer->priv = priv;
  980|  24.4k|    priv->stream = demuxer->stream;
  981|       |
  982|  24.4k|    priv->opts = mp_get_config_group(priv, demuxer->global, &demux_lavf_conf);
  983|  24.4k|    struct demux_lavf_opts *lavfdopts = priv->opts;
  984|       |
  985|  24.4k|    if (lavf_check_file(demuxer, check) < 0)
  ------------------
  |  Branch (985:9): [True: 3.46k, False: 21.0k]
  ------------------
  986|  3.46k|        goto fail;
  987|       |
  988|  21.0k|    avfc = avformat_alloc_context();
  989|  21.0k|    if (!avfc)
  ------------------
  |  Branch (989:9): [True: 0, False: 21.0k]
  ------------------
  990|      0|        goto fail;
  991|       |
  992|  21.0k|    if (demuxer->opts->index_mode != 1)
  ------------------
  |  Branch (992:9): [True: 0, False: 21.0k]
  ------------------
  993|      0|        avfc->flags |= AVFMT_FLAG_IGNIDX;
  994|       |
  995|  21.0k|    if (lavfdopts->probesize) {
  ------------------
  |  Branch (995:9): [True: 0, False: 21.0k]
  ------------------
  996|      0|        if (av_opt_set_int(avfc, "probesize", lavfdopts->probesize, 0) < 0)
  ------------------
  |  Branch (996:13): [True: 0, False: 0]
  ------------------
  997|      0|            MP_ERR(demuxer, "couldn't set option probesize to %u\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  998|      0|                   lavfdopts->probesize);
  999|      0|    }
 1000|       |
 1001|  21.0k|    if (priv->format_hack.analyzeduration)
  ------------------
  |  Branch (1001:9): [True: 0, False: 21.0k]
  ------------------
 1002|      0|        analyze_duration = priv->format_hack.analyzeduration;
 1003|  21.0k|    if (lavfdopts->analyzeduration)
  ------------------
  |  Branch (1003:9): [True: 0, False: 21.0k]
  ------------------
 1004|      0|        analyze_duration = lavfdopts->analyzeduration;
 1005|  21.0k|    if (analyze_duration > 0) {
  ------------------
  |  Branch (1005:9): [True: 0, False: 21.0k]
  ------------------
 1006|      0|        if (av_opt_set_int(avfc, "analyzeduration",
  ------------------
  |  Branch (1006:13): [True: 0, False: 0]
  ------------------
 1007|      0|                           analyze_duration * AV_TIME_BASE, 0) < 0)
 1008|      0|            MP_ERR(demuxer, "demux_lavf, couldn't set option "
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1009|      0|                   "analyzeduration to %f\n", analyze_duration);
 1010|      0|    }
 1011|       |
 1012|  21.0k|    if (priv->format_hack.no_ext_picky) {
  ------------------
  |  Branch (1012:9): [True: 0, False: 21.0k]
  ------------------
 1013|      0|        bool user_set_ext_picky = false;
 1014|      0|        for (int i = 0; lavfdopts->avopts && lavfdopts->avopts[i * 2]; i++) {
  ------------------
  |  Branch (1014:25): [True: 0, False: 0]
  |  Branch (1014:46): [True: 0, False: 0]
  ------------------
 1015|      0|            if (bstr_startswith0(bstr0(lavfdopts->avopts[i * 2]), "extension_picky")) {
  ------------------
  |  Branch (1015:17): [True: 0, False: 0]
  ------------------
 1016|      0|                user_set_ext_picky = true;
 1017|      0|                break;
 1018|      0|            }
 1019|      0|        }
 1020|      0|        if (!user_set_ext_picky && av_dict_set(&dopts, "extension_picky", "0", 0) >= 0)
  ------------------
  |  Branch (1020:13): [True: 0, False: 0]
  |  Branch (1020:36): [True: 0, False: 0]
  ------------------
 1021|      0|            MP_VERBOSE(demuxer, "Option extension_picky=0 was set due to known FFmpeg bugs\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1022|      0|    }
 1023|       |
 1024|  21.0k|    if ((priv->avif_flags & AVFMT_NOFILE) || priv->format_hack.no_stream) {
  ------------------
  |  Branch (1024:9): [True: 0, False: 21.0k]
  |  Branch (1024:46): [True: 0, False: 21.0k]
  ------------------
 1025|      0|        mp_setup_av_network_options(&dopts, priv->avif->name,
 1026|      0|                                    demuxer->global, demuxer->log);
 1027|       |        // This might be incorrect.
 1028|      0|        demuxer->seekable = true;
 1029|  21.0k|    } else {
 1030|  21.0k|        void *buffer = av_malloc(lavfdopts->buffersize);
 1031|  21.0k|        if (!buffer)
  ------------------
  |  Branch (1031:13): [True: 0, False: 21.0k]
  ------------------
 1032|      0|            goto fail;
 1033|  21.0k|        priv->pb = avio_alloc_context(buffer, lavfdopts->buffersize, 0,
 1034|  21.0k|                                      demuxer, mp_read, NULL, mp_seek);
 1035|  21.0k|        if (!priv->pb) {
  ------------------
  |  Branch (1035:13): [True: 0, False: 21.0k]
  ------------------
 1036|      0|            av_free(buffer);
 1037|      0|            goto fail;
 1038|      0|        }
 1039|  21.0k|        priv->pb->read_seek = mp_read_seek;
 1040|  21.0k|        priv->pb->seekable = demuxer->seekable ? AVIO_SEEKABLE_NORMAL : 0;
  ------------------
  |  Branch (1040:30): [True: 21.0k, False: 0]
  ------------------
 1041|  21.0k|        avfc->pb = priv->pb;
 1042|  21.0k|        if (stream_control(priv->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0)
  ------------------
  |  Branch (1042:13): [True: 0, False: 21.0k]
  ------------------
 1043|      0|            demuxer->seekable = true;
 1044|  21.0k|        demuxer->seekable |= priv->format_hack.fully_read;
 1045|  21.0k|    }
 1046|       |
 1047|  21.0k|    if (matches_avinputformat_name(priv, "rtsp")) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 21.0k]
  ------------------
 1048|      0|        const char *transport = NULL;
 1049|      0|        switch (lavfdopts->rtsp_transport) {
  ------------------
  |  Branch (1049:17): [True: 0, False: 0]
  ------------------
 1050|      0|        case 1: transport = "udp";  break;
  ------------------
  |  Branch (1050:9): [True: 0, False: 0]
  ------------------
 1051|      0|        case 2: transport = "tcp";  break;
  ------------------
  |  Branch (1051:9): [True: 0, False: 0]
  ------------------
 1052|      0|        case 3: transport = "http"; break;
  ------------------
  |  Branch (1052:9): [True: 0, False: 0]
  ------------------
 1053|      0|        case 4: transport = "udp_multicast"; break;
  ------------------
  |  Branch (1053:9): [True: 0, False: 0]
  ------------------
 1054|      0|        }
 1055|      0|        if (transport)
  ------------------
  |  Branch (1055:13): [True: 0, False: 0]
  ------------------
 1056|      0|            av_dict_set(&dopts, "rtsp_transport", transport, 0);
 1057|      0|    }
 1058|       |
 1059|  21.0k|    guess_and_set_vobsub_name(demuxer, &dopts);
 1060|       |
 1061|  21.0k|    avfc->interrupt_callback = (AVIOInterruptCB){
 1062|  21.0k|        .callback = interrupt_cb,
 1063|  21.0k|        .opaque = demuxer,
 1064|  21.0k|    };
 1065|       |
 1066|  21.0k|    avfc->opaque = demuxer;
 1067|  21.0k|    if (demuxer->access_references) {
  ------------------
  |  Branch (1067:9): [True: 21.0k, False: 0]
  ------------------
 1068|  21.0k|        priv->default_io_open = avfc->io_open;
 1069|  21.0k|        avfc->io_open = nested_io_open;
 1070|  21.0k|        priv->default_io_close2 = avfc->io_close2;
 1071|  21.0k|        avfc->io_close2 = nested_io_close2;
 1072|  21.0k|    } else {
 1073|      0|        avfc->io_open = block_io_open;
 1074|      0|    }
 1075|       |
 1076|  21.0k|    mp_set_avdict(&dopts, lavfdopts->avopts);
 1077|       |
 1078|  21.0k|    if (av_dict_copy(&priv->av_opts, dopts, 0) < 0) {
  ------------------
  |  Branch (1078:9): [True: 0, False: 21.0k]
  ------------------
 1079|      0|        MP_ERR(demuxer, "av_dict_copy() failed\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1080|      0|        goto fail;
 1081|      0|    }
 1082|       |
 1083|  21.0k|    if (priv->format_hack.readall_on_no_streamseek && priv->pb &&
  ------------------
  |  Branch (1083:9): [True: 1.04k, False: 19.9k]
  |  Branch (1083:55): [True: 1.04k, False: 0]
  ------------------
 1084|  21.0k|        !priv->pb->seekable)
  ------------------
  |  Branch (1084:9): [True: 0, False: 1.04k]
  ------------------
 1085|      0|    {
 1086|      0|        MP_VERBOSE(demuxer, "Non-seekable demuxer pre-read hack...\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1087|       |        // Read incremental to avoid unnecessary large buffer sizes.
 1088|      0|        int r = 0;
 1089|      0|        for (int n = 16; n < 29; n++) {
  ------------------
  |  Branch (1089:26): [True: 0, False: 0]
  ------------------
 1090|      0|            r = stream_peek(priv->stream, 1 << n);
 1091|      0|            if (r < (1 << n))
  ------------------
  |  Branch (1091:17): [True: 0, False: 0]
  ------------------
 1092|      0|                break;
 1093|      0|        }
 1094|      0|        MP_VERBOSE(demuxer, "...did read %d bytes.\n", r);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1095|      0|    }
 1096|       |
 1097|  21.0k|    if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
  ------------------
  |  Branch (1097:9): [True: 822, False: 20.1k]
  ------------------
 1098|    822|        MP_ERR(demuxer, "avformat_open_input() failed\n");
  ------------------
  |  |   85|    822|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    822|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1099|    822|        goto fail;
 1100|    822|    }
 1101|       |
 1102|  20.1k|    mp_avdict_print_unset(demuxer->log, MSGL_V, dopts);
 1103|  20.1k|    av_dict_free(&dopts);
 1104|       |
 1105|  20.1k|    priv->avfc = avfc;
 1106|       |
 1107|  20.1k|    bool probeinfo = lavfdopts->probeinfo != 0;
 1108|  20.1k|    switch (lavfdopts->probeinfo) {
  ------------------
  |  Branch (1108:13): [True: 0, False: 20.1k]
  ------------------
 1109|      0|    case -2: probeinfo = priv->avfc->nb_streams == 0; break;
  ------------------
  |  Branch (1109:5): [True: 0, False: 20.1k]
  ------------------
 1110|  20.1k|    case -1: probeinfo = !priv->format_hack.skipinfo; break;
  ------------------
  |  Branch (1110:5): [True: 20.1k, False: 0]
  ------------------
 1111|  20.1k|    }
 1112|  20.1k|    if (demuxer->params && demuxer->params->skip_lavf_probing)
  ------------------
  |  Branch (1112:9): [True: 20.1k, False: 0]
  |  Branch (1112:28): [True: 0, False: 20.1k]
  ------------------
 1113|      0|        probeinfo = false;
 1114|  20.1k|    if (probeinfo) {
  ------------------
  |  Branch (1114:9): [True: 20.1k, False: 0]
  ------------------
 1115|  20.1k|        if (avformat_find_stream_info(avfc, NULL) < 0) {
  ------------------
  |  Branch (1115:13): [True: 517, False: 19.6k]
  ------------------
 1116|    517|            MP_ERR(demuxer, "av_find_stream_info() failed\n");
  ------------------
  |  |   85|    517|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    517|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1117|    517|            goto fail;
 1118|    517|        }
 1119|       |
 1120|  19.6k|        MP_VERBOSE(demuxer, "avformat_find_stream_info() finished after %"PRId64
  ------------------
  |  |   88|  19.6k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  19.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1121|  19.6k|                   " bytes.\n", stream_tell(priv->stream));
 1122|  19.6k|    }
 1123|       |
 1124|  21.8k|    for (int i = 0; i < avfc->nb_chapters; i++) {
  ------------------
  |  Branch (1124:21): [True: 2.13k, False: 19.6k]
  ------------------
 1125|  2.13k|        AVChapter *c = avfc->chapters[i];
 1126|  2.13k|        t = av_dict_get(c->metadata, "title", NULL, 0);
 1127|  2.13k|        int index = demuxer_add_chapter(demuxer, t ? t->value : "",
  ------------------
  |  Branch (1127:50): [True: 0, False: 2.13k]
  ------------------
 1128|  2.13k|                                        c->start * av_q2d(c->time_base), i);
 1129|  2.13k|        mp_tags_move_from_av_dictionary(demuxer->chapters[index].metadata, &c->metadata);
 1130|  2.13k|    }
 1131|       |
 1132|  19.6k|    add_new_streams(demuxer);
 1133|       |
 1134|  19.6k|    mp_tags_move_from_av_dictionary(demuxer->metadata, &avfc->metadata);
 1135|       |
 1136|  19.6k|    demuxer->ts_resets_possible =
 1137|  19.6k|        priv->avif_flags & (AVFMT_TS_DISCONT | AVFMT_NOTIMESTAMPS);
 1138|       |
 1139|  19.6k|    if (avfc->start_time != AV_NOPTS_VALUE)
  ------------------
  |  Branch (1139:9): [True: 1.76k, False: 17.9k]
  ------------------
 1140|  1.76k|        demuxer->start_time = avfc->start_time / (double)AV_TIME_BASE;
 1141|       |
 1142|  19.6k|    demuxer->fully_read = priv->format_hack.fully_read;
 1143|       |
 1144|  19.6k|#ifdef AVFMTCTX_UNSEEKABLE
 1145|  19.6k|    if (avfc->ctx_flags & AVFMTCTX_UNSEEKABLE)
  ------------------
  |  Branch (1145:9): [True: 0, False: 19.6k]
  ------------------
 1146|      0|        demuxer->seekable = false;
 1147|  19.6k|#endif
 1148|       |
 1149|  19.6k|    demuxer->is_network |= priv->format_hack.is_network;
 1150|  19.6k|    demuxer->seekable &= !priv->format_hack.no_seek;
 1151|       |
 1152|       |    // We initially prefer track durations over container durations because they
 1153|       |    // have a higher degree of precision over the container duration which are
 1154|       |    // only accurate to the 6th decimal place. This is probably a lavf bug.
 1155|  19.6k|    double total_duration = -1;
 1156|  19.6k|    double av_duration = -1;
 1157|  47.9k|    for (int n = 0; n < priv->avfc->nb_streams; n++) {
  ------------------
  |  Branch (1157:21): [True: 28.3k, False: 19.6k]
  ------------------
 1158|  28.3k|        AVStream *st = priv->avfc->streams[n];
 1159|  28.3k|        if (st->duration <= 0)
  ------------------
  |  Branch (1159:13): [True: 14.9k, False: 13.3k]
  ------------------
 1160|  14.9k|            continue;
 1161|  13.3k|        double f_duration = st->duration * av_q2d(st->time_base);
 1162|  13.3k|        total_duration = MPMAX(total_duration, f_duration);
  ------------------
  |  |   43|  13.3k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 4.47k, False: 8.84k]
  |  |  ------------------
  ------------------
 1163|  13.3k|        if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
  ------------------
  |  Branch (1163:13): [True: 6.90k, False: 6.40k]
  ------------------
 1164|  13.3k|            st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  ------------------
  |  Branch (1164:13): [True: 6.40k, False: 0]
  ------------------
 1165|  13.3k|            av_duration = MPMAX(av_duration, f_duration);
  ------------------
  |  |   43|  13.3k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 4.47k, False: 8.84k]
  |  |  ------------------
  ------------------
 1166|  13.3k|    }
 1167|  19.6k|    double duration = av_duration > 0 ? av_duration : total_duration;
  ------------------
  |  Branch (1167:23): [True: 7.15k, False: 12.5k]
  ------------------
 1168|  19.6k|    if (duration <= 0 && priv->avfc->duration > 0)
  ------------------
  |  Branch (1168:9): [True: 12.5k, False: 7.15k]
  |  Branch (1168:26): [True: 0, False: 12.5k]
  ------------------
 1169|      0|        duration = (double)priv->avfc->duration / AV_TIME_BASE;
 1170|  19.6k|    demuxer->duration = duration;
 1171|       |
 1172|  19.6k|    if (demuxer->duration < 0 && priv->format_hack.no_seek_on_no_duration)
  ------------------
  |  Branch (1172:9): [True: 12.5k, False: 7.15k]
  |  Branch (1172:34): [True: 0, False: 12.5k]
  ------------------
 1173|      0|        demuxer->seekable = false;
 1174|       |
 1175|       |    // In some cases, libavformat will export bogus bullshit timestamps anyway,
 1176|       |    // such as with mjpeg.
 1177|  19.6k|    if (priv->avif_flags & AVFMT_NOTIMESTAMPS) {
  ------------------
  |  Branch (1177:9): [True: 189, False: 19.4k]
  ------------------
 1178|    189|        MP_WARN(demuxer,
  ------------------
  |  |   86|    189|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    189|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1179|    189|                "This format is marked by FFmpeg as having no timestamps!\n"
 1180|    189|                "FFmpeg will likely make up its own broken timestamps. For\n"
 1181|    189|                "video streams you can correct this with:\n"
 1182|    189|                "    --no-correct-pts --container-fps-override=VALUE\n"
 1183|    189|                "with VALUE being the real framerate of the stream. You can\n"
 1184|    189|                "expect seeking and buffering estimation to be generally\n"
 1185|    189|                "broken as well.\n");
 1186|    189|    }
 1187|       |
 1188|  19.6k|    if (demuxer->fully_read) {
  ------------------
  |  Branch (1188:9): [True: 336, False: 19.3k]
  ------------------
 1189|    336|        demux_close_stream(demuxer);
 1190|    336|        if (priv->own_stream)
  ------------------
  |  Branch (1190:13): [True: 336, False: 0]
  ------------------
 1191|    336|            free_stream(priv->stream);
 1192|    336|        priv->own_stream = false;
 1193|    336|        priv->stream = NULL;
 1194|    336|    }
 1195|       |
 1196|  19.6k|    if (priv->stream) {
  ------------------
  |  Branch (1196:9): [True: 19.3k, False: 336]
  ------------------
 1197|  19.3k|        const char *sname = priv->stream->info->name;
 1198|  19.3k|        priv->is_dvd_bd = strcmp(sname, "dvdnav") == 0 ||
  ------------------
  |  Branch (1198:27): [True: 0, False: 19.3k]
  ------------------
 1199|  19.3k|                          strcmp(sname, "ifo_dvdnav") == 0 ||
  ------------------
  |  Branch (1199:27): [True: 0, False: 19.3k]
  ------------------
 1200|  19.3k|                          strcmp(sname, "bd") == 0 ||
  ------------------
  |  Branch (1200:27): [True: 0, False: 19.3k]
  ------------------
 1201|  19.3k|                          strcmp(sname, "bdnav") == 0 ||
  ------------------
  |  Branch (1201:27): [True: 0, False: 19.3k]
  ------------------
 1202|  19.3k|                          strcmp(sname, "bdmv/bluray") == 0;
  ------------------
  |  Branch (1202:27): [True: 0, False: 19.3k]
  ------------------
 1203|  19.3k|    }
 1204|       |
 1205|  19.6k|    return 0;
 1206|       |
 1207|  4.80k|fail:
 1208|  4.80k|    if (!priv->avfc)
  ------------------
  |  Branch (1208:9): [True: 4.28k, False: 517]
  ------------------
 1209|  4.28k|        avformat_free_context(avfc);
 1210|  4.80k|    av_dict_free(&dopts);
 1211|       |
 1212|  4.80k|    return -1;
 1213|  20.1k|}
demux_lavf.c:lavf_check_file:
  422|  24.4k|{
  423|  24.4k|    lavf_priv_t *priv = demuxer->priv;
  424|  24.4k|    struct demux_lavf_opts *lavfdopts = priv->opts;
  425|  24.4k|    struct stream *s = priv->stream;
  426|       |
  427|  24.4k|    priv->filename = remove_prefix(s->url, prefixes);
  428|       |
  429|  24.4k|    char *avdevice_format = NULL;
  430|  24.4k|    if (s->info && strcmp(s->info->name, "avdevice") == 0) {
  ------------------
  |  Branch (430:9): [True: 24.4k, False: 0]
  |  Branch (430:20): [True: 0, False: 24.4k]
  ------------------
  431|       |        // always require filename in the form "format:filename"
  432|      0|        char *sep = strchr(priv->filename, ':');
  433|      0|        if (!sep) {
  ------------------
  |  Branch (433:13): [True: 0, False: 0]
  ------------------
  434|      0|            MP_FATAL(demuxer, "Must specify filename in 'format:filename' form\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  435|      0|            return -1;
  436|      0|        }
  437|      0|        avdevice_format = talloc_strndup(priv, priv->filename,
  ------------------
  |  |   51|      0|#define talloc_strndup                  ta_xstrndup
  ------------------
  438|      0|                                         sep - priv->filename);
  439|      0|        priv->filename = sep + 1;
  440|      0|    }
  441|       |
  442|  24.4k|    char *mime_type = s->mime_type;
  443|  24.4k|    if (!lavfdopts->allow_mimetype || !mime_type)
  ------------------
  |  Branch (443:9): [True: 0, False: 24.4k]
  |  Branch (443:39): [True: 24.4k, False: 0]
  ------------------
  444|  24.4k|        mime_type = "";
  445|       |
  446|  24.4k|    const AVInputFormat *forced_format = NULL;
  447|  24.4k|    const char *format = lavfdopts->format;
  448|  24.4k|    if (!format || !format[0])
  ------------------
  |  Branch (448:9): [True: 24.4k, False: 0]
  |  Branch (448:20): [True: 0, False: 0]
  ------------------
  449|  24.4k|        format = s->lavf_type;
  450|  24.4k|    if (!format)
  ------------------
  |  Branch (450:9): [True: 24.4k, False: 0]
  ------------------
  451|  24.4k|        format = avdevice_format;
  452|  24.4k|    if (format) {
  ------------------
  |  Branch (452:9): [True: 0, False: 24.4k]
  ------------------
  453|      0|        if (strcmp(format, "help") == 0) {
  ------------------
  |  Branch (453:13): [True: 0, False: 0]
  ------------------
  454|      0|            list_formats(demuxer);
  455|      0|            return -1;
  456|      0|        }
  457|      0|        forced_format = av_find_input_format(format);
  458|      0|        if (!forced_format) {
  ------------------
  |  Branch (458:13): [True: 0, False: 0]
  ------------------
  459|      0|            MP_FATAL(demuxer, "Unknown lavf format %s\n", format);
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  460|      0|            return -1;
  461|      0|        }
  462|      0|    }
  463|       |
  464|       |    // HLS streams seems to be not well tagged, so matching mime type is not
  465|       |    // enough. Strip URL parameters and match extension.
  466|  24.4k|    bstr ext = bstr_get_ext(bstr_split(bstr0(priv->filename), "?#", NULL));
  467|  24.4k|    AVProbeData avpd = {
  468|       |        // Disable file-extension matching with normal checks, except for HLS
  469|  24.4k|        .filename = !bstrcasecmp0(ext, "m3u8") || !bstrcasecmp0(ext, "m3u") ||
  ------------------
  |  Branch (469:21): [True: 0, False: 24.4k]
  |  Branch (469:51): [True: 2, False: 24.4k]
  ------------------
  470|  24.4k|                    check <= DEMUX_CHECK_REQUEST ? priv->filename : "",
  ------------------
  |  Branch (470:21): [True: 2.08k, False: 22.3k]
  ------------------
  471|  24.4k|        .buf_size = 0,
  472|  24.4k|        .buf = av_mallocz(PROBE_BUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE),
  ------------------
  |  |   59|  24.4k|#define PROBE_BUF_SIZE (10 * 1024 * 1024)
  ------------------
  473|  24.4k|        .mime_type = lavfdopts->allow_mimetype ? mime_type : NULL,
  ------------------
  |  Branch (473:22): [True: 24.4k, False: 0]
  ------------------
  474|  24.4k|    };
  475|  24.4k|    if (!avpd.buf)
  ------------------
  |  Branch (475:9): [True: 0, False: 24.4k]
  ------------------
  476|      0|        return -1;
  477|       |
  478|  24.4k|    bool final_probe = false;
  479|  35.5k|    do {
  480|  35.5k|        int score = 0;
  481|       |
  482|  35.5k|        if (forced_format) {
  ------------------
  |  Branch (482:13): [True: 0, False: 35.5k]
  ------------------
  483|      0|            priv->avif = forced_format;
  484|      0|            score = AVPROBE_SCORE_MAX;
  485|  35.5k|        } else {
  486|  35.5k|            int nsize = av_clip(avpd.buf_size * 2, INITIAL_PROBE_SIZE,
  ------------------
  |  |   58|  35.5k|#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
  |  |  ------------------
  |  |  |  |   33|  35.5k|#define STREAM_BUFFER_SIZE 2048
  |  |  ------------------
  ------------------
  487|  35.5k|                                PROBE_BUF_SIZE);
  ------------------
  |  |   59|  35.5k|#define PROBE_BUF_SIZE (10 * 1024 * 1024)
  ------------------
  488|  35.5k|            nsize = stream_read_peek(s, avpd.buf, nsize);
  489|  35.5k|            if (nsize <= avpd.buf_size)
  ------------------
  |  Branch (489:17): [True: 3.54k, False: 32.0k]
  ------------------
  490|  3.54k|                final_probe = true;
  491|  35.5k|            avpd.buf_size = nsize;
  492|       |
  493|  35.5k|            priv->avif = av_probe_input_format2(&avpd, avpd.buf_size > 0, &score);
  494|  35.5k|        }
  495|       |
  496|  35.5k|        if (priv->avif) {
  ------------------
  |  Branch (496:13): [True: 25.8k, False: 9.72k]
  ------------------
  497|  25.8k|            MP_VERBOSE(demuxer, "Found '%s' at score=%d size=%d%s.\n",
  ------------------
  |  |   88|  25.8k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  51.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 25.8k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  498|  25.8k|                       priv->avif->name, score, avpd.buf_size,
  499|  25.8k|                       forced_format ? " (forced)" : "");
  500|       |
  501|   901k|            for (int n = 0; lavfdopts->hacks && format_hacks[n].ff_name; n++) {
  ------------------
  |  Branch (501:29): [True: 901k, False: 0]
  |  Branch (501:49): [True: 880k, False: 20.4k]
  ------------------
  502|   880k|                const struct format_hack *entry = &format_hacks[n];
  503|   880k|                if (!matches_avinputformat_name(priv, entry->ff_name))
  ------------------
  |  Branch (503:21): [True: 872k, False: 8.54k]
  ------------------
  504|   872k|                    continue;
  505|  8.54k|                if (entry->mime_type && strcasecmp(entry->mime_type, mime_type) != 0)
  ------------------
  |  Branch (505:21): [True: 3.13k, False: 5.40k]
  |  Branch (505:41): [True: 3.13k, False: 0]
  ------------------
  506|  3.13k|                    continue;
  507|  5.40k|                priv->format_hack = *entry;
  508|  5.40k|                break;
  509|  8.54k|            }
  510|       |
  511|       |            // AVIF always needs to find stream info
  512|  25.8k|            if (bstrcasecmp0(ext, "avif") == 0)
  ------------------
  |  Branch (512:17): [True: 0, False: 25.8k]
  ------------------
  513|      0|                priv->format_hack.skipinfo = false;
  514|       |
  515|  25.8k|            if (score >= lavfdopts->probescore)
  ------------------
  |  Branch (515:17): [True: 20.9k, False: 4.87k]
  ------------------
  516|  20.9k|                break;
  517|       |
  518|  4.87k|            if (priv->format_hack.probescore &&
  ------------------
  |  Branch (518:17): [True: 3.00k, False: 1.87k]
  ------------------
  519|  4.87k|                score >= priv->format_hack.probescore &&
  ------------------
  |  Branch (519:17): [True: 485, False: 2.51k]
  ------------------
  520|  4.87k|                (!priv->format_hack.max_probe || final_probe))
  ------------------
  |  Branch (520:18): [True: 0, False: 485]
  |  Branch (520:50): [True: 176, False: 309]
  ------------------
  521|    176|                break;
  522|  4.87k|        }
  523|       |
  524|  14.4k|        priv->avif = NULL;
  525|  14.4k|        priv->format_hack = (struct format_hack){0};
  526|  14.4k|    } while (!final_probe);
  ------------------
  |  Branch (526:14): [True: 11.0k, False: 3.36k]
  ------------------
  527|       |
  528|      0|    av_free(avpd.buf);
  529|       |
  530|  24.4k|    if (priv->avif && !forced_format && priv->format_hack.ignore) {
  ------------------
  |  Branch (530:9): [True: 21.1k, False: 3.36k]
  |  Branch (530:23): [True: 21.1k, False: 0]
  |  Branch (530:41): [True: 102, False: 21.0k]
  ------------------
  531|    102|        MP_VERBOSE(demuxer, "Format blacklisted.\n");
  ------------------
  |  |   88|    102|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    102|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  532|    102|        priv->avif = NULL;
  533|    102|    }
  534|       |
  535|  24.4k|    if (!priv->avif) {
  ------------------
  |  Branch (535:9): [True: 3.46k, False: 21.0k]
  ------------------
  536|  3.46k|        MP_VERBOSE(demuxer, "No format found, try lowering probescore or forcing the format.\n");
  ------------------
  |  |   88|  3.46k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.46k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  537|  3.46k|        return -1;
  538|  3.46k|    }
  539|       |
  540|  21.0k|    if (lavfdopts->hacks)
  ------------------
  |  Branch (540:9): [True: 21.0k, False: 0]
  ------------------
  541|  21.0k|        priv->avif_flags = priv->avif->flags | priv->format_hack.if_flags;
  542|       |
  543|  21.0k|    priv->linearize_ts = lavfdopts->linearize_ts;
  544|  21.0k|    if (priv->linearize_ts < 0 && !priv->format_hack.linearize_audio_ts)
  ------------------
  |  Branch (544:9): [True: 21.0k, False: 0]
  |  Branch (544:35): [True: 21.0k, False: 0]
  ------------------
  545|  21.0k|        priv->linearize_ts = 0;
  546|       |
  547|  21.0k|    demuxer->filetype = priv->avif->name;
  548|       |
  549|  21.0k|    if (priv->format_hack.detect_charset)
  ------------------
  |  Branch (549:9): [True: 458, False: 20.5k]
  ------------------
  550|    458|        convert_charset(demuxer);
  551|       |
  552|  21.0k|    return 0;
  553|  24.4k|}
demux_lavf.c:remove_prefix:
  409|  24.4k|{
  410|   122k|    for (int n = 0; prefixes[n]; n++) {
  ------------------
  |  Branch (410:21): [True: 97.9k, False: 24.4k]
  ------------------
  411|  97.9k|        int len = strlen(prefixes[n]);
  412|  97.9k|        if (strncmp(s, prefixes[n], len) == 0)
  ------------------
  |  Branch (412:13): [True: 0, False: 97.9k]
  ------------------
  413|      0|            return s + len;
  414|  97.9k|    }
  415|  24.4k|    return s;
  416|  24.4k|}
demux_lavf.c:convert_charset:
  379|    458|{
  380|    458|    lavf_priv_t *priv = demuxer->priv;
  381|    458|    char *cp = priv->opts->sub_cp;
  382|    458|    if (!cp || !cp[0] || mp_charset_is_utf8(cp))
  ------------------
  |  Branch (382:9): [True: 0, False: 458]
  |  Branch (382:16): [True: 0, False: 458]
  |  Branch (382:26): [True: 0, False: 458]
  ------------------
  383|      0|        return;
  384|    458|    bstr data = stream_read_complete(priv->stream, NULL, 128 * 1024 * 1024);
  385|    458|    if (!data.start) {
  ------------------
  |  Branch (385:9): [True: 0, False: 458]
  ------------------
  386|      0|        MP_WARN(demuxer, "File too big (or error reading) - skip charset probing.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  387|      0|        return;
  388|      0|    }
  389|    458|    void *alloc = data.start;
  390|    458|    cp = (char *)mp_charset_guess(priv, demuxer->log, data, cp, 0);
  391|    458|    if (cp && !mp_charset_is_utf8(cp))
  ------------------
  |  Branch (391:9): [True: 458, False: 0]
  |  Branch (391:15): [True: 447, False: 11]
  ------------------
  392|    458|        MP_INFO(demuxer, "Using subtitle charset: %s\n", cp);
  ------------------
  |  |   87|    447|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    447|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  393|       |    // libavformat transparently converts UTF-16 to UTF-8
  394|    458|    if (!mp_charset_is_utf16(cp) && !mp_charset_is_utf8(cp)) {
  ------------------
  |  Branch (394:9): [True: 455, False: 3]
  |  Branch (394:37): [True: 444, False: 11]
  ------------------
  395|    444|        bstr conv = mp_iconv_to_utf8(demuxer->log, data, cp, MP_ICONV_VERBOSE);
  396|    444|        if (conv.start && conv.start != data.start)
  ------------------
  |  Branch (396:13): [True: 444, False: 0]
  |  Branch (396:27): [True: 444, False: 0]
  ------------------
  397|    444|            talloc_steal(alloc, conv.start);
  ------------------
  |  |   38|    444|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|    444|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  398|    444|        if (conv.start)
  ------------------
  |  Branch (398:13): [True: 444, False: 0]
  ------------------
  399|    444|            data = conv;
  400|    444|    }
  401|    458|    if (data.start) {
  ------------------
  |  Branch (401:9): [True: 458, False: 0]
  ------------------
  402|    458|        priv->stream = stream_memory_open(demuxer->global, data.start, data.len);
  403|    458|        priv->own_stream = true;
  404|    458|    }
  405|    458|    talloc_free(alloc);
  ------------------
  |  |   47|    458|#define talloc_free                     ta_free
  ------------------
  406|    458|}
demux_lavf.c:mp_read:
  294|   424k|{
  295|   424k|    struct demuxer *demuxer = opaque;
  296|   424k|    lavf_priv_t *priv = demuxer->priv;
  297|   424k|    struct stream *stream = priv->stream;
  298|   424k|    if (!stream)
  ------------------
  |  Branch (298:9): [True: 0, False: 424k]
  ------------------
  299|      0|        return 0;
  300|       |
  301|   424k|    int ret = stream_read_partial(stream, buf, size);
  302|       |
  303|   424k|    MP_TRACE(demuxer, "%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n",
  ------------------
  |  |   90|   424k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   424k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  304|   424k|             ret, stream, buf, size, stream_tell(stream), stream->eof);
  305|   424k|    return ret ? ret : AVERROR_EOF;
  ------------------
  |  Branch (305:12): [True: 43.0k, False: 381k]
  ------------------
  306|   424k|}
demux_lavf.c:mp_seek:
  309|   131k|{
  310|   131k|    struct demuxer *demuxer = opaque;
  311|   131k|    lavf_priv_t *priv = demuxer->priv;
  312|   131k|    struct stream *stream = priv->stream;
  313|   131k|    if (!stream)
  ------------------
  |  Branch (313:9): [True: 0, False: 131k]
  ------------------
  314|      0|        return -1;
  315|       |
  316|   131k|    MP_TRACE(demuxer, "mp_seek(%p, %"PRId64", %s)\n", stream, pos,
  ------------------
  |  |   90|   131k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   791k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 28.3k, False: 103k]
  |  |  |  |  |  Branch (82:57): [True: 0, False: 131k]
  |  |  |  |  |  Branch (82:57): [True: 0, False: 131k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  317|   131k|             whence == SEEK_END ? "end" :
  318|   131k|             whence == SEEK_CUR ? "cur" :
  319|   131k|             whence == SEEK_SET ? "set" : "size");
  320|   131k|    if (whence == SEEK_END || whence == AVSEEK_SIZE) {
  ------------------
  |  Branch (320:9): [True: 0, False: 131k]
  |  Branch (320:31): [True: 103k, False: 28.3k]
  ------------------
  321|   103k|        int64_t end = stream_get_size(stream);
  322|   103k|        if (end < 0)
  ------------------
  |  Branch (322:13): [True: 0, False: 103k]
  ------------------
  323|      0|            return -1;
  324|   103k|        if (whence == AVSEEK_SIZE)
  ------------------
  |  Branch (324:13): [True: 103k, False: 0]
  ------------------
  325|   103k|            return end;
  326|      0|        pos += end;
  327|  28.3k|    } else if (whence == SEEK_CUR) {
  ------------------
  |  Branch (327:16): [True: 0, False: 28.3k]
  ------------------
  328|      0|        pos += stream_tell(stream);
  329|  28.3k|    } else if (whence != SEEK_SET) {
  ------------------
  |  Branch (329:16): [True: 0, False: 28.3k]
  ------------------
  330|      0|        return -1;
  331|      0|    }
  332|       |
  333|  28.3k|    if (pos < 0)
  ------------------
  |  Branch (333:9): [True: 0, False: 28.3k]
  ------------------
  334|      0|        return -1;
  335|       |
  336|  28.3k|    int64_t current_pos = stream_tell(stream);
  337|  28.3k|    if (!priv->is_dvd_bd) {
  ------------------
  |  Branch (337:9): [True: 28.3k, False: 0]
  ------------------
  338|  28.3k|        if (stream_seek(stream, pos) == 0) {
  ------------------
  |  Branch (338:13): [True: 58, False: 28.3k]
  ------------------
  339|     58|            stream_seek(stream, current_pos);
  340|     58|            return -1;
  341|     58|        }
  342|  28.3k|    } else {
  343|      0|        stream_drop_buffers(stream);
  344|      0|        stream->pos = current_pos;
  345|      0|    }
  346|       |
  347|  28.3k|    return pos;
  348|  28.3k|}
demux_lavf.c:matches_avinputformat_name:
  280|   932k|{
  281|   932k|    const char *avifname = priv->avif->name;
  282|   933k|    while (1) {
  ------------------
  |  Branch (282:12): [Folded - Ignored]
  ------------------
  283|   933k|        const char *next = strchr(avifname, ',');
  284|   933k|        if (!next)
  ------------------
  |  Branch (284:13): [True: 932k, False: 1.51k]
  ------------------
  285|   932k|            return !strcmp(avifname, name);
  286|  1.51k|        int len = next - avifname;
  287|  1.51k|        if (len == strlen(name) && !memcmp(avifname, name, len))
  ------------------
  |  Branch (287:13): [True: 477, False: 1.03k]
  |  Branch (287:36): [True: 63, False: 414]
  ------------------
  288|     63|            return true;
  289|  1.44k|        avifname = next + 1;
  290|  1.44k|    }
  291|   932k|}
demux_lavf.c:guess_and_set_vobsub_name:
  564|  21.0k|{
  565|  21.0k|    lavf_priv_t *priv = demuxer->priv;
  566|  21.0k|    if (!matches_avinputformat_name(priv, "vobsub"))
  ------------------
  |  Branch (566:9): [True: 21.0k, False: 0]
  ------------------
  567|  21.0k|        return;
  568|       |
  569|      0|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|      0|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      0|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  570|      0|    bstr bfilename = bstr0(priv->filename);
  571|      0|    char *subname = NULL;
  572|      0|    if (mp_is_url(bfilename)) {
  ------------------
  |  Branch (572:9): [True: 0, False: 0]
  ------------------
  573|       |        // It might be a http URL, which has additional parameters after the
  574|       |        // end of the actual file path.
  575|      0|        bstr start, end;
  576|      0|        if (bstr_split_tok(bfilename, "?", &start, &end)) {
  ------------------
  |  Branch (576:13): [True: 0, False: 0]
  ------------------
  577|      0|            subname = replace_idx_ext(tmp, start);
  578|      0|            if (subname)
  ------------------
  |  Branch (578:17): [True: 0, False: 0]
  ------------------
  579|      0|                subname = talloc_asprintf(tmp, "%s?%.*s", subname, BSTR_P(end));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  580|      0|        }
  581|      0|    }
  582|      0|    if (!subname)
  ------------------
  |  Branch (582:9): [True: 0, False: 0]
  ------------------
  583|      0|        subname = replace_idx_ext(tmp, bfilename);
  584|      0|    if (!subname)
  ------------------
  |  Branch (584:9): [True: 0, False: 0]
  ------------------
  585|      0|        subname = talloc_asprintf(tmp, "%.*s.sub", BSTR_P(bfilename));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  586|       |
  587|      0|    MP_VERBOSE(demuxer, "Assuming associated .sub file: %s\n", subname);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  588|      0|    av_dict_set(d, "sub_name", subname, 0);
  589|      0|    talloc_free(tmp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  590|      0|}
demux_lavf.c:interrupt_cb:
  905|   133k|{
  906|   133k|    struct demuxer *demuxer = ctx;
  907|   133k|    return mp_cancel_test(demuxer->cancel);
  908|   133k|}
demux_lavf.c:add_new_streams:
  888|  1.43M|{
  889|  1.43M|    lavf_priv_t *priv = demuxer->priv;
  890|  1.46M|    while (priv->num_streams < priv->avfc->nb_streams)
  ------------------
  |  Branch (890:12): [True: 28.3k, False: 1.43M]
  ------------------
  891|  28.3k|        handle_new_stream(demuxer, priv->num_streams);
  892|  1.43M|}
demux_lavf.c:handle_new_stream:
  686|  28.3k|{
  687|  28.3k|    lavf_priv_t *priv = demuxer->priv;
  688|  28.3k|    AVFormatContext *avfc = priv->avfc;
  689|  28.3k|    AVStream *st = avfc->streams[i];
  690|  28.3k|    struct sh_stream *sh = NULL;
  691|  28.3k|    AVCodecParameters *codec = st->codecpar;
  692|  28.3k|    int lavc_delay = codec->initial_padding;
  693|       |
  694|  28.3k|    switch (codec->codec_type) {
  695|  16.4k|    case AVMEDIA_TYPE_AUDIO: {
  ------------------
  |  Branch (695:5): [True: 16.4k, False: 11.8k]
  ------------------
  696|  16.4k|        sh = demux_alloc_sh_stream(STREAM_AUDIO);
  697|  16.4k|        if (!mp_chmap_from_av_layout(&sh->codec->channels, &codec->ch_layout)) {
  ------------------
  |  Branch (697:13): [True: 0, False: 16.4k]
  ------------------
  698|      0|            char layout[128] = {0};
  699|      0|            MP_WARN(demuxer,
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  700|      0|                    "Failed to convert channel layout %s to mpv one!\n",
  701|      0|                    av_channel_layout_describe(&codec->ch_layout,
  702|      0|                                               layout, 128) < 0 ?
  703|      0|                    "undefined" : layout);
  704|      0|        }
  705|       |
  706|  16.4k|        sh->codec->samplerate = codec->sample_rate;
  707|  16.4k|        sh->codec->bitrate = codec->bit_rate;
  708|  16.4k|        sh->codec->format_name = talloc_strdup(sh, av_get_sample_fmt_name(codec->format));
  ------------------
  |  |   50|  16.4k|#define talloc_strdup                   ta_xstrdup
  ------------------
  709|       |
  710|  16.4k|        double delay = 0;
  711|  16.4k|        if (codec->sample_rate > 0)
  ------------------
  |  Branch (711:13): [True: 7.08k, False: 9.35k]
  ------------------
  712|  7.08k|            delay = lavc_delay / (double)codec->sample_rate;
  713|  16.4k|        priv->seek_delay = MPMAX(priv->seek_delay, delay);
  ------------------
  |  |   43|  16.4k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 16.4k]
  |  |  ------------------
  ------------------
  714|       |
  715|  16.4k|        export_replaygain(demuxer, sh, st);
  716|       |
  717|  16.4k|        sh->seek_preroll = delay;
  718|       |
  719|  16.4k|        break;
  720|      0|    }
  721|  9.04k|    case AVMEDIA_TYPE_VIDEO: {
  ------------------
  |  Branch (721:5): [True: 9.04k, False: 19.2k]
  ------------------
  722|  9.04k|        sh = demux_alloc_sh_stream(STREAM_VIDEO);
  723|       |
  724|  9.04k|        if ((st->disposition & AV_DISPOSITION_ATTACHED_PIC) &&
  ------------------
  |  Branch (724:13): [True: 0, False: 9.04k]
  ------------------
  725|  9.04k|            !(st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS))
  ------------------
  |  Branch (725:13): [True: 0, False: 0]
  ------------------
  726|      0|        {
  727|      0|            sh->attached_picture =
  728|      0|                new_demux_packet_from_avpacket(demuxer->packet_pool, &st->attached_pic);
  729|      0|            if (sh->attached_picture) {
  ------------------
  |  Branch (729:17): [True: 0, False: 0]
  ------------------
  730|      0|                sh->attached_picture->pts = 0;
  731|      0|                talloc_steal(sh, sh->attached_picture);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  732|      0|                sh->attached_picture->keyframe = true;
  733|      0|            }
  734|      0|        }
  735|       |
  736|  9.04k|        if (!sh->attached_picture) {
  ------------------
  |  Branch (736:13): [True: 9.04k, False: 0]
  ------------------
  737|       |            // A real video stream probably means it's a packet based format.
  738|  9.04k|            priv->pcm_seek_hack_disabled = true;
  739|  9.04k|            priv->pcm_seek_hack = NULL;
  740|       |            // Also, we don't want to do this shit for ogv videos.
  741|  9.04k|            if (priv->linearize_ts < 0)
  ------------------
  |  Branch (741:17): [True: 0, False: 9.04k]
  ------------------
  742|      0|                priv->linearize_ts = 0;
  743|  9.04k|        }
  744|       |
  745|  9.04k|        sh->codec->disp_w = codec->width;
  746|  9.04k|        sh->codec->disp_h = codec->height;
  747|  9.04k|        sh->codec->format_name = talloc_strdup(sh, av_get_pix_fmt_name(codec->format));
  ------------------
  |  |   50|  9.04k|#define talloc_strdup                   ta_xstrdup
  ------------------
  748|  9.04k|        if (st->avg_frame_rate.num)
  ------------------
  |  Branch (748:13): [True: 1.63k, False: 7.41k]
  ------------------
  749|  1.63k|            sh->codec->fps = av_q2d(st->avg_frame_rate);
  750|  9.04k|        if (is_image(st, sh->attached_picture, priv->avif)) {
  ------------------
  |  Branch (750:13): [True: 2.41k, False: 6.62k]
  ------------------
  751|  2.41k|            MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
  ------------------
  |  |   88|  2.41k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.41k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  752|  2.41k|            sh->image = true;
  753|  2.41k|            sh->codec->fps = demuxer->opts->mf_fps;
  754|  2.41k|        }
  755|  9.04k|        sh->codec->par_w = st->sample_aspect_ratio.num;
  756|  9.04k|        sh->codec->par_h = st->sample_aspect_ratio.den;
  757|       |
  758|  9.04k|        const uint8_t *sd = mp_av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX);
  759|  9.04k|        if (sd) {
  ------------------
  |  Branch (759:13): [True: 0, False: 9.04k]
  ------------------
  760|      0|            double r = av_display_rotation_get((int32_t *)sd);
  761|      0|            if (!isnan(r))
  ------------------
  |  Branch (761:17): [True: 0, False: 0]
  ------------------
  762|      0|                sh->codec->rotate = (((int)(-r) % 360) + 360) % 360;
  763|      0|        }
  764|       |
  765|  9.04k|        if ((sd = mp_av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF))) {
  ------------------
  |  Branch (765:13): [True: 0, False: 9.04k]
  ------------------
  766|      0|            const AVDOVIDecoderConfigurationRecord *cfg = (void *) sd;
  767|      0|            MP_VERBOSE(demuxer, "Found Dolby Vision config record: profile "
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  768|      0|                       "%d level %d\n", cfg->dv_profile, cfg->dv_level);
  769|      0|            sh->codec->dovi = true;
  770|      0|            sh->codec->dv_profile = cfg->dv_profile;
  771|      0|            sh->codec->dv_level = cfg->dv_level;
  772|      0|        }
  773|       |
  774|       |        // This also applies to vfw-muxed mkv, but we can't detect these easily.
  775|  9.04k|        sh->codec->avi_dts = matches_avinputformat_name(priv, "avi");
  776|       |
  777|  9.04k|        break;
  778|      0|    }
  779|    394|    case AVMEDIA_TYPE_SUBTITLE: {
  ------------------
  |  Branch (779:5): [True: 394, False: 27.9k]
  ------------------
  780|    394|        sh = demux_alloc_sh_stream(STREAM_SUB);
  781|       |
  782|    394|        if (codec->extradata_size) {
  ------------------
  |  Branch (782:13): [True: 44, False: 350]
  ------------------
  783|     44|            sh->codec->extradata = talloc_size(sh, codec->extradata_size);
  ------------------
  |  |   43|     44|#define talloc_size                     ta_xalloc_size
  |  |  ------------------
  |  |  |  |  120|     44|#define ta_xalloc_size(...)             ta_oom_p(ta_alloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  153|     44|#define ta_alloc_size(...)      ta_dbg_set_loc(ta_alloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|     44|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|     44|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|     44|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  784|     44|            memcpy(sh->codec->extradata, codec->extradata, codec->extradata_size);
  785|     44|            sh->codec->extradata_size = codec->extradata_size;
  786|     44|        }
  787|       |
  788|    394|        if (matches_avinputformat_name(priv, "microdvd")) {
  ------------------
  |  Branch (788:13): [True: 0, False: 394]
  ------------------
  789|      0|            AVRational r;
  790|      0|            if (av_opt_get_q(avfc, "subfps", AV_OPT_SEARCH_CHILDREN, &r) >= 0) {
  ------------------
  |  Branch (790:17): [True: 0, False: 0]
  ------------------
  791|       |                // File headers don't have a FPS set.
  792|      0|                if (r.num < 1 || r.den < 1)
  ------------------
  |  Branch (792:21): [True: 0, False: 0]
  |  Branch (792:34): [True: 0, False: 0]
  ------------------
  793|      0|                    sh->codec->frame_based = 23.976; // default timebase
  794|      0|            }
  795|      0|        }
  796|    394|        break;
  797|      0|    }
  798|      0|    case AVMEDIA_TYPE_ATTACHMENT: {
  ------------------
  |  Branch (798:5): [True: 0, False: 28.3k]
  ------------------
  799|      0|        AVDictionaryEntry *ftag = av_dict_get(st->metadata, "filename", NULL, 0);
  800|      0|        char *filename = ftag ? ftag->value : NULL;
  ------------------
  |  Branch (800:26): [True: 0, False: 0]
  ------------------
  801|      0|        AVDictionaryEntry *mt = av_dict_get(st->metadata, "mimetype", NULL, 0);
  802|      0|        char *mimetype = mt ? mt->value : NULL;
  ------------------
  |  Branch (802:26): [True: 0, False: 0]
  ------------------
  803|      0|        if (mimetype) {
  ------------------
  |  Branch (803:13): [True: 0, False: 0]
  ------------------
  804|      0|            demuxer_add_attachment(demuxer, filename, mimetype,
  805|      0|                                   codec->extradata, codec->extradata_size);
  806|      0|        }
  807|      0|        break;
  808|      0|    }
  809|  2.42k|    default: ;
  ------------------
  |  Branch (809:5): [True: 2.42k, False: 25.8k]
  ------------------
  810|  28.3k|    }
  811|       |
  812|  28.3k|    struct stream_info *info = talloc_zero(priv, struct stream_info);
  ------------------
  |  |   27|  28.3k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  28.3k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  28.3k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  813|  28.3k|    *info = (struct stream_info){
  814|  28.3k|        .sh = sh,
  815|  28.3k|        .last_key_pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  28.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  816|  28.3k|        .highest_pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  28.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  817|  28.3k|    };
  818|  28.3k|    mp_assert(priv->num_streams == i); // directly mapped
  ------------------
  |  |   41|  28.3k|#define mp_assert assert
  ------------------
  819|  28.3k|    MP_TARRAY_APPEND(priv, priv->streams, priv->num_streams, info);
  ------------------
  |  |  105|  28.3k|    do {                                            \
  |  |  106|  28.3k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  28.3k|    do {                                            \
  |  |  |  |   97|  28.3k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  28.3k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  28.3k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  28.3k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 19.7k, False: 8.57k]
  |  |  |  |  ------------------
  |  |  |  |   99|  28.3k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  19.7k|    do {                                                        \
  |  |  |  |  |  |   89|  19.7k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  19.7k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  19.7k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  19.7k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  19.7k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  19.7k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  19.7k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  28.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  28.3k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  28.3k|        (idxvar)++;                                 \
  |  |  109|  28.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  820|       |
  821|  28.3k|    if (sh) {
  ------------------
  |  Branch (821:9): [True: 25.8k, False: 2.42k]
  ------------------
  822|  25.8k|        sh->ff_index = st->index;
  823|  25.8k|        sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id);
  824|  25.8k|        sh->codec->codec_tag = codec->codec_tag;
  825|  25.8k|        sh->codec->lav_codecpar = avcodec_parameters_alloc();
  826|  25.8k|        if (sh->codec->lav_codecpar)
  ------------------
  |  Branch (826:13): [True: 25.8k, False: 0]
  ------------------
  827|  25.8k|            avcodec_parameters_copy(sh->codec->lav_codecpar, codec);
  828|  25.8k|        sh->codec->native_tb_num = st->time_base.num;
  829|  25.8k|        sh->codec->native_tb_den = st->time_base.den;
  830|       |
  831|  25.8k|        if (st->disposition & AV_DISPOSITION_DEFAULT)
  ------------------
  |  Branch (831:13): [True: 0, False: 25.8k]
  ------------------
  832|      0|            sh->default_track = true;
  833|  25.8k|        if (st->disposition & AV_DISPOSITION_FORCED)
  ------------------
  |  Branch (833:13): [True: 0, False: 25.8k]
  ------------------
  834|      0|            sh->forced_track = true;
  835|  25.8k|        if (st->disposition & AV_DISPOSITION_DEPENDENT)
  ------------------
  |  Branch (835:13): [True: 0, False: 25.8k]
  ------------------
  836|      0|            sh->dependent_track = true;
  837|  25.8k|        if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
  ------------------
  |  Branch (837:13): [True: 0, False: 25.8k]
  ------------------
  838|      0|            sh->visual_impaired_track = true;
  839|  25.8k|        if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
  ------------------
  |  Branch (839:13): [True: 0, False: 25.8k]
  ------------------
  840|      0|            sh->hearing_impaired_track = true;
  841|  25.8k|        if (st->disposition & AV_DISPOSITION_STILL_IMAGE)
  ------------------
  |  Branch (841:13): [True: 0, False: 25.8k]
  ------------------
  842|      0|            sh->still_image = true;
  843|  25.8k|        if (priv->format_hack.use_stream_ids)
  ------------------
  |  Branch (843:13): [True: 0, False: 25.8k]
  ------------------
  844|      0|            sh->demuxer_id = st->id;
  845|  25.8k|        AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0);
  846|  25.8k|        if (title && title->value)
  ------------------
  |  Branch (846:13): [True: 0, False: 25.8k]
  |  Branch (846:22): [True: 0, False: 0]
  ------------------
  847|      0|            sh->title = talloc_strdup(sh, title->value);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  848|  25.8k|        if (!sh->title && st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
  ------------------
  |  Branch (848:13): [True: 25.8k, False: 0]
  |  Branch (848:27): [True: 0, False: 25.8k]
  ------------------
  849|      0|            sh->title = talloc_asprintf(sh, "visual impaired");
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  850|  25.8k|        if (!sh->title && st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
  ------------------
  |  Branch (850:13): [True: 25.8k, False: 0]
  |  Branch (850:27): [True: 0, False: 25.8k]
  ------------------
  851|      0|            sh->title = talloc_asprintf(sh, "hearing impaired");
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  852|  25.8k|        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
  853|  25.8k|        if (lang && lang->value && strcmp(lang->value, "und") != 0)
  ------------------
  |  Branch (853:13): [True: 0, False: 25.8k]
  |  Branch (853:21): [True: 0, False: 0]
  |  Branch (853:36): [True: 0, False: 0]
  ------------------
  854|      0|            sh->lang = talloc_strdup(sh, lang->value);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  855|  25.8k|        sh->hls_bitrate = dict_get_decimal(st->metadata, "variant_bitrate", 0);
  856|  25.8k|        AVProgram *prog = av_find_program_from_stream(avfc, NULL, i);
  857|  25.8k|        if (prog)
  ------------------
  |  Branch (857:13): [True: 0, False: 25.8k]
  ------------------
  858|      0|            sh->program_id = prog->id;
  859|  25.8k|        sh->missing_timestamps = !!(priv->avif_flags & AVFMT_NOTIMESTAMPS);
  860|  25.8k|        mp_tags_move_from_av_dictionary(sh->tags, &st->metadata);
  861|  25.8k|        demux_add_sh_stream(demuxer, sh);
  862|       |
  863|       |        // Unfortunately, there is no better way to detect PCM codecs, other
  864|       |        // than listing them all manually. (Or other "frameless" codecs. Or
  865|       |        // rather, codecs with frames so small libavformat will put multiple of
  866|       |        // them into a single packet, but not preserve these artificial packet
  867|       |        // boundaries on seeking.)
  868|  25.8k|        if (sh->codec->codec && strncmp(sh->codec->codec, "pcm_", 4) == 0 &&
  ------------------
  |  Branch (868:13): [True: 25.8k, False: 0]
  |  Branch (868:33): [True: 6.25k, False: 19.6k]
  ------------------
  869|  25.8k|            codec->block_align && !priv->pcm_seek_hack_disabled &&
  ------------------
  |  Branch (869:13): [True: 2, False: 6.25k]
  |  Branch (869:35): [True: 2, False: 0]
  ------------------
  870|  25.8k|            priv->opts->hacks && !priv->format_hack.no_pcm_seek &&
  ------------------
  |  Branch (870:13): [True: 2, False: 0]
  |  Branch (870:34): [True: 2, False: 0]
  ------------------
  871|  25.8k|            st->time_base.num == 1 && st->time_base.den == codec->sample_rate)
  ------------------
  |  Branch (871:13): [True: 2, False: 0]
  |  Branch (871:39): [True: 2, False: 0]
  ------------------
  872|      2|        {
  873|      2|            if (priv->pcm_seek_hack) {
  ------------------
  |  Branch (873:17): [True: 0, False: 2]
  ------------------
  874|       |                // More than 1 audio stream => usually doesn't apply.
  875|      0|                priv->pcm_seek_hack_disabled = true;
  876|      0|                priv->pcm_seek_hack = NULL;
  877|      2|            } else {
  878|      2|                priv->pcm_seek_hack = st;
  879|      2|            }
  880|      2|        }
  881|  25.8k|    }
  882|       |
  883|  28.3k|    select_tracks(demuxer, i);
  884|  28.3k|}
demux_lavf.c:export_replaygain:
  616|  16.4k|{
  617|  16.4k|    const AVReplayGain *av_rgain =
  618|  16.4k|        (const AVReplayGain *)mp_av_stream_get_side_data(st, AV_PKT_DATA_REPLAYGAIN);
  619|  16.4k|    if (!av_rgain)
  ------------------
  |  Branch (619:9): [True: 16.4k, False: 0]
  ------------------
  620|  16.4k|        return;
  621|       |
  622|      0|    bool track_data_available =
  623|      0|        av_rgain->track_gain != INT32_MIN && av_rgain->track_peak != 0;
  ------------------
  |  Branch (623:9): [True: 0, False: 0]
  |  Branch (623:46): [True: 0, False: 0]
  ------------------
  624|      0|    bool album_data_available =
  625|      0|        av_rgain->album_gain != INT32_MIN && av_rgain->album_peak != 0;
  ------------------
  |  Branch (625:9): [True: 0, False: 0]
  |  Branch (625:46): [True: 0, False: 0]
  ------------------
  626|       |
  627|      0|    if (!track_data_available && !album_data_available)
  ------------------
  |  Branch (627:9): [True: 0, False: 0]
  |  Branch (627:34): [True: 0, False: 0]
  ------------------
  628|      0|        return;
  629|       |
  630|      0|    struct replaygain_data *rgain = talloc_ptrtype(demuxer, rgain);
  ------------------
  |  |   34|      0|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|      0|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  631|      0|    rgain->track_gain = rgain->album_gain = 0;
  632|      0|    rgain->track_peak = rgain->album_peak = 1;
  633|       |
  634|       |    // Set values in *rgain, using track gain as a fallback for album gain
  635|       |    // if the latter is not present. This behavior matches that in
  636|       |    // demux/demux.c's decode_rgain; if you change this, please make
  637|       |    // equivalent changes there too.
  638|      0|    if (track_data_available) {
  ------------------
  |  Branch (638:9): [True: 0, False: 0]
  ------------------
  639|      0|        rgain->track_gain = rgain->album_gain =
  640|      0|            av_rgain->track_gain / 100000.0f;
  641|      0|        rgain->track_peak = rgain->album_peak =
  642|      0|            av_rgain->track_peak / 100000.0f;
  643|      0|    }
  644|       |
  645|       |    // If album data is actually available, fill it in with proper values.
  646|      0|    if (album_data_available) {
  ------------------
  |  Branch (646:9): [True: 0, False: 0]
  ------------------
  647|      0|        rgain->album_gain = av_rgain->album_gain / 100000.0f;
  648|      0|        rgain->album_peak = av_rgain->album_peak / 100000.0f;
  649|      0|    }
  650|       |
  651|       |    // This must be run only before the stream was added, otherwise there
  652|       |    // will be race conditions with accesses from the user thread.
  653|      0|    mp_assert(!sh->ds);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  654|      0|    sh->codec->replaygain_data = rgain;
  655|      0|}
demux_lavf.c:is_image:
  671|  9.04k|{
  672|  9.04k|    return st->nb_frames <= 1 && (
  ------------------
  |  Branch (672:12): [True: 9.03k, False: 9]
  ------------------
  673|  9.03k|        attached_picture ||
  ------------------
  |  Branch (673:9): [True: 0, False: 9.03k]
  ------------------
  674|  9.03k|        bstr_endswith0(bstr0(avif->name), "_pipe") ||
  ------------------
  |  Branch (674:9): [True: 1.37k, False: 7.66k]
  ------------------
  675|  9.03k|        strcmp(avif->name, "alias_pix") == 0 ||
  ------------------
  |  Branch (675:9): [True: 0, False: 7.66k]
  ------------------
  676|  9.03k|        strcmp(avif->name, "gif") == 0 ||
  ------------------
  |  Branch (676:9): [True: 1.04k, False: 6.61k]
  ------------------
  677|  9.03k|        strcmp(avif->name, "ico") == 0 ||
  ------------------
  |  Branch (677:9): [True: 0, False: 6.61k]
  ------------------
  678|  9.03k|        strcmp(avif->name, "image2pipe") == 0 ||
  ------------------
  |  Branch (678:9): [True: 0, False: 6.61k]
  ------------------
  679|  9.03k|        ((st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
  ------------------
  |  Branch (679:11): [True: 0, False: 6.61k]
  ------------------
  680|  6.61k|          st->codecpar->codec_id == AV_CODEC_ID_AV1)
  ------------------
  |  Branch (680:11): [True: 0, False: 6.61k]
  ------------------
  681|  6.61k|         && st->nb_frames == 1)
  ------------------
  |  Branch (681:13): [True: 0, False: 0]
  ------------------
  682|  9.03k|    );
  683|  9.04k|}
demux_lavf.c:mp_av_stream_get_side_data:
  606|  34.5k|{
  607|  34.5k|    const AVPacketSideData *sd;
  608|  34.5k|    sd = av_packet_side_data_get(st->codecpar->coded_side_data,
  609|  34.5k|                                 st->codecpar->nb_coded_side_data,
  610|  34.5k|                                 type);
  611|  34.5k|    return sd ? sd->data : NULL;
  ------------------
  |  Branch (611:12): [True: 0, False: 34.5k]
  ------------------
  612|  34.5k|}
demux_lavf.c:dict_get_decimal:
  659|  25.8k|{
  660|  25.8k|    AVDictionaryEntry *e = av_dict_get(dict, entry, NULL, 0);
  661|  25.8k|    if (e && e->value) {
  ------------------
  |  Branch (661:9): [True: 0, False: 25.8k]
  |  Branch (661:14): [True: 0, False: 0]
  ------------------
  662|      0|        char *end = NULL;
  663|      0|        long int r = strtol(e->value, &end, 10);
  664|      0|        if (end && !end[0] && r >= INT_MIN && r <= INT_MAX)
  ------------------
  |  Branch (664:13): [True: 0, False: 0]
  |  Branch (664:20): [True: 0, False: 0]
  |  Branch (664:31): [True: 0, False: 0]
  |  Branch (664:47): [True: 0, False: 0]
  ------------------
  665|      0|            return r;
  666|      0|    }
  667|  25.8k|    return def;
  668|  25.8k|}
demux_lavf.c:select_tracks:
  593|   188k|{
  594|   188k|    lavf_priv_t *priv = demuxer->priv;
  595|   443k|    for (int n = start; n < priv->num_streams; n++) {
  ------------------
  |  Branch (595:25): [True: 255k, False: 188k]
  ------------------
  596|   255k|        struct sh_stream *stream = priv->streams[n]->sh;
  597|   255k|        AVStream *st = priv->avfc->streams[n];
  598|   255k|        bool selected = stream && demux_stream_is_selected(stream) &&
  ------------------
  |  Branch (598:25): [True: 252k, False: 2.42k]
  |  Branch (598:35): [True: 115k, False: 137k]
  ------------------
  599|   255k|                        !stream->attached_picture;
  ------------------
  |  Branch (599:25): [True: 115k, False: 0]
  ------------------
  600|   255k|        st->discard = selected ? AVDISCARD_DEFAULT : AVDISCARD_ALL;
  ------------------
  |  Branch (600:23): [True: 115k, False: 139k]
  ------------------
  601|   255k|    }
  602|   188k|}
demux_lavf.c:demux_lavf_read_packet:
 1217|  1.56M|{
 1218|  1.56M|    lavf_priv_t *priv = demux->priv;
 1219|       |
 1220|  1.56M|    AVPacket *pkt = av_packet_alloc();
 1221|  1.56M|    MP_HANDLE_OOM(pkt);
  ------------------
  |  |  176|  1.56M|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  1.56M|        void *oom_p_ = (x);     \
  |  |  178|  1.56M|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 1.56M]
  |  |  ------------------
  |  |  179|  1.56M|            abort();            \
  |  |  180|  1.56M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1222|  1.56M|    int r = av_read_frame(priv->avfc, pkt);
 1223|  1.56M|    update_read_stats(demux);
 1224|  1.56M|    if (r < 0) {
  ------------------
  |  Branch (1224:9): [True: 146k, False: 1.41M]
  ------------------
 1225|   146k|        av_packet_free(&pkt);
 1226|   146k|        if (r == AVERROR_EOF)
  ------------------
  |  Branch (1226:13): [True: 47.7k, False: 98.8k]
  ------------------
 1227|  47.7k|            return false;
 1228|  98.8k|        MP_WARN(demux, "error reading packet: %s.\n", av_err2str(r));
  ------------------
  |  |   86|  98.8k|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  98.8k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1229|  98.8k|        if (priv->retry_counter >= 10) {
  ------------------
  |  Branch (1229:13): [True: 16.7k, False: 82.0k]
  ------------------
 1230|  16.7k|            MP_ERR(demux, "...treating it as fatal error.\n");
  ------------------
  |  |   85|  16.7k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  16.7k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1231|  16.7k|            return false;
 1232|  16.7k|        }
 1233|  82.0k|        priv->retry_counter += 1;
 1234|  82.0k|        return true;
 1235|  98.8k|    }
 1236|  1.41M|    priv->retry_counter = 0;
 1237|       |
 1238|  1.41M|    add_new_streams(demux);
 1239|  1.41M|    update_metadata(demux);
 1240|       |
 1241|  1.41M|    mp_assert(pkt->stream_index >= 0 && pkt->stream_index < priv->num_streams);
  ------------------
  |  |   41|  1.41M|#define mp_assert assert
  ------------------
 1242|  1.41M|    struct stream_info *info = priv->streams[pkt->stream_index];
 1243|  1.41M|    struct sh_stream *stream = info->sh;
 1244|  1.41M|    AVStream *st = priv->avfc->streams[pkt->stream_index];
 1245|       |
 1246|  1.41M|    if (!demux_stream_is_selected(stream)) {
  ------------------
  |  Branch (1246:9): [True: 0, False: 1.41M]
  ------------------
 1247|      0|        av_packet_free(&pkt);
 1248|      0|        return true; // don't signal EOF if skipping a packet
 1249|      0|    }
 1250|       |
 1251|       |    // Never send additional frames for streams that are a single frame.
 1252|  1.41M|    if (stream->image && priv->format_hack.first_frame_only && pkt->pos != 0) {
  ------------------
  |  Branch (1252:9): [True: 108k, False: 1.30M]
  |  Branch (1252:26): [True: 0, False: 108k]
  |  Branch (1252:64): [True: 0, False: 0]
  ------------------
 1253|      0|        av_packet_free(&pkt);
 1254|      0|        return true;
 1255|      0|    }
 1256|       |
 1257|  1.41M|    struct demux_packet *dp = new_demux_packet_from_avpacket(demux->packet_pool, pkt);
 1258|  1.41M|    if (!dp) {
  ------------------
  |  Branch (1258:9): [True: 0, False: 1.41M]
  ------------------
 1259|      0|        av_packet_free(&pkt);
 1260|      0|        return true;
 1261|      0|    }
 1262|       |
 1263|  1.41M|    if (priv->pcm_seek_hack == st && !priv->pcm_seek_hack_packet_size)
  ------------------
  |  Branch (1263:9): [True: 16, False: 1.41M]
  |  Branch (1263:38): [True: 0, False: 16]
  ------------------
 1264|      0|        priv->pcm_seek_hack_packet_size = pkt->size;
 1265|       |
 1266|  1.41M|    dp->pts = mp_pts_from_av(pkt->pts, &st->time_base);
 1267|  1.41M|    dp->dts = mp_pts_from_av(pkt->dts, &st->time_base);
 1268|  1.41M|    dp->duration = pkt->duration * av_q2d(st->time_base);
 1269|  1.41M|    dp->pos = pkt->pos;
 1270|  1.41M|    dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
 1271|  1.41M|    dp->is_wrapped_avframe = st->codecpar->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME;
 1272|  1.41M|    av_packet_free(&pkt);
 1273|       |
 1274|  1.41M|    if (priv->format_hack.clear_filepos)
  ------------------
  |  Branch (1274:9): [True: 0, False: 1.41M]
  ------------------
 1275|      0|        dp->pos = -1;
 1276|       |
 1277|  1.41M|    dp->stream = stream->index;
 1278|       |
 1279|  1.41M|    if (priv->linearize_ts) {
  ------------------
  |  Branch (1279:9): [True: 0, False: 1.41M]
  ------------------
 1280|      0|        dp->pts = MP_ADD_PTS(dp->pts, info->ts_offset);
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1281|      0|        dp->dts = MP_ADD_PTS(dp->dts, info->ts_offset);
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1282|       |
 1283|      0|        double pts = MP_PTS_OR_DEF(dp->pts, dp->dts);
  ------------------
  |  |   61|      0|#define MP_PTS_OR_DEF(a, def) ((a) == MP_NOPTS_VALUE ? (def) : (a))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (61:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1284|      0|        if (pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1284:13): [True: 0, False: 0]
  ------------------
 1285|      0|            if (dp->keyframe) {
  ------------------
  |  Branch (1285:17): [True: 0, False: 0]
  ------------------
 1286|      0|                if (pts < info->highest_pts) {
  ------------------
  |  Branch (1286:21): [True: 0, False: 0]
  ------------------
 1287|      0|                    MP_WARN(demux, "Linearizing discontinuity: %f -> %f\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1288|      0|                            pts, info->highest_pts);
 1289|       |                    // Note: introduces a small discontinuity by a frame size.
 1290|      0|                    double diff = info->highest_pts - pts;
 1291|      0|                    dp->pts = MP_ADD_PTS(dp->pts, diff);
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1292|      0|                    dp->dts = MP_ADD_PTS(dp->dts, diff);
  ------------------
  |  |   66|      0|#define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b)))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (66:27): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1293|      0|                    pts += diff;
 1294|      0|                    info->ts_offset += diff;
 1295|      0|                    priv->any_ts_fixed = true;
 1296|      0|                }
 1297|      0|                info->last_key_pts = pts;
 1298|      0|            }
 1299|      0|            info->highest_pts = MP_PTS_MAX(info->highest_pts, pts);
  ------------------
  |  |   64|      0|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:23): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:29): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1300|      0|        }
 1301|      0|    }
 1302|       |
 1303|  1.41M|    if (st->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
  ------------------
  |  Branch (1303:9): [True: 0, False: 1.41M]
  ------------------
 1304|      0|        st->event_flags = 0;
 1305|      0|        struct mp_tags *tags = talloc_zero(NULL, struct mp_tags);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1306|      0|        mp_tags_move_from_av_dictionary(tags, &st->metadata);
 1307|      0|        double pts = MP_PTS_OR_DEF(dp->pts, dp->dts);
  ------------------
  |  |   61|      0|#define MP_PTS_OR_DEF(a, def) ((a) == MP_NOPTS_VALUE ? (def) : (a))
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  |  |  ------------------
  |  |  |  Branch (61:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1308|      0|        demux_stream_tags_changed(demux, stream, tags, pts);
 1309|      0|    }
 1310|       |
 1311|  1.41M|    *mp_pkt = dp;
 1312|  1.41M|    return true;
 1313|  1.41M|}
demux_lavf.c:update_read_stats:
  263|  1.62M|{
  264|  1.62M|    lavf_priv_t *priv = demuxer->priv;
  265|       |
  266|  1.62M|    for (int n = 0; n < priv->num_nested; n++) {
  ------------------
  |  Branch (266:21): [True: 0, False: 1.62M]
  ------------------
  267|      0|        struct nested_stream *nest = &priv->nested[n];
  268|       |
  269|      0|        int64_t cur = nest->id->bytes_read;
  270|      0|        int64_t new = cur - nest->last_bytes;
  271|      0|        nest->last_bytes = cur;
  272|      0|        demux_report_unbuffered_read_bytes(demuxer, new);
  273|      0|    }
  274|  1.62M|}
demux_lavf.c:update_metadata:
  895|  1.41M|{
  896|  1.41M|    lavf_priv_t *priv = demuxer->priv;
  897|  1.41M|    if (priv->avfc->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
  ------------------
  |  Branch (897:9): [True: 0, False: 1.41M]
  ------------------
  898|      0|        mp_tags_move_from_av_dictionary(demuxer->metadata, &priv->avfc->metadata);
  899|      0|        priv->avfc->event_flags = 0;
  900|      0|        demux_metadata_changed(demuxer);
  901|      0|    }
  902|  1.41M|}
demux_lavf.c:demux_close_lavf:
 1416|  24.4k|{
 1417|  24.4k|    lavf_priv_t *priv = demuxer->priv;
 1418|  24.4k|    if (priv) {
  ------------------
  |  Branch (1418:9): [True: 24.4k, False: 0]
  ------------------
 1419|       |        // This will be a dangling pointer; but see below.
 1420|  24.4k|        AVIOContext *leaking = priv->avfc ? priv->avfc->pb : NULL;
  ------------------
  |  Branch (1420:32): [True: 20.1k, False: 4.28k]
  ------------------
 1421|  24.4k|        avformat_close_input(&priv->avfc);
 1422|       |        // The ffmpeg garbage breaks its own API yet again: hls.c will call
 1423|       |        // io_open on the main playlist, but never calls io_close. This happens
 1424|       |        // to work out for us (since we don't really use custom I/O), but it's
 1425|       |        // still weird. Compensate.
 1426|  24.4k|        if (priv->num_nested == 1 && priv->nested[0].id == leaking)
  ------------------
  |  Branch (1426:13): [True: 0, False: 24.4k]
  |  Branch (1426:38): [True: 0, False: 0]
  ------------------
 1427|      0|            priv->num_nested = 0;
 1428|  24.4k|        if (priv->num_nested) {
  ------------------
  |  Branch (1428:13): [True: 0, False: 24.4k]
  ------------------
 1429|      0|            MP_WARN(demuxer, "Leaking %d nested connections (FFmpeg bug).\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1430|      0|                    priv->num_nested);
 1431|      0|        }
 1432|  24.4k|        if (priv->pb)
  ------------------
  |  Branch (1432:13): [True: 21.0k, False: 3.46k]
  ------------------
 1433|  21.0k|            av_freep(&priv->pb->buffer);
 1434|  24.4k|        av_freep(&priv->pb);
 1435|  52.7k|        for (int n = 0; n < priv->num_streams; n++) {
  ------------------
  |  Branch (1435:25): [True: 28.3k, False: 24.4k]
  ------------------
 1436|  28.3k|            struct stream_info *info = priv->streams[n];
 1437|  28.3k|            if (info->sh)
  ------------------
  |  Branch (1437:17): [True: 25.8k, False: 2.42k]
  ------------------
 1438|  25.8k|                avcodec_parameters_free(&info->sh->codec->lav_codecpar);
 1439|  28.3k|        }
 1440|  24.4k|        if (priv->own_stream)
  ------------------
  |  Branch (1440:13): [True: 122, False: 24.3k]
  ------------------
 1441|    122|            free_stream(priv->stream);
 1442|  24.4k|        if (priv->av_opts)
  ------------------
  |  Branch (1442:13): [True: 0, False: 24.4k]
  ------------------
 1443|      0|            av_dict_free(&priv->av_opts);
 1444|  24.4k|        talloc_free(priv);
  ------------------
  |  |   47|  24.4k|#define talloc_free                     ta_free
  ------------------
 1445|  24.4k|        demuxer->priv = NULL;
 1446|  24.4k|    }
 1447|  24.4k|}
demux_lavf.c:demux_seek_lavf:
 1326|  63.2k|{
 1327|  63.2k|    lavf_priv_t *priv = demuxer->priv;
 1328|  63.2k|    int avsflags = 0;
 1329|  63.2k|    int64_t seek_pts_av = 0;
 1330|  63.2k|    int seek_stream = -1;
 1331|       |
 1332|  63.2k|    if (priv->any_ts_fixed)  {
  ------------------
  |  Branch (1332:9): [True: 0, False: 63.2k]
  ------------------
 1333|       |        // helpful message to piss of users
 1334|      0|        MP_WARN(demuxer, "Some timestamps returned by the demuxer were linearized. "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1335|      0|                         "A low level seek was requested; this won't work due to "
 1336|      0|                         "restrictions in libavformat's API. You may have more "
 1337|      0|                         "luck by enabling or enlarging the mpv cache.\n");
 1338|      0|    }
 1339|       |
 1340|  63.2k|    if (priv->linearize_ts < 0)
  ------------------
  |  Branch (1340:9): [True: 0, False: 63.2k]
  ------------------
 1341|      0|        priv->linearize_ts = 0;
 1342|       |
 1343|  63.2k|    if (!(flags & SEEK_FORWARD))
  ------------------
  |  |   93|  63.2k|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
  |  Branch (1343:9): [True: 63.2k, False: 0]
  ------------------
 1344|  63.2k|        avsflags = AVSEEK_FLAG_BACKWARD;
 1345|       |
 1346|  63.2k|    if (flags & SEEK_FACTOR) {
  ------------------
  |  |   92|  63.2k|#define SEEK_FACTOR   (1 << 1)      // argument is in range [0,1]
  ------------------
  |  Branch (1346:9): [True: 0, False: 63.2k]
  ------------------
 1347|      0|        struct stream *s = priv->stream;
 1348|      0|        int64_t end = s ? stream_get_size(s) : -1;
  ------------------
  |  Branch (1348:23): [True: 0, False: 0]
  ------------------
 1349|      0|        if (end > 0 && demuxer->ts_resets_possible &&
  ------------------
  |  Branch (1349:13): [True: 0, False: 0]
  |  Branch (1349:24): [True: 0, False: 0]
  ------------------
 1350|      0|            !(priv->avif_flags & AVFMT_NO_BYTE_SEEK))
  ------------------
  |  Branch (1350:13): [True: 0, False: 0]
  ------------------
 1351|      0|        {
 1352|      0|            avsflags |= AVSEEK_FLAG_BYTE;
 1353|      0|            seek_pts_av = end * seek_pts;
 1354|      0|        } else if (priv->avfc->duration != 0 &&
  ------------------
  |  Branch (1354:20): [True: 0, False: 0]
  ------------------
 1355|      0|                   priv->avfc->duration != AV_NOPTS_VALUE)
  ------------------
  |  Branch (1355:20): [True: 0, False: 0]
  ------------------
 1356|      0|        {
 1357|      0|            seek_pts_av = seek_pts * priv->avfc->duration;
 1358|      0|        }
 1359|  63.2k|    } else {
 1360|  63.2k|        if (!(flags & SEEK_FORWARD))
  ------------------
  |  |   93|  63.2k|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
  |  Branch (1360:13): [True: 63.2k, False: 0]
  ------------------
 1361|  63.2k|            seek_pts -= priv->seek_delay;
 1362|  63.2k|        seek_pts_av = seek_pts * AV_TIME_BASE;
 1363|  63.2k|    }
 1364|       |
 1365|       |    // Hack to make wav seeking "deterministic". Without this, features like
 1366|       |    // backward playback won't work.
 1367|  63.2k|    if (priv->pcm_seek_hack && !priv->pcm_seek_hack_packet_size) {
  ------------------
  |  Branch (1367:9): [True: 2, False: 63.2k]
  |  Branch (1367:32): [True: 2, False: 0]
  ------------------
 1368|       |        // This might for example be the initial seek. Fuck it up like the
 1369|       |        // bullshit it is.
 1370|      2|        AVPacket *pkt = av_packet_alloc();
 1371|      2|        MP_HANDLE_OOM(pkt);
  ------------------
  |  |  176|      2|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|      2|        void *oom_p_ = (x);     \
  |  |  178|      2|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 2]
  |  |  ------------------
  |  |  179|      2|            abort();            \
  |  |  180|      2|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1372|      2|        if (av_read_frame(priv->avfc, pkt) >= 0)
  ------------------
  |  Branch (1372:13): [True: 2, False: 0]
  ------------------
 1373|      2|            priv->pcm_seek_hack_packet_size = pkt->size;
 1374|      2|        av_packet_free(&pkt);
 1375|      2|        add_new_streams(demuxer);
 1376|      2|    }
 1377|  63.2k|    if (priv->pcm_seek_hack && priv->pcm_seek_hack_packet_size &&
  ------------------
  |  Branch (1377:9): [True: 2, False: 63.2k]
  |  Branch (1377:32): [True: 2, False: 0]
  ------------------
 1378|  63.2k|        !(avsflags & AVSEEK_FLAG_BYTE))
  ------------------
  |  Branch (1378:9): [True: 2, False: 0]
  ------------------
 1379|      2|    {
 1380|      2|        int samples = priv->pcm_seek_hack_packet_size /
 1381|      2|                      priv->pcm_seek_hack->codecpar->block_align;
 1382|      2|        if (samples > 0) {
  ------------------
  |  Branch (1382:13): [True: 2, False: 0]
  ------------------
 1383|      2|            MP_VERBOSE(demuxer, "using bullshit libavformat PCM seek hack\n");
  ------------------
  |  |   88|      2|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      2|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1384|      2|            double pts = seek_pts_av / (double)AV_TIME_BASE;
 1385|      2|            seek_pts_av = pts / av_q2d(priv->pcm_seek_hack->time_base);
 1386|      2|            int64_t align = seek_pts_av % samples;
 1387|      2|            seek_pts_av -= align;
 1388|      2|            seek_stream = priv->pcm_seek_hack->index;
 1389|      2|        }
 1390|      2|    }
 1391|       |
 1392|  63.2k|    int r = av_seek_frame(priv->avfc, seek_stream, seek_pts_av, avsflags);
 1393|  63.2k|    if (r < 0 && (avsflags & AVSEEK_FLAG_BACKWARD)) {
  ------------------
  |  Branch (1393:9): [True: 60.3k, False: 2.87k]
  |  Branch (1393:18): [True: 60.3k, False: 0]
  ------------------
 1394|       |        // When seeking before the beginning of the file, and seeking fails,
 1395|       |        // try again without the backwards flag to make it seek to the
 1396|       |        // beginning.
 1397|  60.3k|        avsflags &= ~AVSEEK_FLAG_BACKWARD;
 1398|  60.3k|        r = av_seek_frame(priv->avfc, seek_stream, seek_pts_av, avsflags);
 1399|  60.3k|    }
 1400|       |
 1401|  63.2k|    if (r < 0) {
  ------------------
  |  Branch (1401:9): [True: 60.3k, False: 2.87k]
  ------------------
 1402|  60.3k|        char buf[180];
 1403|  60.3k|        av_strerror(r, buf, sizeof(buf));
 1404|  60.3k|        MP_VERBOSE(demuxer, "Seek failed (%s)\n", buf);
  ------------------
  |  |   88|  60.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  60.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1405|  60.3k|    }
 1406|       |
 1407|  63.2k|    update_read_stats(demuxer);
 1408|  63.2k|}
demux_lavf.c:demux_lavf_switched_tracks:
 1411|   159k|{
 1412|   159k|    select_tracks(demuxer, 0);
 1413|   159k|}

demux_mf.c:demux_open_mf:
  372|  4.80k|{
  373|  4.80k|    mf_t *mf;
  374|       |
  375|  4.80k|    if (strncmp(demuxer->stream->url, "mf://", 5) == 0 &&
  ------------------
  |  Branch (375:9): [True: 0, False: 4.80k]
  ------------------
  376|  4.80k|        demuxer->stream->info && strcmp(demuxer->stream->info->name, "mf") == 0)
  ------------------
  |  Branch (376:9): [True: 0, False: 0]
  |  Branch (376:34): [True: 0, False: 0]
  ------------------
  377|      0|    {
  378|      0|        mf = open_mf_pattern(demuxer, demuxer, demuxer->stream->url + 5);
  379|  4.80k|    } else {
  380|  4.80k|        mf = open_mf_single(demuxer, demuxer->log, demuxer->stream->url);
  381|  4.80k|        int bog = 0;
  382|  4.80k|        MP_TARRAY_APPEND(mf, mf->streams, bog, demuxer->stream);
  ------------------
  |  |  105|  4.80k|    do {                                            \
  |  |  106|  4.80k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.80k|    do {                                            \
  |  |  |  |   97|  4.80k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.80k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.80k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.80k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.80k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.80k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.80k|    do {                                                        \
  |  |  |  |  |  |   89|  4.80k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.80k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.80k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.80k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.80k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.80k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.80k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.80k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.80k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.80k|        (idxvar)++;                                 \
  |  |  109|  4.80k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  383|  4.80k|    }
  384|       |
  385|  4.80k|    if (!mf || mf->nr_of_files < 1)
  ------------------
  |  Branch (385:9): [True: 0, False: 4.80k]
  |  Branch (385:16): [True: 0, False: 4.80k]
  ------------------
  386|      0|        goto error;
  387|       |
  388|  4.80k|    const char *codec = mp_map_mimetype_to_video_codec(demuxer->stream->mime_type);
  389|  4.80k|    if (!codec || (demuxer->opts->mf_type && demuxer->opts->mf_type[0]))
  ------------------
  |  Branch (389:9): [True: 4.80k, False: 0]
  |  Branch (389:20): [True: 0, False: 0]
  |  Branch (389:46): [True: 0, False: 0]
  ------------------
  390|  4.80k|        codec = probe_format(mf, demuxer->opts->mf_type, check);
  391|  4.80k|    if (!codec)
  ------------------
  |  Branch (391:9): [True: 4.58k, False: 225]
  ------------------
  392|  4.58k|        goto error;
  393|       |
  394|    225|    mf->curr_frame = 0;
  395|       |
  396|       |    // create a new video stream header
  397|    225|    struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO);
  398|    225|    if (mf->nr_of_files == 1) {
  ------------------
  |  Branch (398:9): [True: 225, False: 0]
  ------------------
  399|    225|        MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
  ------------------
  |  |   88|    225|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    225|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  400|    225|        sh->image = true;
  401|    225|    }
  402|       |
  403|    225|    struct mp_codec_params *c = sh->codec;
  404|    225|    c->codec = codec;
  405|    225|    c->disp_w = 0;
  406|    225|    c->disp_h = 0;
  407|    225|    c->fps = demuxer->opts->mf_fps;
  408|    225|    c->reliable_fps = true;
  409|       |
  410|    225|    demux_add_sh_stream(demuxer, sh);
  411|       |
  412|    225|    mf->sh = sh;
  413|    225|    demuxer->priv = (void *)mf;
  414|    225|    demuxer->seekable = true;
  415|    225|    demuxer->duration = mf->nr_of_files / mf->sh->codec->fps;
  416|       |
  417|    225|    return 0;
  418|       |
  419|  4.58k|error:
  420|  4.58k|    return -1;
  421|  4.80k|}
demux_mf.c:mf_add:
   53|  4.80k|{
   54|  4.80k|    char *entry = talloc_strdup(mf, fname);
  ------------------
  |  |   50|  4.80k|#define talloc_strdup                   ta_xstrdup
  ------------------
   55|  4.80k|    MP_TARRAY_APPEND(mf, mf->names, mf->nr_of_files, entry);
  ------------------
  |  |  105|  4.80k|    do {                                            \
  |  |  106|  4.80k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.80k|    do {                                            \
  |  |  |  |   97|  4.80k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.80k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.80k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.80k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.80k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.80k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.80k|    do {                                                        \
  |  |  |  |  |  |   89|  4.80k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.80k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.80k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.80k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.80k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.80k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.80k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.80k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.80k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.80k|        (idxvar)++;                                 \
  |  |  109|  4.80k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   56|  4.80k|}
demux_mf.c:open_mf_single:
  219|  4.80k|{
  220|  4.80k|    mf_t *mf = talloc_zero(talloc_ctx, mf_t);
  ------------------
  |  |   27|  4.80k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  4.80k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  4.80k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  221|  4.80k|    mf->log = log;
  222|  4.80k|    mf_add(mf, filename);
  223|  4.80k|    return mf;
  224|  4.80k|}
demux_mf.c:probe_format:
  348|  4.80k|{
  349|  4.80k|    if (check > DEMUX_CHECK_REQUEST)
  ------------------
  |  Branch (349:9): [True: 2.72k, False: 2.08k]
  ------------------
  350|  2.72k|        return NULL;
  351|  2.08k|    char *org_type = type;
  352|  2.08k|    if (!type || !type[0]) {
  ------------------
  |  Branch (352:9): [True: 2.08k, False: 0]
  |  Branch (352:18): [True: 0, False: 0]
  ------------------
  353|  2.08k|        char *p = strrchr(mf->names[0], '.');
  354|  2.08k|        if (p)
  ------------------
  |  Branch (354:13): [True: 1.16k, False: 920]
  ------------------
  355|  1.16k|            type = p + 1;
  356|  2.08k|    }
  357|  99.5k|    for (int i = 0; type2format[i].type; i++) {
  ------------------
  |  Branch (357:21): [True: 97.6k, False: 1.85k]
  ------------------
  358|  97.6k|        if (type && strcasecmp(type, type2format[i].type) == 0)
  ------------------
  |  Branch (358:13): [True: 51.6k, False: 46.0k]
  |  Branch (358:21): [True: 225, False: 51.4k]
  ------------------
  359|    225|            return type2format[i].codec;
  360|  97.6k|    }
  361|  1.85k|    if (check == DEMUX_CHECK_REQUEST) {
  ------------------
  |  Branch (361:9): [True: 0, False: 1.85k]
  ------------------
  362|      0|        if (!org_type) {
  ------------------
  |  Branch (362:13): [True: 0, False: 0]
  ------------------
  363|      0|            MP_ERR(mf, "file type was not set! (try --mf-type=ext)\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  364|      0|        } else {
  365|      0|            MP_ERR(mf, "--mf-type set to an unknown codec!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  366|      0|        }
  367|      0|    }
  368|  1.85k|    return NULL;
  369|  2.08k|}
demux_mf.c:demux_mf_read_packet:
  242|    446|{
  243|    446|    mf_t *mf = demuxer->priv;
  244|    446|    if (mf->curr_frame >= mf->nr_of_files)
  ------------------
  |  Branch (244:9): [True: 223, False: 223]
  ------------------
  245|    223|        return false;
  246|    223|    bool ok = false;
  247|       |
  248|    223|    struct stream *entry_stream = NULL;
  249|    223|    if (mf->streams)
  ------------------
  |  Branch (249:9): [True: 223, False: 0]
  ------------------
  250|    223|        entry_stream = mf->streams[mf->curr_frame];
  251|    223|    struct stream *stream = entry_stream;
  252|    223|    if (!stream) {
  ------------------
  |  Branch (252:9): [True: 0, False: 223]
  ------------------
  253|      0|        char *filename = mf->names[mf->curr_frame];
  254|      0|        if (filename) {
  ------------------
  |  Branch (254:13): [True: 0, False: 0]
  ------------------
  255|      0|            stream = stream_create(filename, demuxer->stream_origin | STREAM_READ,
  ------------------
  |  |   41|      0|#define STREAM_READ               0
  ------------------
  256|      0|                                   demuxer->cancel, demuxer->global);
  257|      0|        }
  258|      0|    }
  259|       |
  260|    223|    if (stream) {
  ------------------
  |  Branch (260:9): [True: 223, False: 0]
  ------------------
  261|    223|        stream_seek(stream, 0);
  262|    223|        bstr data = stream_read_complete(stream, NULL, MF_MAX_FILE_SIZE);
  ------------------
  |  |   39|    223|#define MF_MAX_FILE_SIZE (1024 * 1024 * 256)
  ------------------
  263|    223|        if (data.len) {
  ------------------
  |  Branch (263:13): [True: 223, False: 0]
  ------------------
  264|    223|            demux_packet_t *dp = new_demux_packet(demuxer->packet_pool, data.len);
  265|    223|            if (dp) {
  ------------------
  |  Branch (265:17): [True: 223, False: 0]
  ------------------
  266|    223|                memcpy(dp->buffer, data.start, data.len);
  267|    223|                dp->pts = mf->curr_frame / mf->sh->codec->fps;
  268|    223|                dp->keyframe = true;
  269|    223|                dp->stream = mf->sh->index;
  270|    223|                *pkt = dp;
  271|    223|                ok = true;
  272|    223|            }
  273|    223|        }
  274|    223|        talloc_free(data.start);
  ------------------
  |  |   47|    223|#define talloc_free                     ta_free
  ------------------
  275|    223|    }
  276|       |
  277|    223|    if (stream && stream != entry_stream)
  ------------------
  |  Branch (277:9): [True: 223, False: 0]
  |  Branch (277:19): [True: 0, False: 223]
  ------------------
  278|      0|        free_stream(stream);
  279|       |
  280|    223|    mf->curr_frame++;
  281|       |
  282|    223|    if (!ok)
  ------------------
  |  Branch (282:9): [True: 0, False: 223]
  ------------------
  283|    223|        MP_ERR(demuxer, "error reading image file\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  284|       |
  285|    223|    return true;
  286|    446|}
demux_mf.c:demux_close_mf:
  424|  4.80k|{
  425|  4.80k|}

demux_mkv.c:demux_mkv_open:
 2390|  24.4k|{
 2391|  24.4k|    stream_t *s = demuxer->stream;
 2392|  24.4k|    mkv_demuxer_t *mkv_d;
 2393|  24.4k|    int64_t start_pos;
 2394|  24.4k|    int64_t end_pos;
 2395|       |
 2396|  24.4k|    mkv_d = talloc_zero(demuxer, struct mkv_demuxer);
  ------------------
  |  |   27|  24.4k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  24.4k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  24.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2397|  24.4k|    demuxer->priv = mkv_d;
 2398|  24.4k|    mkv_d->tc_scale = 1000000;
 2399|  24.4k|    mkv_d->a_skip_preroll = 1;
 2400|  24.4k|    mkv_d->skip_to_timecode = INT64_MIN;
 2401|       |
 2402|  24.4k|    if (demuxer->params)
  ------------------
  |  Branch (2402:9): [True: 24.4k, False: 0]
  ------------------
 2403|  24.4k|        mkv_d->probably_webm_dash_init = demuxer->params->init_fragment.len > 0;
 2404|       |
 2405|       |    // Make sure you can seek back after read_ebml_header() if no EBML ID.
 2406|  24.4k|    if (stream_read_peek(s, &(char[4]){0}, 4) != 4)
  ------------------
  |  Branch (2406:9): [True: 100, False: 24.3k]
  ------------------
 2407|    100|        return -1;
 2408|  24.3k|    if (!read_ebml_header(demuxer))
  ------------------
  |  Branch (2408:9): [True: 24.2k, False: 88]
  ------------------
 2409|  24.2k|        return -1;
 2410|     88|    MP_DBG(demuxer, "Found the head...\n");
  ------------------
  |  |   89|     88|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     88|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2411|       |
 2412|     88|    if (!read_mkv_segment_header(demuxer, &end_pos))
  ------------------
  |  Branch (2412:9): [True: 88, False: 0]
  ------------------
 2413|     88|        return -1;
 2414|       |
 2415|      0|    mkv_d->segment_start = stream_tell(s);
 2416|      0|    mkv_d->segment_end = end_pos;
 2417|       |
 2418|      0|    struct MPOpts *mp_opts = mp_get_config_group(mkv_d, demuxer->global, &mp_opt_root);
 2419|      0|    mkv_d->edition_id = mp_opts->edition_id;
 2420|      0|    talloc_free(mp_opts);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2421|       |
 2422|      0|    mkv_d->opts = mp_get_config_group(mkv_d, demuxer->global, &demux_mkv_conf);
 2423|       |
 2424|      0|    if (demuxer->params && demuxer->params->matroska_was_valid)
  ------------------
  |  Branch (2424:9): [True: 0, False: 0]
  |  Branch (2424:28): [True: 0, False: 0]
  ------------------
 2425|      0|        *demuxer->params->matroska_was_valid = true;
 2426|       |
 2427|      0|    while (1) {
  ------------------
  |  Branch (2427:12): [Folded - Ignored]
  ------------------
 2428|      0|        start_pos = stream_tell(s);
 2429|      0|        uint32_t id = ebml_read_id(s);
 2430|      0|        if (s->eof) {
  ------------------
  |  Branch (2430:13): [True: 0, False: 0]
  ------------------
 2431|      0|            if (!mkv_d->probably_webm_dash_init)
  ------------------
  |  Branch (2431:17): [True: 0, False: 0]
  ------------------
 2432|      0|                MP_WARN(demuxer, "Unexpected end of file (no clusters found)\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2433|      0|            break;
 2434|      0|        }
 2435|      0|        if (id == MATROSKA_ID_CLUSTER) {
  ------------------
  |  |   28|      0|#define MATROSKA_ID_CLUSTER                      0x1f43b675
  ------------------
  |  Branch (2435:13): [True: 0, False: 0]
  ------------------
 2436|      0|            MP_DBG(demuxer, "|+ found cluster\n");
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2437|      0|            mkv_d->cluster_start = start_pos;
 2438|      0|            break;
 2439|      0|        }
 2440|      0|        int res = read_header_element(demuxer, id, start_pos);
 2441|      0|        if (res < 0)
  ------------------
  |  Branch (2441:13): [True: 0, False: 0]
  ------------------
 2442|      0|            return -1;
 2443|      0|    }
 2444|       |
 2445|      0|    int64_t end = stream_get_size(s);
 2446|       |
 2447|       |    // Read headers that come after the first cluster (i.e. require seeking).
 2448|       |    // Note: reading might increase ->num_headers.
 2449|       |    //       Likewise, ->headers might be reallocated.
 2450|      0|    int only_cue = -1;
 2451|      0|    for (int n = 0; n < mkv_d->num_headers; n++) {
  ------------------
  |  Branch (2451:21): [True: 0, False: 0]
  ------------------
 2452|      0|        struct header_elem *elem = &mkv_d->headers[n];
 2453|      0|        if (elem->parsed)
  ------------------
  |  Branch (2453:13): [True: 0, False: 0]
  ------------------
 2454|      0|            continue;
 2455|       |        // Warn against incomplete files and skip headers outside of range.
 2456|      0|        if (elem->pos >= end || !s->seekable) {
  ------------------
  |  Branch (2456:13): [True: 0, False: 0]
  |  Branch (2456:33): [True: 0, False: 0]
  ------------------
 2457|      0|            elem->parsed = true; // don't bother if file is incomplete
 2458|      0|            if (end < 0 || !s->seekable) {
  ------------------
  |  Branch (2458:17): [True: 0, False: 0]
  |  Branch (2458:28): [True: 0, False: 0]
  ------------------
 2459|      0|                MP_WARN(demuxer, "Stream is not seekable or unknown size, "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2460|      0|                        "not reading mkv metadata at end of file.\n");
 2461|      0|            } else if (!mkv_d->eof_warning &&
  ------------------
  |  Branch (2461:24): [True: 0, False: 0]
  ------------------
 2462|      0|                       !(mkv_d->probably_webm_dash_init &&  elem->pos == end))
  ------------------
  |  Branch (2462:26): [True: 0, False: 0]
  |  Branch (2462:61): [True: 0, False: 0]
  ------------------
 2463|      0|            {
 2464|      0|                MP_WARN(demuxer, "mkv metadata beyond end of file - incomplete "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2465|      0|                        "file?\n");
 2466|      0|                mkv_d->eof_warning = true;
 2467|      0|            }
 2468|      0|            continue;
 2469|      0|        }
 2470|      0|        only_cue = only_cue < 0 && elem->id == MATROSKA_ID_CUES;
  ------------------
  |  |  126|      0|#define MATROSKA_ID_CUES                         0x1c53bb6b
  ------------------
  |  Branch (2470:20): [True: 0, False: 0]
  |  Branch (2470:36): [True: 0, False: 0]
  ------------------
 2471|      0|    }
 2472|       |
 2473|       |    // If there's only 1 needed element, and it's the cues, defer reading.
 2474|      0|    if (only_cue == 1) {
  ------------------
  |  Branch (2474:9): [True: 0, False: 0]
  ------------------
 2475|       |        // Read cues when they are needed, to avoid seeking on opening.
 2476|      0|        MP_VERBOSE(demuxer, "Deferring reading cues.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2477|      0|    } else {
 2478|       |        // Read them by ascending position to reduce unneeded seeks.
 2479|       |        // O(n^2) because the number of elements is very low.
 2480|      0|        while (1) {
  ------------------
  |  Branch (2480:16): [Folded - Ignored]
  ------------------
 2481|      0|            struct header_elem *lowest = NULL;
 2482|      0|            for (int n = 0; n < mkv_d->num_headers; n++) {
  ------------------
  |  Branch (2482:29): [True: 0, False: 0]
  ------------------
 2483|      0|                struct header_elem *elem = &mkv_d->headers[n];
 2484|      0|                if (elem->parsed)
  ------------------
  |  Branch (2484:21): [True: 0, False: 0]
  ------------------
 2485|      0|                    continue;
 2486|      0|                if (!lowest || elem->pos < lowest->pos)
  ------------------
  |  Branch (2486:21): [True: 0, False: 0]
  |  Branch (2486:32): [True: 0, False: 0]
  ------------------
 2487|      0|                    lowest = elem;
 2488|      0|            }
 2489|       |
 2490|      0|            if (!lowest)
  ------------------
  |  Branch (2490:17): [True: 0, False: 0]
  ------------------
 2491|      0|                break;
 2492|       |
 2493|      0|            if (read_deferred_element(demuxer, lowest) < 0)
  ------------------
  |  Branch (2493:17): [True: 0, False: 0]
  ------------------
 2494|      0|                return -1;
 2495|      0|        }
 2496|      0|    }
 2497|       |
 2498|      0|    if (!stream_seek(s, start_pos)) {
  ------------------
  |  Branch (2498:9): [True: 0, False: 0]
  ------------------
 2499|      0|        MP_ERR(demuxer, "Couldn't seek back after reading headers?\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2500|      0|        return -1;
 2501|      0|    }
 2502|       |
 2503|      0|    MP_VERBOSE(demuxer, "All headers are parsed!\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2504|       |
 2505|      0|    display_create_tracks(demuxer);
 2506|      0|    add_coverart(demuxer);
 2507|      0|    process_tags(demuxer);
 2508|       |
 2509|      0|    probe_first_timestamp(demuxer);
 2510|      0|    if (mkv_d->opts->probe_duration)
  ------------------
  |  Branch (2510:9): [True: 0, False: 0]
  ------------------
 2511|      0|        probe_last_timestamp(demuxer, start_pos);
 2512|      0|    probe_x264_garbage(demuxer);
 2513|      0|    probe_if_image(demuxer);
 2514|       |
 2515|      0|    return 0;
 2516|      0|}
demux_mkv.c:read_ebml_header:
 2303|  24.3k|{
 2304|  24.3k|    mkv_demuxer_t *mkv_d = demuxer->priv;
 2305|  24.3k|    stream_t *s = demuxer->stream;
 2306|       |
 2307|  24.3k|    if (ebml_read_id(s) != EBML_ID_EBML)
  ------------------
  |  |    3|  24.3k|#define EBML_ID_EBML                             0x1a45dfa3
  ------------------
  |  Branch (2307:9): [True: 24.2k, False: 99]
  ------------------
 2308|  24.2k|        return 0;
 2309|     99|    struct ebml_ebml ebml_master = {0};
 2310|     99|    struct ebml_parse_ctx parse_ctx = { demuxer->log, .no_error_messages = true };
 2311|     99|    if (ebml_read_element(s, &parse_ctx, &ebml_master, &ebml_ebml_desc) < 0)
  ------------------
  |  Branch (2311:9): [True: 11, False: 88]
  ------------------
 2312|     11|        return 0;
 2313|     88|    bool is_matroska = false, is_webm = false;
 2314|     88|    if (!ebml_master.doc_type) {
  ------------------
  |  Branch (2314:9): [True: 88, False: 0]
  ------------------
 2315|     88|        MP_VERBOSE(demuxer, "File has EBML header but no doctype. "
  ------------------
  |  |   88|     88|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     88|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2316|     88|                   "Assuming \"matroska\".\n");
 2317|     88|        is_matroska = true;
 2318|     88|    } else if (strcmp(ebml_master.doc_type, "matroska") == 0) {
  ------------------
  |  Branch (2318:16): [True: 0, False: 0]
  ------------------
 2319|      0|        is_matroska = true;
 2320|      0|    } else if (strcmp(ebml_master.doc_type, "webm") == 0) {
  ------------------
  |  Branch (2320:16): [True: 0, False: 0]
  ------------------
 2321|      0|        is_webm = true;
 2322|      0|    }
 2323|     88|    if (!is_matroska && !is_webm) {
  ------------------
  |  Branch (2323:9): [True: 0, False: 88]
  |  Branch (2323:25): [True: 0, False: 0]
  ------------------
 2324|      0|        MP_TRACE(demuxer, "no head found\n");
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2325|      0|        talloc_free(parse_ctx.talloc_ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2326|      0|        return 0;
 2327|      0|    }
 2328|     88|    mkv_d->probably_webm_dash_init &= is_webm;
 2329|     88|    if (ebml_master.doc_type_read_version > 2) {
  ------------------
  |  Branch (2329:9): [True: 0, False: 88]
  ------------------
 2330|      0|        MP_WARN(demuxer, "This looks like a Matroska file, "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2331|      0|                "but we don't support format version %"PRIu64"\n",
 2332|      0|                ebml_master.doc_type_read_version);
 2333|      0|        talloc_free(parse_ctx.talloc_ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2334|      0|        return 0;
 2335|      0|    }
 2336|     88|    if ((ebml_master.n_ebml_read_version
  ------------------
  |  Branch (2336:10): [True: 0, False: 88]
  ------------------
 2337|     88|         && ebml_master.ebml_read_version != EBML_VERSION)
  ------------------
  |  |   31|      0|#define EBML_VERSION 1
  ------------------
  |  Branch (2337:13): [True: 0, False: 0]
  ------------------
 2338|     88|        || (ebml_master.n_ebml_max_size_length
  ------------------
  |  Branch (2338:13): [True: 0, False: 88]
  ------------------
 2339|     88|            && ebml_master.ebml_max_size_length > 8)
  ------------------
  |  Branch (2339:16): [True: 0, False: 0]
  ------------------
 2340|     88|        || (ebml_master.n_ebml_max_id_length
  ------------------
  |  Branch (2340:13): [True: 0, False: 88]
  ------------------
 2341|     88|            && ebml_master.ebml_max_id_length != 4))
  ------------------
  |  Branch (2341:16): [True: 0, False: 0]
  ------------------
 2342|      0|    {
 2343|      0|        MP_WARN(demuxer, "This looks like a Matroska file, "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2344|      0|                "but the header has bad parameters\n");
 2345|      0|        talloc_free(parse_ctx.talloc_ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2346|      0|        return 0;
 2347|      0|    }
 2348|     88|    talloc_free(parse_ctx.talloc_ctx);
  ------------------
  |  |   47|     88|#define talloc_free                     ta_free
  ------------------
 2349|       |
 2350|     88|    return 1;
 2351|     88|}
demux_mkv.c:read_mkv_segment_header:
 2354|     88|{
 2355|     88|    stream_t *s = demuxer->stream;
 2356|     88|    int num_skip = 0;
 2357|     88|    if (demuxer->params)
  ------------------
  |  Branch (2357:9): [True: 88, False: 0]
  ------------------
 2358|     88|        num_skip = demuxer->params->matroska_wanted_segment;
 2359|       |
 2360|     88|    while (stream_read_peek(s, &(char){0}, 1)) {
  ------------------
  |  Branch (2360:12): [True: 63, False: 25]
  ------------------
 2361|     63|        if (ebml_read_id(s) != MATROSKA_ID_SEGMENT) {
  ------------------
  |  |   13|     63|#define MATROSKA_ID_SEGMENT                      0x18538067
  ------------------
  |  Branch (2361:13): [True: 63, False: 0]
  ------------------
 2362|     63|            MP_VERBOSE(demuxer, "segment not found\n");
  ------------------
  |  |   88|     63|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     63|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2363|     63|            return 0;
 2364|     63|        }
 2365|      0|        MP_DBG(demuxer, "+ a segment...\n");
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2366|      0|        uint64_t len = ebml_read_length(s);
 2367|      0|        *segment_end = (len == EBML_UINT_INVALID) ? 0 : stream_tell(s) + len;
  ------------------
  |  |   78|      0|#define EBML_UINT_INVALID   UINT64_MAX
  ------------------
  |  Branch (2367:24): [True: 0, False: 0]
  ------------------
 2368|      0|        if (num_skip <= 0)
  ------------------
  |  Branch (2368:13): [True: 0, False: 0]
  ------------------
 2369|      0|            return 1;
 2370|      0|        num_skip--;
 2371|      0|        MP_DBG(demuxer, "  (skipping)\n");
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2372|      0|        if (*segment_end <= 0)
  ------------------
  |  Branch (2372:13): [True: 0, False: 0]
  ------------------
 2373|      0|            break;
 2374|      0|        if (*segment_end >= stream_get_size(s))
  ------------------
  |  Branch (2374:13): [True: 0, False: 0]
  ------------------
 2375|      0|            return 0;
 2376|      0|        if (!stream_seek(s, *segment_end)) {
  ------------------
  |  Branch (2376:13): [True: 0, False: 0]
  ------------------
 2377|      0|            MP_WARN(demuxer, "Failed to seek in file\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2378|      0|            return 0;
 2379|      0|        }
 2380|       |        // Segments are like concatenated Matroska files
 2381|      0|        if (!read_ebml_header(demuxer))
  ------------------
  |  Branch (2381:13): [True: 0, False: 0]
  ------------------
 2382|      0|            return 0;
 2383|      0|    }
 2384|       |
 2385|     25|    MP_VERBOSE(demuxer, "End of file, no further segments.\n");
  ------------------
  |  |   88|     25|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     25|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2386|     25|    return 0;
 2387|     88|}
demux_mkv.c:mkv_seek_reset:
 2715|  24.4k|{
 2716|  24.4k|    mkv_demuxer_t *mkv_d = demuxer->priv;
 2717|       |
 2718|  24.4k|    for (int i = 0; i < mkv_d->num_tracks; i++) {
  ------------------
  |  Branch (2718:21): [True: 0, False: 24.4k]
  ------------------
 2719|      0|        mkv_track_t *track = mkv_d->tracks[i];
 2720|      0|        if (track->av_parser)
  ------------------
  |  Branch (2720:13): [True: 0, False: 0]
  ------------------
 2721|      0|            av_parser_close(track->av_parser);
 2722|      0|        track->av_parser = NULL;
 2723|      0|        avcodec_free_context(&track->av_parser_codec);
 2724|      0|    }
 2725|       |
 2726|  24.4k|    for (int n = 0; n < mkv_d->num_blocks; n++)
  ------------------
  |  Branch (2726:21): [True: 0, False: 24.4k]
  ------------------
 2727|      0|        free_block(&mkv_d->blocks[n]);
 2728|  24.4k|    mkv_d->num_blocks = 0;
 2729|       |
 2730|  24.4k|    for (int n = 0; n < mkv_d->num_packets; n++)
  ------------------
  |  Branch (2730:21): [True: 0, False: 24.4k]
  ------------------
 2731|      0|        talloc_free(mkv_d->packets[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 2732|  24.4k|    mkv_d->num_packets = 0;
 2733|       |
 2734|  24.4k|    mkv_d->skip_to_timecode = INT64_MIN;
 2735|  24.4k|}
demux_mkv.c:mkv_free:
 3638|  24.4k|{
 3639|  24.4k|    struct mkv_demuxer *mkv_d = demuxer->priv;
 3640|  24.4k|    if (!mkv_d)
  ------------------
  |  Branch (3640:9): [True: 0, False: 24.4k]
  ------------------
 3641|      0|        return;
 3642|  24.4k|    mkv_seek_reset(demuxer);
 3643|  24.4k|    for (int i = 0; i < mkv_d->num_tracks; i++)
  ------------------
  |  Branch (3643:21): [True: 0, False: 24.4k]
  ------------------
 3644|      0|        demux_mkv_free_trackentry(mkv_d->tracks[i]);
 3645|  24.4k|}

demux_mpv.c:open_mpv:
   24|  3.94k|{
   25|  3.94k|    if (check != DEMUX_CHECK_REQUEST)
  ------------------
  |  Branch (25:9): [True: 3.94k, False: 0]
  ------------------
   26|  3.94k|        return -1;
   27|       |
   28|      0|    struct stream *s = demuxer->stream;
   29|      0|    if (!s->info || strcmp(s->info->name, "mpv"))
  ------------------
  |  Branch (29:9): [True: 0, False: 0]
  |  Branch (29:21): [True: 0, False: 0]
  ------------------
   30|      0|        return -1;
   31|       |
   32|      0|    demuxer->playlist = talloc_zero(demuxer, struct playlist);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   33|      0|    mp_url_unescape_inplace(s->path);
   34|      0|    playlist_append_file(demuxer->playlist, s->path);
   35|      0|    playlist_set_stream_flags(demuxer->playlist, demuxer->stream_origin);
   36|      0|    demuxer->fully_read = true;
   37|      0|    demux_close_stream(demuxer);
   38|       |
   39|      0|    return 0;
   40|      0|}

demux_null.c:try_open_file:
   23|  4.02k|{
   24|  4.02k|    if (!bstr_startswith0(bstr0(demux->filename), "null://") &&
  ------------------
  |  Branch (24:9): [True: 3.94k, False: 80]
  ------------------
   25|  4.02k|        check != DEMUX_CHECK_REQUEST)
  ------------------
  |  Branch (25:9): [True: 3.94k, False: 0]
  ------------------
   26|  3.94k|        return -1;
   27|     80|    demux->seekable = true;
   28|     80|    return 0;
   29|  4.02k|}

demux_playlist.c:open_file:
  654|  29.6k|{
  655|  29.6k|    if (!demuxer->access_references)
  ------------------
  |  Branch (655:9): [True: 0, False: 29.6k]
  ------------------
  656|      0|        return -1;
  657|       |
  658|  29.6k|    bool force = check < DEMUX_CHECK_UNSAFE || check == DEMUX_CHECK_REQUEST;
  ------------------
  |  Branch (658:18): [True: 0, False: 29.6k]
  |  Branch (658:48): [True: 0, False: 29.6k]
  ------------------
  659|       |
  660|  29.6k|    struct pl_parser *p = talloc_zero(NULL, struct pl_parser);
  ------------------
  |  |   27|  29.6k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  29.6k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  29.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  661|  29.6k|    p->global = demuxer->global;
  662|  29.6k|    p->log = demuxer->log;
  663|  29.6k|    p->pl = talloc_zero(p, struct playlist);
  ------------------
  |  |   27|  29.6k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  29.6k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  29.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  664|  29.6k|    p->real_stream = demuxer->stream;
  665|  29.6k|    p->add_base = true;
  666|       |
  667|  29.6k|    struct demux_opts *opts = mp_get_config_group(p, p->global, &demux_conf);
  668|  29.6k|    p->codepage = opts->meta_cp;
  669|       |
  670|  29.6k|    char probe[PROBE_SIZE];
  671|  29.6k|    int probe_len = stream_read_peek(p->real_stream, probe, sizeof(probe));
  672|  29.6k|    p->s = stream_memory_open(demuxer->global, probe, probe_len);
  673|  29.6k|    p->s->mime_type = demuxer->stream->mime_type;
  674|  29.6k|    p->utf16 = stream_skip_bom(p->s);
  675|  29.6k|    p->force = force;
  676|  29.6k|    p->check_level = check;
  677|  29.6k|    p->probing = true;
  678|  29.6k|    p->autocreate_playlist = demuxer->params->allow_playlist_create ? opts->autocreate_playlist : 0;
  ------------------
  |  Branch (678:30): [True: 10.0k, False: 19.6k]
  ------------------
  679|  29.6k|    p->mp_opts = mp_get_config_group(demuxer, demuxer->global, &mp_opt_root);
  680|  29.6k|    p->opts = mp_get_config_group(demuxer, demuxer->global, &demux_playlist_conf);
  681|       |
  682|  29.6k|    const struct pl_format *fmts = playlist_formats;
  683|  29.6k|    if (demuxer->desc == &demuxer_desc_directory)
  ------------------
  |  Branch (683:9): [True: 25.0k, False: 4.58k]
  ------------------
  684|  25.0k|        fmts = dir_formats;
  685|       |
  686|  29.6k|    const struct pl_format *fmt = probe_pl(p, fmts);
  687|  29.6k|    free_stream(p->s);
  688|  29.6k|    playlist_clear(p->pl);
  689|  29.6k|    if (!fmt) {
  ------------------
  |  Branch (689:9): [True: 29.0k, False: 558]
  ------------------
  690|  29.0k|        talloc_free(p);
  ------------------
  |  |   47|  29.0k|#define talloc_free                     ta_free
  ------------------
  691|  29.0k|        return -1;
  692|  29.0k|    }
  693|       |
  694|    558|    p->probing = false;
  695|    558|    p->error = false;
  696|    558|    p->s = demuxer->stream;
  697|    558|    p->utf16 = stream_skip_bom(p->s);
  698|    558|    bool ok = fmt->parse(p) >= 0 && !p->error;
  ------------------
  |  Branch (698:15): [True: 558, False: 0]
  |  Branch (698:37): [True: 558, False: 0]
  ------------------
  699|    558|    if (p->add_base) {
  ------------------
  |  Branch (699:9): [True: 558, False: 0]
  ------------------
  700|    558|        bstr proto = mp_split_proto(bstr0(demuxer->filename), NULL);
  701|       |        // Don't add base path to self-expanding protocols
  702|    558|        if (bstrcasecmp0(proto, "memory") && bstrcasecmp0(proto, "lavf") &&
  ------------------
  |  Branch (702:13): [True: 0, False: 558]
  |  Branch (702:46): [True: 0, False: 0]
  ------------------
  703|    558|            bstrcasecmp0(proto, "hex") && bstrcasecmp0(proto, "data") &&
  ------------------
  |  Branch (703:13): [True: 0, False: 0]
  |  Branch (703:43): [True: 0, False: 0]
  ------------------
  704|    558|            bstrcasecmp0(proto, "fd"))
  ------------------
  |  Branch (704:13): [True: 0, False: 0]
  ------------------
  705|      0|        {
  706|      0|            playlist_add_base_path(p->pl, mp_dirname(demuxer->filename));
  707|      0|        }
  708|    558|    }
  709|    558|    playlist_set_stream_flags(p->pl, demuxer->stream_origin);
  710|    558|    demuxer->playlist = talloc_steal(demuxer, p->pl);
  ------------------
  |  |   38|    558|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|    558|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  711|    558|    demuxer->filetype = p->format ? p->format : fmt->name;
  ------------------
  |  Branch (711:25): [True: 21, False: 537]
  ------------------
  712|    558|    demuxer->fully_read = true;
  713|    558|    talloc_free(p);
  ------------------
  |  |   47|    558|#define talloc_free                     ta_free
  ------------------
  714|    558|    if (ok)
  ------------------
  |  Branch (714:9): [True: 558, False: 0]
  ------------------
  715|    558|        demux_close_stream(demuxer);
  716|    558|    return ok ? 0 : -1;
  ------------------
  |  Branch (716:12): [True: 558, False: 0]
  ------------------
  717|  29.6k|}
demux_playlist.c:parse_m3u:
  243|  4.96k|{
  244|  4.96k|    bstr line = pl_get_line(p);
  245|  4.96k|    if (p->probing && !bstr_equals0(line, "#EXTM3U")) {
  ------------------
  |  Branch (245:9): [True: 4.58k, False: 382]
  |  Branch (245:23): [True: 4.19k, False: 381]
  ------------------
  246|       |        // Last resort: if the file extension is m3u, it might be headerless.
  247|  4.19k|        if (p->check_level == DEMUX_CHECK_UNSAFE) {
  ------------------
  |  Branch (247:13): [True: 1.85k, False: 2.34k]
  ------------------
  248|  1.85k|            char *ext = mp_splitext(p->real_stream->url, NULL);
  249|  1.85k|            char probe[PROBE_SIZE];
  250|  1.85k|            int len = stream_read_peek(p->real_stream, probe, sizeof(probe));
  251|  1.85k|            bstr data = {probe, len};
  252|  1.85k|            if (ext && data.len >= 2 && maybe_text(data)) {
  ------------------
  |  Branch (252:17): [True: 456, False: 1.40k]
  |  Branch (252:24): [True: 455, False: 1]
  |  Branch (252:41): [True: 58, False: 397]
  ------------------
  253|     58|                const char *exts[] = {"m3u", "m3u8", NULL};
  254|    172|                for (int n = 0; exts[n]; n++) {
  ------------------
  |  Branch (254:33): [True: 115, False: 57]
  ------------------
  255|    115|                    if (strcasecmp(ext, exts[n]) == 0)
  ------------------
  |  Branch (255:25): [True: 1, False: 114]
  ------------------
  256|      1|                        goto ok;
  257|    115|                }
  258|     58|            }
  259|  1.85k|        }
  260|  4.19k|        pl_free_line(p, line);
  261|  4.19k|        return -1;
  262|  4.19k|    }
  263|       |
  264|    764|ok:
  265|    764|    if (p->probing) {
  ------------------
  |  Branch (265:9): [True: 382, False: 382]
  ------------------
  266|    382|        pl_free_line(p, line);
  267|    382|        return 0;
  268|    382|    }
  269|       |
  270|    382|    char *title = NULL;
  271|   171k|    while (line.len || !pl_eof(p)) {
  ------------------
  |  Branch (271:12): [True: 89.5k, False: 82.1k]
  |  Branch (271:24): [True: 81.8k, False: 382]
  ------------------
  272|   171k|        bstr line_dup = line;
  273|   171k|        if (bstr_eatstart0(&line_dup, "#EXTINF:")) {
  ------------------
  |  Branch (273:13): [True: 0, False: 171k]
  ------------------
  274|      0|            bstr duration, btitle;
  275|      0|            if (bstr_split_tok(line_dup, ",", &duration, &btitle) && btitle.len) {
  ------------------
  |  Branch (275:17): [True: 0, False: 0]
  |  Branch (275:70): [True: 0, False: 0]
  ------------------
  276|      0|                talloc_free(title);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  277|      0|                title = bstrto0(NULL, btitle);
  278|      0|            }
  279|   171k|        } else if (bstr_startswith0(line_dup, "#EXT-X-")) {
  ------------------
  |  Branch (279:20): [True: 283, False: 171k]
  ------------------
  280|    283|            p->format = "hls";
  281|   171k|        } else if (line_dup.len > 0 && !bstr_startswith0(line_dup, "#")) {
  ------------------
  |  Branch (281:20): [True: 89.2k, False: 81.8k]
  |  Branch (281:40): [True: 88.4k, False: 881]
  ------------------
  282|  88.4k|            char *fn = bstrto0(NULL, line_dup);
  283|  88.4k|            struct playlist_entry *e = playlist_entry_new(fn);
  284|  88.4k|            talloc_free(fn);
  ------------------
  |  |   47|  88.4k|#define talloc_free                     ta_free
  ------------------
  285|  88.4k|            e->title = talloc_steal(e, title);
  ------------------
  |  |   38|  88.4k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  88.4k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  286|  88.4k|            title = NULL;
  287|  88.4k|            playlist_insert_at(p->pl, e, NULL);
  288|  88.4k|        }
  289|   171k|        pl_free_line(p, line);
  290|   171k|        line = pl_get_line(p);
  291|   171k|    }
  292|    382|    pl_free_line(p, line);
  293|    382|    talloc_free(title);
  ------------------
  |  |   47|    382|#define talloc_free                     ta_free
  ------------------
  294|    382|    return 0;
  295|    764|}
demux_playlist.c:pl_get_line:
  198|   624k|{
  199|   624k|    bstr line = bstr_strip(bstr0(pl_get_line0(p)));
  200|   624k|    const char *charset = mp_charset_guess(p, p->log, line, p->codepage, 0);
  201|   624k|    if (charset && !mp_charset_is_utf8(charset)) {
  ------------------
  |  Branch (201:9): [True: 624k, False: 0]
  |  Branch (201:20): [True: 161k, False: 462k]
  ------------------
  202|   161k|        bstr utf8 = mp_iconv_to_utf8(p->log, line, charset, 0);
  203|   161k|        if (utf8.start && utf8.start != line.start) {
  ------------------
  |  Branch (203:13): [True: 161k, False: 0]
  |  Branch (203:27): [True: 161k, False: 0]
  ------------------
  204|   161k|            line = utf8;
  205|   161k|            p->line_allocated = true;
  206|   161k|        }
  207|   161k|    }
  208|   624k|    return line;
  209|   624k|}
demux_playlist.c:pl_get_line0:
  185|   624k|{
  186|   624k|    char *res = read_line(p->s, p->buffer, sizeof(p->buffer), p->utf16);
  187|   624k|    if (res) {
  ------------------
  |  Branch (187:9): [True: 623k, False: 838]
  ------------------
  188|   623k|        int len = strlen(res);
  189|   623k|        if (len > 0 && res[len - 1] == '\n')
  ------------------
  |  Branch (189:13): [True: 623k, False: 0]
  |  Branch (189:24): [True: 614k, False: 8.49k]
  ------------------
  190|   614k|            res[len - 1] = '\0';
  191|   623k|    } else {
  192|    838|        p->error |= !p->s->eof;
  193|    838|    }
  194|   624k|    return res;
  195|   624k|}
demux_playlist.c:read_line:
  163|   624k|{
  164|   624k|    if (max < 1)
  ------------------
  |  Branch (164:9): [True: 0, False: 624k]
  ------------------
  165|      0|        return NULL;
  166|   624k|    int read = 0;
  167|   665k|    while (1) {
  ------------------
  |  Branch (167:12): [Folded - Ignored]
  ------------------
  168|       |        // Reserve 1 byte of ptr for terminating \0.
  169|   665k|        int l = read_characters(s, &mem[read], max - read - 1, utf16);
  170|   665k|        if (l < 0 || memchr(&mem[read], '\0', l)) {
  ------------------
  |  Branch (170:13): [True: 120, False: 664k]
  |  Branch (170:22): [True: 0, False: 664k]
  ------------------
  171|    120|            MP_WARN(s, "error reading line\n");
  ------------------
  |  |   86|    120|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    120|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  172|    120|            return NULL;
  173|    120|        }
  174|   664k|        read += l;
  175|   664k|        if (l == 0 || (read > 0 && mem[read - 1] == '\n'))
  ------------------
  |  Branch (175:13): [True: 9.20k, False: 655k]
  |  Branch (175:24): [True: 655k, False: 0]
  |  Branch (175:36): [True: 614k, False: 40.8k]
  ------------------
  176|   624k|            break;
  177|   664k|    }
  178|   624k|    mem[read] = '\0';
  179|   624k|    if (!stream_read_peek(s, &(char){0}, 1) && read == 0) // legitimate EOF
  ------------------
  |  Branch (179:9): [True: 9.21k, False: 614k]
  |  Branch (179:48): [True: 718, False: 8.49k]
  ------------------
  180|    718|        return NULL;
  181|   623k|    return mem;
  182|   624k|}
demux_playlist.c:read_characters:
  128|   665k|{
  129|   665k|    if (utf16 == 1 || utf16 == 2) {
  ------------------
  |  Branch (129:9): [True: 80, False: 664k]
  |  Branch (129:23): [True: 280, False: 664k]
  ------------------
  130|    360|        uint8_t *cur = dst;
  131|   284k|        while (1) {
  ------------------
  |  Branch (131:16): [Folded - Ignored]
  ------------------
  132|   284k|            if ((cur - dst) + 8 >= dstsize) // PUT_UTF8 writes max. 8 bytes
  ------------------
  |  Branch (132:17): [True: 0, False: 284k]
  ------------------
  133|      0|                return -1; // line too long
  134|   284k|            uint32_t c;
  135|   284k|            uint8_t tmp;
  136|   284k|            GET_UTF16(c, stream_read_word_endian(s, utf16 == 2), return -1;)
  137|   284k|            if (s->eof)
  ------------------
  |  Branch (137:17): [True: 240, False: 284k]
  ------------------
  138|    240|                break; // legitimate EOF; ignore the case of partial reads
  139|   284k|            PUT_UTF8(c, tmp, *cur++ = tmp;)
  140|   284k|            if (c == '\n')
  ------------------
  |  Branch (140:17): [True: 0, False: 284k]
  ------------------
  141|      0|                break;
  142|   284k|        }
  143|    240|        return cur - dst;
  144|   664k|    } else {
  145|   664k|        uint8_t buf[1024];
  146|   664k|        int buf_len = stream_read_peek(s, buf, sizeof(buf));
  147|   664k|        uint8_t *end = memchr(buf, '\n', buf_len);
  148|   664k|        int len = end ? end - buf + 1 : buf_len;
  ------------------
  |  Branch (148:19): [True: 614k, False: 49.7k]
  ------------------
  149|   664k|        if (len > dstsize)
  ------------------
  |  Branch (149:13): [True: 0, False: 664k]
  ------------------
  150|      0|            return -1; // line too long
  151|   664k|        memcpy(dst, buf, len);
  152|   664k|        stream_seek_skip(s, stream_tell(s) + len);
  153|   664k|        return len;
  154|   664k|    }
  155|   665k|}
demux_playlist.c:stream_read_word_endian:
  117|   285k|{
  118|   285k|    unsigned int y = stream_read_char(s);
  119|   285k|    y = (y << 8) | stream_read_char(s);
  120|   285k|    if (!big_endian)
  ------------------
  |  Branch (120:9): [True: 38.6k, False: 246k]
  ------------------
  121|  38.6k|        y = ((y >> 8) & 0xFF) | (y << 8);
  122|   285k|    return y;
  123|   285k|}
demux_playlist.c:maybe_text:
  233|    455|{
  234|  95.5k|    for (int n = 0; n < d.len; n++) {
  ------------------
  |  Branch (234:21): [True: 95.4k, False: 58]
  ------------------
  235|  95.4k|        unsigned char c = d.start[n];
  236|  95.4k|        if (c < 32 && c != '\n' && c != '\r' && c != '\t')
  ------------------
  |  Branch (236:13): [True: 30.5k, False: 64.9k]
  |  Branch (236:23): [True: 29.9k, False: 595]
  |  Branch (236:36): [True: 29.2k, False: 731]
  |  Branch (236:49): [True: 397, False: 28.8k]
  ------------------
  237|    397|            return false;
  238|  95.4k|    }
  239|     58|    return true;
  240|    455|}
demux_playlist.c:pl_free_line:
  213|   624k|{
  214|   624k|    if (p->line_allocated) {
  ------------------
  |  Branch (214:9): [True: 161k, False: 462k]
  ------------------
  215|   161k|        talloc_free(line.start);
  ------------------
  |  |   47|   161k|#define talloc_free                     ta_free
  ------------------
  216|   161k|        p->line_allocated = false;
  217|   161k|    }
  218|   624k|}
demux_playlist.c:pl_eof:
  228|   526k|{
  229|   526k|    return p->error || p->s->eof;
  ------------------
  |  Branch (229:12): [True: 116, False: 526k]
  |  Branch (229:24): [True: 741, False: 525k]
  ------------------
  230|   526k|}
demux_playlist.c:parse_ref_init:
  298|  4.21k|{
  299|  4.21k|    bstr line = pl_get_line(p);
  300|  4.21k|    if (!bstr_equals0(line, "[Reference]")) {
  ------------------
  |  Branch (300:9): [True: 4.18k, False: 26]
  ------------------
  301|  4.18k|        pl_free_line(p, line);
  302|  4.18k|        return -1;
  303|  4.18k|    }
  304|     26|    pl_free_line(p, line);
  305|       |
  306|       |    // ASF http streaming redirection - this is needed because ffmpeg http://
  307|       |    // and mmsh:// can not automatically switch automatically between each
  308|       |    // others. Both protocols use http - MMSH requires special http headers
  309|       |    // to "activate" it, and will in other cases return this playlist.
  310|     26|    static const char *const mmsh_types[] = {"audio/x-ms-wax",
  311|     26|        "audio/x-ms-wma", "video/x-ms-asf", "video/x-ms-afs", "video/x-ms-wmv",
  312|     26|        "video/x-ms-wma", "application/x-mms-framed",
  313|     26|        "application/vnd.ms.wms-hdr.asfv1", NULL};
  314|     26|    bstr burl = bstr0(p->s->url);
  315|     26|    if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) {
  ------------------
  |  Branch (315:9): [True: 0, False: 26]
  |  Branch (315:45): [True: 0, False: 0]
  ------------------
  316|      0|        MP_INFO(p, "Redirecting to mmsh://\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  317|      0|        playlist_append_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl)));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  318|      0|        return 0;
  319|      0|    }
  320|       |
  321|  16.2k|    while (!pl_eof(p)) {
  ------------------
  |  Branch (321:12): [True: 16.2k, False: 26]
  ------------------
  322|  16.2k|        line = pl_get_line(p);
  323|  16.2k|        bstr value;
  324|  16.2k|        if (bstr_case_startswith(line, bstr0("Ref"))) {
  ------------------
  |  Branch (324:13): [True: 8, False: 16.2k]
  ------------------
  325|      8|            bstr_split_tok(line, "=", &(bstr){0}, &value);
  326|      8|            if (value.len)
  ------------------
  |  Branch (326:17): [True: 0, False: 8]
  ------------------
  327|      0|                pl_add(p, value);
  328|      8|        }
  329|  16.2k|        pl_free_line(p, line);
  330|  16.2k|    }
  331|     26|    return 0;
  332|     26|}
demux_playlist.c:check_mimetype:
   84|  46.2k|{
   85|  46.2k|    if (s->mime_type) {
  ------------------
  |  Branch (85:9): [True: 0, False: 46.2k]
  ------------------
   86|      0|        for (int n = 0; list && list[n]; n++) {
  ------------------
  |  Branch (86:25): [True: 0, False: 0]
  |  Branch (86:33): [True: 0, False: 0]
  ------------------
   87|      0|            if (strcasecmp(s->mime_type, list[n]) == 0)
  ------------------
  |  Branch (87:17): [True: 0, False: 0]
  ------------------
   88|      0|                return true;
   89|      0|        }
   90|      0|    }
   91|  46.2k|    return false;
   92|  46.2k|}
demux_playlist.c:pl_add:
  221|    538|{
  222|    538|    char *s = bstrto0(NULL, entry);
  223|    538|    playlist_append_file(p->pl, s);
  224|    538|    talloc_free(s);
  ------------------
  |  |   47|    538|#define talloc_free                     ta_free
  ------------------
  225|    538|}
demux_playlist.c:parse_pls:
  366|  4.20k|{
  367|  4.20k|    return parse_ini_thing(p, "[playlist]", "File");
  368|  4.20k|}
demux_playlist.c:parse_ini_thing:
  336|  8.51k|{
  337|  8.51k|    bstr line = {0};
  338|  17.1k|    while (!line.len && !pl_eof(p))
  ------------------
  |  Branch (338:12): [True: 8.95k, False: 8.23k]
  |  Branch (338:25): [True: 8.66k, False: 286]
  ------------------
  339|  8.66k|        line = pl_get_line(p);
  340|  8.51k|    if (bstrcasecmp0(line, header) != 0) {
  ------------------
  |  Branch (340:9): [True: 8.19k, False: 326]
  ------------------
  341|  8.19k|        pl_free_line(p, line);
  342|  8.19k|        return -1;
  343|  8.19k|    }
  344|    326|    if (p->probing) {
  ------------------
  |  Branch (344:9): [True: 163, False: 163]
  ------------------
  345|    163|        pl_free_line(p, line);
  346|    163|        return 0;
  347|    163|    }
  348|    163|    pl_free_line(p, line);
  349|   418k|    while (!pl_eof(p)) {
  ------------------
  |  Branch (349:12): [True: 418k, False: 163]
  ------------------
  350|   418k|        line = pl_get_line(p);
  351|   418k|        bstr key, value;
  352|   418k|        if (bstr_split_tok(line, "=", &key, &value) &&
  ------------------
  |  Branch (352:13): [True: 1.28k, False: 417k]
  ------------------
  353|   418k|            bstr_case_startswith(key, bstr0(entry)))
  ------------------
  |  Branch (353:13): [True: 538, False: 748]
  ------------------
  354|    538|        {
  355|    538|            value = bstr_strip(value);
  356|    538|            if (bstr_startswith0(value, "\"") && bstr_endswith0(value, "\""))
  ------------------
  |  Branch (356:17): [True: 0, False: 538]
  |  Branch (356:50): [True: 0, False: 0]
  ------------------
  357|      0|                value = bstr_splice(value, 1, -1);
  358|    538|            pl_add(p, value);
  359|    538|        }
  360|   418k|        pl_free_line(p, line);
  361|   418k|    }
  362|    163|    return 0;
  363|    326|}
demux_playlist.c:parse_url:
  371|  4.31k|{
  372|  4.31k|    return parse_ini_thing(p, "[InternetShortcut]", "URL");
  373|  4.31k|}
demux_playlist.c:parse_txt:
  376|  4.02k|{
  377|  4.02k|    if (!p->force)
  ------------------
  |  Branch (377:9): [True: 4.02k, False: 0]
  ------------------
  378|  4.02k|        return -1;
  379|      0|    if (p->probing)
  ------------------
  |  Branch (379:9): [True: 0, False: 0]
  ------------------
  380|      0|        return 0;
  381|      0|    MP_WARN(p, "Reading plaintext playlist.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  382|      0|    while (!pl_eof(p)) {
  ------------------
  |  Branch (382:12): [True: 0, False: 0]
  ------------------
  383|      0|        bstr line = pl_get_line(p);
  384|      0|        if (line.len == 0)
  ------------------
  |  Branch (384:13): [True: 0, False: 0]
  ------------------
  385|      0|            continue;
  386|      0|        pl_add(p, line);
  387|      0|        pl_free_line(p, line);
  388|      0|    }
  389|      0|    return 0;
  390|      0|}
demux_playlist.c:parse_dir:
  538|  25.0k|{
  539|  25.0k|    int ret = -1;
  540|  25.0k|    struct stream *stream = p->real_stream;
  541|  25.0k|    enum autocreate_mode autocreate = AUTO_NONE;
  542|  25.0k|    p->pl->playlist_dir = NULL;
  543|  25.0k|    if (p->autocreate_playlist && p->real_stream->is_local_fs && !p->real_stream->is_directory) {
  ------------------
  |  Branch (543:9): [True: 0, False: 25.0k]
  |  Branch (543:35): [True: 0, False: 0]
  |  Branch (543:66): [True: 0, False: 0]
  ------------------
  544|      0|        bstr ext = bstr_get_ext(bstr0(p->real_stream->url));
  545|      0|        switch (p->autocreate_playlist) {
  ------------------
  |  Branch (545:17): [True: 0, False: 0]
  ------------------
  546|      0|        case 1: // filter
  ------------------
  |  Branch (546:9): [True: 0, False: 0]
  ------------------
  547|      0|            autocreate = get_directory_filter(p);
  548|      0|            break;
  549|      0|        case 2: // same
  ------------------
  |  Branch (549:9): [True: 0, False: 0]
  ------------------
  550|      0|            if (str_in_list(ext, p->mp_opts->video_exts)) {
  ------------------
  |  Branch (550:17): [True: 0, False: 0]
  ------------------
  551|      0|                autocreate = AUTO_VIDEO;
  552|      0|            } else if (str_in_list(ext, p->mp_opts->audio_exts)) {
  ------------------
  |  Branch (552:24): [True: 0, False: 0]
  ------------------
  553|      0|                autocreate = AUTO_AUDIO;
  554|      0|            } else if (str_in_list(ext, p->mp_opts->image_exts)) {
  ------------------
  |  Branch (554:24): [True: 0, False: 0]
  ------------------
  555|      0|                autocreate = AUTO_IMAGE;
  556|      0|            } else if (str_in_list(ext, p->mp_opts->archive_exts)) {
  ------------------
  |  Branch (556:24): [True: 0, False: 0]
  ------------------
  557|      0|                autocreate = AUTO_ARCHIVE;
  558|      0|            } else if (str_in_list(ext, p->mp_opts->playlist_exts)) {
  ------------------
  |  Branch (558:24): [True: 0, False: 0]
  ------------------
  559|      0|                autocreate = AUTO_PLAYLIST;
  560|      0|            }
  561|      0|            break;
  562|      0|        }
  563|      0|        int flags = STREAM_READ_FILE_FLAGS_DEFAULT;
  ------------------
  |  |   60|      0|    (STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE)
  |  |  ------------------
  |  |  |  |   47|      0|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  |  |  ------------------
  |  |                   (STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE)
  |  |  ------------------
  |  |  |  |   41|      0|#define STREAM_READ               0
  |  |  ------------------
  |  |                   (STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE)
  |  |  ------------------
  |  |  |  |   54|      0|#define STREAM_LOCAL_FS_ONLY      (1 << 5) // stream_file only, no URLs
  |  |  ------------------
  |  |                   (STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE)
  |  |  ------------------
  |  |  |  |   55|      0|#define STREAM_LESS_NOISE         (1 << 6) // try to log errors only
  |  |  ------------------
  ------------------
  564|      0|        bstr dir = mp_dirname(p->real_stream->url);
  565|      0|        if (!dir.len)
  ------------------
  |  Branch (565:13): [True: 0, False: 0]
  ------------------
  566|      0|            autocreate = AUTO_NONE;
  567|      0|        if (autocreate != AUTO_NONE) {
  ------------------
  |  Branch (567:13): [True: 0, False: 0]
  ------------------
  568|      0|            stream = stream_create(bstrdup0(p, dir), flags, NULL, p->global);
  569|      0|            p->pl->playlist_dir = bstrdup0(p->pl, dir);
  570|      0|        }
  571|  25.0k|    } else {
  572|  25.0k|        autocreate = get_directory_filter(p);
  573|  25.0k|    }
  574|  25.0k|    if (!stream->is_directory)
  ------------------
  |  Branch (574:9): [True: 25.0k, False: 0]
  ------------------
  575|  25.0k|        goto done;
  576|      0|    if (p->probing) {
  ------------------
  |  Branch (576:9): [True: 0, False: 0]
  ------------------
  577|      0|        ret = 0;
  578|      0|        goto done;
  579|      0|    }
  580|       |
  581|      0|    char *path = mp_file_get_path(p, bstr0(stream->url));
  582|      0|    if (!path)
  ------------------
  |  Branch (582:9): [True: 0, False: 0]
  ------------------
  583|      0|        goto done;
  584|       |
  585|      0|    if (autocreate == AUTO_NONE)
  ------------------
  |  Branch (585:9): [True: 0, False: 0]
  ------------------
  586|      0|        goto done;
  587|       |
  588|      0|    struct stat dir_stack[MAX_DIR_STACK];
  589|       |
  590|      0|    if (p->opts->dir_mode == DIR_AUTO) {
  ------------------
  |  Branch (590:9): [True: 0, False: 0]
  ------------------
  591|      0|        struct MPOpts *opts = mp_get_config_group(NULL, p->global, &mp_opt_root);
  592|      0|        p->opts->dir_mode = opts->shuffle ? DIR_RECURSIVE : DIR_LAZY;
  ------------------
  |  Branch (592:29): [True: 0, False: 0]
  ------------------
  593|      0|        talloc_free(opts);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  594|      0|    }
  595|       |
  596|      0|    scan_dir(p, path, dir_stack, 0, autocreate);
  597|       |
  598|      0|    p->add_base = false;
  599|      0|    ret = p->pl->num_entries > 0 ? 0 : -1;
  ------------------
  |  Branch (599:11): [True: 0, False: 0]
  ------------------
  600|       |
  601|  25.0k|done:
  602|  25.0k|    if (stream != p->real_stream)
  ------------------
  |  Branch (602:9): [True: 0, False: 25.0k]
  ------------------
  603|      0|        free_stream(stream);
  604|  25.0k|    return ret;
  605|      0|}
demux_playlist.c:get_directory_filter:
  520|  25.0k|{
  521|  25.0k|    enum autocreate_mode autocreate = AUTO_NONE;
  522|  25.0k|    if (!p->opts->directory_filter || !p->opts->directory_filter[0])
  ------------------
  |  Branch (522:9): [True: 0, False: 25.0k]
  |  Branch (522:39): [True: 0, False: 25.0k]
  ------------------
  523|      0|        autocreate = AUTO_ANY;
  524|  25.0k|    if (str_in_list(bstr0("video"), p->opts->directory_filter))
  ------------------
  |  Branch (524:9): [True: 25.0k, False: 0]
  ------------------
  525|  25.0k|        autocreate |= AUTO_VIDEO;
  526|  25.0k|    if (str_in_list(bstr0("audio"), p->opts->directory_filter))
  ------------------
  |  Branch (526:9): [True: 25.0k, False: 0]
  ------------------
  527|  25.0k|        autocreate |= AUTO_AUDIO;
  528|  25.0k|    if (str_in_list(bstr0("image"), p->opts->directory_filter))
  ------------------
  |  Branch (528:9): [True: 25.0k, False: 0]
  ------------------
  529|  25.0k|        autocreate |= AUTO_IMAGE;
  530|  25.0k|    if (str_in_list(bstr0("archive"), p->opts->directory_filter))
  ------------------
  |  Branch (530:9): [True: 25.0k, False: 0]
  ------------------
  531|  25.0k|        autocreate |= AUTO_ARCHIVE;
  532|  25.0k|    if (str_in_list(bstr0("playlist"), p->opts->directory_filter))
  ------------------
  |  Branch (532:9): [True: 25.0k, False: 0]
  ------------------
  533|  25.0k|        autocreate |= AUTO_PLAYLIST;
  534|  25.0k|    return autocreate;
  535|  25.0k|}
demux_playlist.c:probe_pl:
  633|  29.6k|{
  634|  29.6k|    int64_t start = stream_tell(p->s);
  635|  29.6k|    const struct pl_format *fmt = fmts;
  636|  75.2k|    while (fmt->name) {
  ------------------
  |  Branch (636:12): [True: 46.2k, False: 29.0k]
  ------------------
  637|  46.2k|        stream_seek(p->s, start);
  638|  46.2k|        if (check_mimetype(p->s, fmt->mime_types)) {
  ------------------
  |  Branch (638:13): [True: 0, False: 46.2k]
  ------------------
  639|      0|            MP_VERBOSE(p, "forcing format by mime-type.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  640|      0|            p->force = true;
  641|      0|            return fmt;
  642|      0|        }
  643|  46.2k|        if (fmt->parse(p) >= 0)
  ------------------
  |  Branch (643:13): [True: 558, False: 45.6k]
  ------------------
  644|    558|            return fmt;
  645|  45.6k|        fmt++;
  646|  45.6k|    }
  647|  29.0k|    return NULL;
  648|  29.6k|}

demux_raw.c:demux_rawaudio_open:
  146|  24.4k|{
  147|  24.4k|    struct demux_rawaudio_opts *opts =
  148|  24.4k|        mp_get_config_group(demuxer, demuxer->global, &demux_rawaudio_conf);
  149|       |
  150|  24.4k|    if (check != DEMUX_CHECK_REQUEST && check != DEMUX_CHECK_FORCE)
  ------------------
  |  Branch (150:9): [True: 24.4k, False: 0]
  |  Branch (150:41): [True: 24.4k, False: 0]
  ------------------
  151|  24.4k|        return -1;
  152|       |
  153|      0|    if (opts->channels.num_chmaps != 1) {
  ------------------
  |  Branch (153:9): [True: 0, False: 0]
  ------------------
  154|      0|        MP_ERR(demuxer, "Invalid channels option given.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  155|      0|        return -1;
  156|      0|    }
  157|       |
  158|      0|    struct sh_stream *sh = demux_alloc_sh_stream(STREAM_AUDIO);
  159|      0|    struct mp_codec_params *c = sh->codec;
  160|      0|    c->channels = opts->channels.chmaps[0];
  161|      0|    c->force_channels = true;
  162|      0|    c->samplerate = opts->samplerate;
  163|       |
  164|      0|    c->native_tb_num = 1;
  165|      0|    c->native_tb_den = c->samplerate;
  166|       |
  167|      0|    int f = opts->aformat;
  168|       |    // See PCM():               sign   float  bits    endian
  169|      0|    mp_set_pcm_codec(sh->codec, f & 1, f & 2, f >> 3, f & 4);
  170|      0|    int samplesize = ((f >> 3) + 7) / 8;
  171|       |
  172|      0|    demux_add_sh_stream(demuxer, sh);
  173|       |
  174|      0|    struct priv *p = talloc_ptrtype(demuxer, p);
  ------------------
  |  |   34|      0|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|      0|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  175|      0|    demuxer->priv = p;
  176|      0|    *p = (struct priv) {
  177|      0|        .sh = sh,
  178|      0|        .frame_size = samplesize * c->channels.num,
  179|      0|        .frame_rate = c->samplerate,
  180|      0|        .read_frames = c->samplerate / 8,
  181|      0|    };
  182|       |
  183|      0|    return generic_open(demuxer);
  184|      0|}
demux_raw.c:demux_rawvideo_open:
  187|  24.4k|{
  188|  24.4k|    struct demux_rawvideo_opts *opts =
  189|  24.4k|        mp_get_config_group(demuxer, demuxer->global, &demux_rawvideo_conf);
  190|       |
  191|  24.4k|    if (check != DEMUX_CHECK_REQUEST && check != DEMUX_CHECK_FORCE)
  ------------------
  |  Branch (191:9): [True: 24.4k, False: 0]
  |  Branch (191:41): [True: 24.4k, False: 0]
  ------------------
  192|  24.4k|        return -1;
  193|       |
  194|      0|    int width = opts->width;
  195|      0|    int height = opts->height;
  196|       |
  197|      0|    if (!width || !height) {
  ------------------
  |  Branch (197:9): [True: 0, False: 0]
  |  Branch (197:19): [True: 0, False: 0]
  ------------------
  198|      0|        MP_ERR(demuxer, "rawvideo: width or height not specified!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  199|      0|        return -1;
  200|      0|    }
  201|       |
  202|      0|    const char *decoder = "rawvideo";
  203|      0|    int imgfmt = opts->vformat;
  204|      0|    int imgsize = opts->imgsize;
  205|      0|    int mp_imgfmt = 0;
  206|      0|    if (opts->mp_format && !IMGFMT_IS_HWACCEL(opts->mp_format)) {
  ------------------
  |  |  327|      0|#define IMGFMT_IS_HWACCEL(fmt) (!!(mp_imgfmt_get_desc(fmt).flags & MP_IMGFLAG_HWACCEL))
  |  |  ------------------
  |  |  |  |   70|      0|#define MP_IMGFLAG_HWACCEL      MP_IMGFLAG_TYPE_HW
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define MP_IMGFLAG_TYPE_HW      (8 << 10)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (206:9): [True: 0, False: 0]
  |  Branch (206:28): [True: 0, False: 0]
  ------------------
  207|      0|        mp_imgfmt = opts->mp_format;
  208|      0|        if (!imgsize) {
  ------------------
  |  Branch (208:13): [True: 0, False: 0]
  ------------------
  209|      0|            struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(opts->mp_format);
  210|      0|            for (int p = 0; p < desc.num_planes; p++) {
  ------------------
  |  Branch (210:29): [True: 0, False: 0]
  ------------------
  211|      0|                imgsize += ((width >> desc.xs[p]) * (height >> desc.ys[p]) *
  212|      0|                            desc.bpp[p] + 7) / 8;
  213|      0|            }
  214|      0|        }
  215|      0|    } else if (opts->codec && opts->codec[0])
  ------------------
  |  Branch (215:16): [True: 0, False: 0]
  |  Branch (215:31): [True: 0, False: 0]
  ------------------
  216|      0|        decoder = talloc_strdup(demuxer, opts->codec);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  217|       |
  218|      0|    if (!imgsize) {
  ------------------
  |  Branch (218:9): [True: 0, False: 0]
  ------------------
  219|      0|        int bpp = 0;
  220|      0|        switch (imgfmt) {
  ------------------
  |  Branch (220:17): [True: 0, False: 0]
  ------------------
  221|      0|        case MKTAG('Y', 'V', '1', '2'):
  ------------------
  |  Branch (221:9): [True: 0, False: 0]
  ------------------
  222|      0|        case MKTAG('I', '4', '2', '0'):
  ------------------
  |  Branch (222:9): [True: 0, False: 0]
  ------------------
  223|      0|        case MKTAG('I', 'Y', 'U', 'V'):
  ------------------
  |  Branch (223:9): [True: 0, False: 0]
  ------------------
  224|      0|            bpp = 12;
  225|      0|            break;
  226|      0|        case MKTAG('U', 'Y', 'V', 'Y'):
  ------------------
  |  Branch (226:9): [True: 0, False: 0]
  ------------------
  227|      0|        case MKTAG('Y', 'U', 'Y', '2'):
  ------------------
  |  Branch (227:9): [True: 0, False: 0]
  ------------------
  228|      0|            bpp = 16;
  229|      0|            break;
  230|      0|        }
  231|      0|        if (!bpp) {
  ------------------
  |  Branch (231:13): [True: 0, False: 0]
  ------------------
  232|      0|            MP_ERR(demuxer, "rawvideo: img size not specified and unknown format!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  233|      0|            return -1;
  234|      0|        }
  235|      0|        imgsize = width * height * bpp / 8;
  236|      0|    }
  237|       |
  238|      0|    struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO);
  239|      0|    struct mp_codec_params *c = sh->codec;
  240|      0|    c->codec = decoder;
  241|      0|    c->codec_tag = imgfmt;
  242|      0|    c->fps = opts->fps;
  243|      0|    c->reliable_fps = true;
  244|      0|    c->disp_w = width;
  245|      0|    c->disp_h = height;
  246|      0|    if (mp_imgfmt) {
  ------------------
  |  Branch (246:9): [True: 0, False: 0]
  ------------------
  247|      0|        c->lav_codecpar = avcodec_parameters_alloc();
  248|      0|        MP_HANDLE_OOM(c->lav_codecpar);
  ------------------
  |  |  176|      0|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|      0|        void *oom_p_ = (x);     \
  |  |  178|      0|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  179|      0|            abort();            \
  |  |  180|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  249|      0|        c->lav_codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
  250|      0|        c->lav_codecpar->codec_id = mp_codec_to_av_codec_id(decoder);
  251|      0|        c->lav_codecpar->format = imgfmt2pixfmt(mp_imgfmt);
  252|      0|        c->lav_codecpar->width = width;
  253|      0|        c->lav_codecpar->height = height;
  254|      0|    }
  255|      0|    demux_add_sh_stream(demuxer, sh);
  256|       |
  257|      0|    struct priv *p = talloc_ptrtype(demuxer, p);
  ------------------
  |  |   34|      0|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|      0|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  258|      0|    demuxer->priv = p;
  259|      0|    *p = (struct priv) {
  260|      0|        .sh = sh,
  261|      0|        .frame_size = imgsize,
  262|      0|        .frame_rate = c->fps,
  263|      0|        .read_frames = 1,
  264|      0|    };
  265|       |
  266|      0|    return generic_open(demuxer);
  267|      0|}

demux_timeline.c:d_open:
  637|    436|{
  638|    436|    struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);
  ------------------
  |  |   27|    436|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|    436|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    436|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  639|    436|    p->tl = demuxer->params ? demuxer->params->timeline : NULL;
  ------------------
  |  Branch (639:13): [True: 436, False: 0]
  ------------------
  640|    436|    if (!p->tl || p->tl->num_pars < 1)
  ------------------
  |  Branch (640:9): [True: 0, False: 436]
  |  Branch (640:19): [True: 0, False: 436]
  ------------------
  641|      0|        return -1;
  642|       |
  643|    436|    demuxer->chapters = p->tl->chapters;
  644|    436|    demuxer->num_chapters = p->tl->num_chapters;
  645|       |
  646|    436|    struct demuxer *meta = p->tl->meta;
  647|    436|    if (meta) {
  ------------------
  |  Branch (647:9): [True: 436, False: 0]
  ------------------
  648|    436|        demuxer->metadata = meta->metadata;
  649|    436|        demuxer->attachments = meta->attachments;
  650|    436|        demuxer->num_attachments = meta->num_attachments;
  651|    436|        demuxer->editions = meta->editions;
  652|    436|        demuxer->num_editions = meta->num_editions;
  653|    436|        demuxer->edition = meta->edition;
  654|    436|    }
  655|       |
  656|    872|    for (int n = 0; n < p->tl->num_pars; n++) {
  ------------------
  |  Branch (656:21): [True: 436, False: 436]
  ------------------
  657|    436|        if (!add_tl(demuxer, p->tl->pars[n]))
  ------------------
  |  Branch (657:13): [True: 0, False: 436]
  ------------------
  658|      0|            return -1;
  659|    436|    }
  660|       |
  661|    436|    if (!p->num_sources)
  ------------------
  |  Branch (661:9): [True: 0, False: 436]
  ------------------
  662|      0|        return -1;
  663|       |
  664|    436|    demuxer->is_network |= p->tl->is_network;
  665|    436|    demuxer->is_streaming |= p->tl->is_streaming;
  666|       |
  667|    436|    demuxer->duration = p->duration;
  668|       |
  669|    436|    print_timeline(demuxer);
  670|       |
  671|    436|    demuxer->seekable = true;
  672|    436|    demuxer->partially_seekable = false;
  673|       |
  674|    436|    const char *format_name = "unknown";
  675|    436|    if (meta)
  ------------------
  |  Branch (675:9): [True: 436, False: 0]
  ------------------
  676|    436|        format_name = meta->filetype ? meta->filetype : meta->desc->name;
  ------------------
  |  Branch (676:23): [True: 436, False: 0]
  ------------------
  677|    436|    demuxer->filetype = talloc_asprintf(p, "%s/%s", p->tl->format, format_name);
  ------------------
  |  |   52|    436|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|    436|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  678|       |
  679|    436|    reselect_streams(demuxer);
  680|       |
  681|    436|    p->owns_tl = true;
  682|    436|    return 0;
  683|    436|}
demux_timeline.c:add_tl:
  541|    436|{
  542|    436|    struct priv *p = demuxer->priv;
  543|       |
  544|    436|    struct virtual_source *src = talloc_ptrtype(p, src);
  ------------------
  |  |   34|    436|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|    436|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    436|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  545|    436|    *src = (struct virtual_source){
  546|    436|        .tl = tl,
  547|    436|        .dash = tl->dash,
  548|    436|        .delay_open = tl->delay_open,
  549|    436|        .no_clip = tl->no_clip || tl->dash,
  ------------------
  |  Branch (549:20): [True: 0, False: 436]
  |  Branch (549:35): [True: 0, False: 436]
  ------------------
  550|    436|        .dts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|    436|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  551|    436|    };
  552|       |
  553|    436|    if (!tl->num_parts)
  ------------------
  |  Branch (553:9): [True: 0, False: 436]
  ------------------
  554|      0|        return false;
  555|       |
  556|    436|    MP_TARRAY_APPEND(p, p->sources, p->num_sources, src);
  ------------------
  |  |  105|    436|    do {                                            \
  |  |  106|    436|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    436|    do {                                            \
  |  |  |  |   97|    436|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    436|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    436|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    436|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 436, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|    436|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    436|    do {                                                        \
  |  |  |  |  |  |   89|    436|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    436|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    436|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    436|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    436|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    436|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    436|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    436|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    436|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    436|        (idxvar)++;                                 \
  |  |  109|    436|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  557|       |
  558|    436|    p->duration = MPMAX(p->duration, tl->parts[tl->num_parts - 1].end);
  ------------------
  |  |   43|    436|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 436]
  |  |  ------------------
  ------------------
  559|       |
  560|    436|    struct demuxer *meta = tl->track_layout;
  561|       |
  562|       |    // delay_open streams normally have meta==NULL, and 1 virtual stream
  563|    436|    int num_streams = 0;
  564|    436|    if (tl->delay_open) {
  ------------------
  |  Branch (564:9): [True: 0, False: 436]
  ------------------
  565|      0|        num_streams = tl->num_sh_meta;
  566|    436|    } else if (meta) {
  ------------------
  |  Branch (566:16): [True: 436, False: 0]
  ------------------
  567|    436|        num_streams = demux_get_num_stream(meta);
  568|    436|    }
  569|  1.25k|    for (int n = 0; n < num_streams; n++) {
  ------------------
  |  Branch (569:21): [True: 818, False: 436]
  ------------------
  570|    818|        struct sh_stream *new = NULL;
  571|       |
  572|    818|        if (tl->delay_open) {
  ------------------
  |  Branch (572:13): [True: 0, False: 818]
  ------------------
  573|      0|            struct sh_stream *tsh = tl->sh_meta[n];
  574|      0|            new = demux_alloc_sh_stream(tsh->type);
  575|      0|            new->codec = tsh->codec;
  576|      0|            apply_meta(new, tsh);
  577|      0|            demuxer->is_network = true;
  578|      0|            demuxer->is_streaming = true;
  579|    818|        } else {
  580|    818|            struct sh_stream *sh = demux_get_stream(meta, n);
  581|    818|            new = demux_alloc_sh_stream(sh->type);
  582|    818|            apply_meta(new, sh);
  583|    818|            new->codec = sh->codec;
  584|    818|            struct sh_stream *tsh = find_matching_meta(tl, n);
  585|    818|            if (tsh)
  ------------------
  |  Branch (585:17): [True: 0, False: 818]
  ------------------
  586|      0|                apply_meta(new, tsh);
  587|    818|        }
  588|       |
  589|    818|        demux_add_sh_stream(demuxer, new);
  590|    818|        struct virtual_stream *vs = talloc_ptrtype(p, vs);
  ------------------
  |  |   34|    818|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|    818|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    818|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  591|    818|        *vs = (struct virtual_stream){
  592|    818|            .src = src,
  593|    818|            .sh = new,
  594|    818|        };
  595|    818|        MP_TARRAY_APPEND(p, p->streams, p->num_streams, vs);
  ------------------
  |  |  105|    818|    do {                                            \
  |  |  106|    818|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    818|    do {                                            \
  |  |  |  |   97|    818|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    818|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    818|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    818|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 436, False: 382]
  |  |  |  |  ------------------
  |  |  |  |   99|    818|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    436|    do {                                                        \
  |  |  |  |  |  |   89|    436|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    436|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    436|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    436|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    436|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    436|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    436|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    818|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    818|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    818|        (idxvar)++;                                 \
  |  |  109|    818|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  596|    818|        mp_assert(demux_get_stream(demuxer, p->num_streams - 1) == new);
  ------------------
  |  |   41|    818|#define mp_assert assert
  ------------------
  597|    818|        MP_TARRAY_APPEND(src, src->streams, src->num_streams, vs);
  ------------------
  |  |  105|    818|    do {                                            \
  |  |  106|    818|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    818|    do {                                            \
  |  |  |  |   97|    818|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    818|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    818|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    818|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 436, False: 382]
  |  |  |  |  ------------------
  |  |  |  |   99|    818|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    436|    do {                                                        \
  |  |  |  |  |  |   89|    436|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    436|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    436|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    436|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    436|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    436|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    436|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    818|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    818|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    818|        (idxvar)++;                                 \
  |  |  109|    818|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  598|    818|    }
  599|       |
  600|  63.0k|    for (int n = 0; n < tl->num_parts; n++) {
  ------------------
  |  Branch (600:21): [True: 62.6k, False: 436]
  ------------------
  601|  62.6k|        struct timeline_part *part = &tl->parts[n];
  602|       |
  603|       |        // demux_timeline already does caching, doing it for the sub-demuxers
  604|       |        // would be pointless and wasteful.
  605|  62.6k|        if (part->source) {
  ------------------
  |  Branch (605:13): [True: 62.6k, False: 0]
  ------------------
  606|  62.6k|            demuxer->is_network |= part->source->is_network;
  607|  62.6k|            demuxer->is_streaming |= part->source->is_streaming;
  608|  62.6k|        }
  609|       |
  610|  62.6k|        if (!part->source)
  ------------------
  |  Branch (610:13): [True: 0, False: 62.6k]
  ------------------
  611|  62.6k|            mp_assert(tl->dash || tl->delay_open);
  ------------------
  |  |   41|  62.6k|#define mp_assert assert
  ------------------
  612|       |
  613|  62.6k|        struct segment *seg = talloc_ptrtype(src, seg);
  ------------------
  |  |   34|  62.6k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  62.6k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  62.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  614|  62.6k|        *seg = (struct segment){
  615|  62.6k|            .d = part->source,
  616|  62.6k|            .url = part->source ? part->source->filename : part->url,
  ------------------
  |  Branch (616:20): [True: 62.6k, False: 0]
  ------------------
  617|  62.6k|            .lazy = !part->source,
  618|  62.6k|            .d_start = part->source_start,
  619|  62.6k|            .start = part->start,
  620|  62.6k|            .end = part->end,
  621|  62.6k|        };
  622|       |
  623|  62.6k|        associate_streams(demuxer, src, seg);
  624|       |
  625|  62.6k|        seg->index = n;
  626|  62.6k|        MP_TARRAY_APPEND(src, src->segments, src->num_segments, seg);
  ------------------
  |  |  105|  62.6k|    do {                                            \
  |  |  106|  62.6k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  62.6k|    do {                                            \
  |  |  |  |   97|  62.6k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  62.6k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  62.6k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  62.6k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.32k, False: 60.3k]
  |  |  |  |  ------------------
  |  |  |  |   99|  62.6k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.32k|    do {                                                        \
  |  |  |  |  |  |   89|  2.32k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.32k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.32k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.32k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.32k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.32k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.32k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  62.6k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  62.6k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  62.6k|        (idxvar)++;                                 \
  |  |  109|  62.6k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  627|  62.6k|    }
  628|       |
  629|    436|    if (tl->track_layout) {
  ------------------
  |  Branch (629:9): [True: 436, False: 0]
  ------------------
  630|    436|        demuxer->is_network |= tl->track_layout->is_network;
  631|    436|        demuxer->is_streaming |= tl->track_layout->is_streaming;
  632|    436|    }
  633|    436|    return true;
  634|    436|}
demux_timeline.c:apply_meta:
  512|    818|{
  513|    818|    if (src->demuxer_id >= 0)
  ------------------
  |  Branch (513:9): [True: 0, False: 818]
  ------------------
  514|      0|        dst->demuxer_id = src->demuxer_id;
  515|    818|    if (src->title)
  ------------------
  |  Branch (515:9): [True: 0, False: 818]
  ------------------
  516|      0|        dst->title = src->title;
  517|    818|    if (src->lang)
  ------------------
  |  Branch (517:9): [True: 0, False: 818]
  ------------------
  518|      0|        dst->lang = src->lang;
  519|    818|    dst->default_track = src->default_track;
  520|    818|    dst->forced_track = src->forced_track;
  521|    818|    if (src->hls_bitrate)
  ------------------
  |  Branch (521:9): [True: 0, False: 818]
  ------------------
  522|      0|        dst->hls_bitrate = src->hls_bitrate;
  523|    818|    dst->missing_timestamps = src->missing_timestamps;
  524|    818|    if (src->attached_picture)
  ------------------
  |  Branch (524:9): [True: 0, False: 818]
  ------------------
  525|      0|        dst->attached_picture = src->attached_picture;
  526|    818|    dst->image = src->image;
  527|    818|}
demux_timeline.c:find_matching_meta:
  531|    818|{
  532|    818|    for (int n = 0; n < tl->num_sh_meta; n++) {
  ------------------
  |  Branch (532:21): [True: 0, False: 818]
  ------------------
  533|      0|        struct sh_stream *sh = tl->sh_meta[n];
  534|      0|        if (sh->index == index || sh->index < 0)
  ------------------
  |  Branch (534:13): [True: 0, False: 0]
  |  Branch (534:35): [True: 0, False: 0]
  ------------------
  535|      0|            return sh;
  536|      0|    }
  537|    818|    return NULL;
  538|    818|}
demux_timeline.c:associate_streams:
  111|  62.6k|{
  112|  62.6k|    if (!seg->d || seg->stream_map)
  ------------------
  |  Branch (112:9): [True: 0, False: 62.6k]
  |  Branch (112:20): [True: 0, False: 62.6k]
  ------------------
  113|      0|        return;
  114|       |
  115|  62.6k|    int num_streams = demux_get_num_stream(seg->d);
  116|   141k|    for (int n = 0; n < num_streams; n++) {
  ------------------
  |  Branch (116:21): [True: 79.2k, False: 62.6k]
  ------------------
  117|  79.2k|        struct sh_stream *sh = demux_get_stream(seg->d, n);
  118|  79.2k|        struct virtual_stream *other = NULL;
  119|       |
  120|   235k|        for (int i = 0; i < src->num_streams; i++) {
  ------------------
  |  Branch (120:25): [True: 156k, False: 79.2k]
  ------------------
  121|   156k|            struct virtual_stream *vs = src->streams[i];
  122|       |
  123|       |            // The stream must always have the same media type. Also, a stream
  124|       |            // can't be assigned multiple times.
  125|   156k|            if (sh->type != vs->sh->type || target_stream_used(seg, vs))
  ------------------
  |  Branch (125:17): [True: 77.0k, False: 79.1k]
  |  Branch (125:45): [True: 0, False: 79.1k]
  ------------------
  126|  77.0k|                continue;
  127|       |
  128|       |            // By default pick the first matching stream.
  129|  79.1k|            if (!other)
  ------------------
  |  Branch (129:17): [True: 79.1k, False: 0]
  ------------------
  130|  79.1k|                other = vs;
  131|       |
  132|       |            // Matching by demuxer ID is supposedly useful and preferable for
  133|       |            // ordered chapters.
  134|  79.1k|            if (sh->demuxer_id >= 0 && sh->demuxer_id == vs->sh->demuxer_id)
  ------------------
  |  Branch (134:17): [True: 0, False: 79.1k]
  |  Branch (134:40): [True: 0, False: 0]
  ------------------
  135|      0|                other = vs;
  136|  79.1k|        }
  137|       |
  138|  79.2k|        if (!other) {
  ------------------
  |  Branch (138:13): [True: 96, False: 79.1k]
  ------------------
  139|     96|            MP_WARN(demuxer, "Source stream %d (%s) unused and hidden.\n",
  ------------------
  |  |   86|     96|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     96|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  140|     96|                    n, stream_type_name(sh->type));
  141|     96|        }
  142|       |
  143|  79.2k|        MP_TARRAY_APPEND(seg, seg->stream_map, seg->num_stream_map, other);
  ------------------
  |  |  105|  79.2k|    do {                                            \
  |  |  106|  79.2k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  79.2k|    do {                                            \
  |  |  |  |   97|  79.2k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  79.2k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  79.2k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  79.2k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 62.5k, False: 16.6k]
  |  |  |  |  ------------------
  |  |  |  |   99|  79.2k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  62.5k|    do {                                                        \
  |  |  |  |  |  |   89|  62.5k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  62.5k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  62.5k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  62.5k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  62.5k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  62.5k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  62.5k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  79.2k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  79.2k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  79.2k|        (idxvar)++;                                 \
  |  |  109|  79.2k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  144|  79.2k|    }
  145|  62.6k|}
demux_timeline.c:target_stream_used:
   99|  79.1k|{
  100|  95.7k|    for (int n = 0; n < seg->num_stream_map; n++) {
  ------------------
  |  Branch (100:21): [True: 16.6k, False: 79.1k]
  ------------------
  101|  16.6k|        if (seg->stream_map[n] == vs)
  ------------------
  |  Branch (101:13): [True: 0, False: 16.6k]
  ------------------
  102|      0|            return true;
  103|  16.6k|    }
  104|  79.1k|    return false;
  105|  79.1k|}
demux_timeline.c:print_timeline:
  472|    436|{
  473|    436|    struct priv *p = demuxer->priv;
  474|       |
  475|    436|    MP_VERBOSE(demuxer, "Timeline segments:\n");
  ------------------
  |  |   88|    436|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    436|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  476|    872|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (476:21): [True: 436, False: 436]
  ------------------
  477|    436|        struct virtual_source *src = p->sources[x];
  478|       |
  479|    436|        if (x >= 1)
  ------------------
  |  Branch (479:13): [True: 0, False: 436]
  ------------------
  480|    436|            MP_VERBOSE(demuxer, " --- new parallel stream ---\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  481|       |
  482|  63.0k|        for (int n = 0; n < src->num_segments; n++) {
  ------------------
  |  Branch (482:25): [True: 62.6k, False: 436]
  ------------------
  483|  62.6k|            struct segment *seg = src->segments[n];
  484|  62.6k|            int src_num = n;
  485|  2.77M|            for (int i = 0; i < n; i++) {
  ------------------
  |  Branch (485:29): [True: 2.75M, False: 13.2k]
  ------------------
  486|  2.75M|                if (seg->d && src->segments[i]->d == seg->d) {
  ------------------
  |  Branch (486:21): [True: 2.75M, False: 0]
  |  Branch (486:31): [True: 49.3k, False: 2.70M]
  ------------------
  487|  49.3k|                    src_num = i;
  488|  49.3k|                    break;
  489|  49.3k|                }
  490|  2.75M|            }
  491|  62.6k|            MP_VERBOSE(demuxer, " %2d: %12f - %12f [%12f] (",
  ------------------
  |  |   88|  62.6k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  62.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  492|  62.6k|                       n, seg->start, seg->end, seg->d_start);
  493|   141k|            for (int i = 0; i < seg->num_stream_map; i++) {
  ------------------
  |  Branch (493:29): [True: 79.2k, False: 62.6k]
  ------------------
  494|  79.2k|                struct virtual_stream *vs = seg->stream_map[i];
  495|  79.2k|                MP_VERBOSE(demuxer, "%s%d", i ? " " : "",
  ------------------
  |  |   88|  79.2k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   316k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 16.6k, False: 62.5k]
  |  |  |  |  |  Branch (82:57): [True: 79.1k, False: 96]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  496|  79.2k|                           vs ? vs->sh->index : -1);
  497|  79.2k|            }
  498|  62.6k|            MP_VERBOSE(demuxer, ")\n  source %d:'%s'\n", src_num, seg->url);
  ------------------
  |  |   88|  62.6k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  62.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  499|  62.6k|        }
  500|       |
  501|    436|        if (src->dash)
  ------------------
  |  Branch (501:13): [True: 0, False: 436]
  ------------------
  502|    436|            MP_VERBOSE(demuxer, " (Using pseudo-DASH mode.)\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  503|    436|    }
  504|    436|    MP_VERBOSE(demuxer, "Total duration: %f\n", p->duration);
  ------------------
  |  |   88|    436|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    436|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  505|    436|}
demux_timeline.c:reselect_streams:
  148|  63.2k|{
  149|  63.2k|    struct priv *p = demuxer->priv;
  150|       |
  151|   187k|    for (int n = 0; n < p->num_streams; n++) {
  ------------------
  |  Branch (151:21): [True: 124k, False: 63.2k]
  ------------------
  152|   124k|        struct virtual_stream *vs = p->streams[n];
  153|   124k|        vs->selected = demux_stream_is_selected(vs->sh);
  154|   124k|    }
  155|       |
  156|   126k|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (156:21): [True: 63.2k, False: 63.2k]
  ------------------
  157|  63.2k|        struct virtual_source *src = p->sources[x];
  158|       |
  159|  58.0M|        for (int n = 0; n < src->num_segments; n++) {
  ------------------
  |  Branch (159:25): [True: 57.9M, False: 63.2k]
  ------------------
  160|  57.9M|            struct segment *seg = src->segments[n];
  161|       |
  162|  57.9M|            if (!seg->d)
  ------------------
  |  Branch (162:17): [True: 0, False: 57.9M]
  ------------------
  163|      0|                continue;
  164|       |
  165|   128M|            for (int i = 0; i < seg->num_stream_map; i++) {
  ------------------
  |  Branch (165:29): [True: 70.5M, False: 57.9M]
  ------------------
  166|  70.5M|                bool selected =
  167|  70.5M|                    seg->stream_map[i] && seg->stream_map[i]->selected;
  ------------------
  |  Branch (167:21): [True: 70.5M, False: 1.34k]
  |  Branch (167:43): [True: 70.4M, False: 79.2k]
  ------------------
  168|       |
  169|       |                // This stops demuxer readahead for inactive segments.
  170|  70.5M|                if (!src->current || seg->d != src->current->d)
  ------------------
  |  Branch (170:21): [True: 158k, False: 70.3M]
  |  Branch (170:38): [True: 66.7M, False: 3.59M]
  ------------------
  171|  66.9M|                    selected = false;
  172|  70.5M|                struct sh_stream *sh = demux_get_stream(seg->d, i);
  173|  70.5M|                demuxer_select_track(seg->d, sh, MP_NOPTS_VALUE, selected);
  ------------------
  |  |   38|  70.5M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  174|       |
  175|  70.5M|                update_slave_stats(demuxer, seg->d);
  176|  70.5M|            }
  177|  57.9M|        }
  178|       |
  179|  63.2k|        bool was_selected = src->any_selected;
  180|  63.2k|        src->any_selected = false;
  181|       |
  182|   187k|        for (int n = 0; n < src->num_streams; n++)
  ------------------
  |  Branch (182:25): [True: 124k, False: 63.2k]
  ------------------
  183|   124k|            src->any_selected |= src->streams[n]->selected;
  184|       |
  185|  63.2k|        if (!was_selected && src->any_selected) {
  ------------------
  |  Branch (185:13): [True: 872, False: 62.3k]
  |  Branch (185:30): [True: 436, False: 436]
  ------------------
  186|    436|            src->eof_reached = false;
  187|    436|            src->dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|    436|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  188|    436|            TA_FREEP(&src->next);
  ------------------
  |  |   81|    436|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|    436|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  189|    436|        }
  190|  63.2k|    }
  191|  63.2k|}
demux_timeline.c:update_slave_stats:
   94|  70.6M|{
   95|  70.6M|    demux_report_unbuffered_read_bytes(demuxer, demux_get_bytes_read_hack(slave));
   96|  70.6M|}
demux_timeline.c:d_read_packet:
  368|  69.1k|{
  369|  69.1k|    struct priv *p = demuxer->priv;
  370|  69.1k|    struct virtual_source *src = NULL;
  371|       |
  372|   138k|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (372:21): [True: 69.1k, False: 69.1k]
  ------------------
  373|  69.1k|        struct virtual_source *cur = p->sources[x];
  374|       |
  375|  69.1k|        if (!cur->any_selected || cur->eof_reached)
  ------------------
  |  Branch (375:13): [True: 0, False: 69.1k]
  |  Branch (375:35): [True: 423, False: 68.7k]
  ------------------
  376|    423|            continue;
  377|       |
  378|  68.7k|        if (!cur->current)
  ------------------
  |  Branch (378:13): [True: 423, False: 68.2k]
  ------------------
  379|    423|            switch_segment(demuxer, cur, cur->segments[0], 0, 0, true);
  380|       |
  381|  68.7k|        if (!cur->any_selected || !cur->current || !cur->current->d)
  ------------------
  |  Branch (381:13): [True: 0, False: 68.7k]
  |  Branch (381:35): [True: 0, False: 68.7k]
  |  Branch (381:52): [True: 0, False: 68.7k]
  ------------------
  382|      0|            continue;
  383|       |
  384|  68.7k|        if (!src || cur->dts == MP_NOPTS_VALUE ||
  ------------------
  |  |   38|  68.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (384:13): [True: 68.7k, False: 0]
  |  Branch (384:21): [True: 0, False: 0]
  ------------------
  385|  68.7k|            (src->dts != MP_NOPTS_VALUE && cur->dts < src->dts))
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (385:14): [True: 0, False: 0]
  |  Branch (385:44): [True: 0, False: 0]
  ------------------
  386|  68.7k|            src = cur;
  387|  68.7k|    }
  388|       |
  389|  69.1k|    if (!src)
  ------------------
  |  Branch (389:9): [True: 423, False: 68.7k]
  ------------------
  390|    423|        return false;
  391|       |
  392|  68.7k|    do_read_next_packet(demuxer, src);
  393|  68.7k|    *out_pkt = src->next;
  394|  68.7k|    src->next = NULL;
  395|  68.7k|    return true;
  396|  69.1k|}
demux_timeline.c:switch_segment:
  234|  62.3k|{
  235|  62.3k|    if (!(flags & SEEK_FORWARD))
  ------------------
  |  |   93|  62.3k|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
  |  Branch (235:9): [True: 62.3k, False: 0]
  ------------------
  236|  62.3k|        flags |= SEEK_HR;
  ------------------
  |  |   97|  62.3k|#define SEEK_HR       (1 << 5)      // hr-seek (this is a weak hint only)
  ------------------
  237|       |
  238|  62.3k|    MP_VERBOSE(demuxer, "switch to segment %d\n", new->index);
  ------------------
  |  |   88|  62.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  62.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  239|       |
  240|  62.3k|    if (src->current && src->current->d)
  ------------------
  |  Branch (240:9): [True: 61.9k, False: 436]
  |  Branch (240:25): [True: 61.9k, False: 0]
  ------------------
  241|  61.9k|        update_slave_stats(demuxer, src->current->d);
  242|       |
  243|  62.3k|    src->current = new;
  244|  62.3k|    reopen_lazy_segments(demuxer, src);
  245|  62.3k|    if (!new->d)
  ------------------
  |  Branch (245:9): [True: 0, False: 62.3k]
  ------------------
  246|      0|        return;
  247|  62.3k|    reselect_streams(demuxer);
  248|  62.3k|    if (!src->no_clip)
  ------------------
  |  Branch (248:9): [True: 62.3k, False: 0]
  ------------------
  249|  62.3k|        demux_set_ts_offset(new->d, new->start - new->d_start);
  250|  62.3k|    if (!src->no_clip || !init)
  ------------------
  |  Branch (250:9): [True: 62.3k, False: 0]
  |  Branch (250:26): [True: 0, False: 0]
  ------------------
  251|  62.3k|        demux_seek(new->d, start_pts, flags);
  252|       |
  253|   185k|    for (int n = 0; n < src->num_streams; n++) {
  ------------------
  |  Branch (253:21): [True: 122k, False: 62.3k]
  ------------------
  254|   122k|        struct virtual_stream *vs = src->streams[n];
  255|   122k|        vs->eos_packets = 0;
  256|   122k|    }
  257|       |
  258|  62.3k|    src->eof_reached = false;
  259|  62.3k|    src->eos_packets = 0;
  260|  62.3k|}
demux_timeline.c:reopen_lazy_segments:
  209|  62.3k|{
  210|  62.3k|    if (src->current->d)
  ------------------
  |  Branch (210:9): [True: 62.3k, False: 0]
  ------------------
  211|  62.3k|        return;
  212|       |
  213|       |    // Note: we must _not_ close segments during demuxing,
  214|       |    // because demuxed packets have demux_packet.codec set to objects owned
  215|       |    // by the segments. Closing them would create dangling pointers.
  216|       |
  217|      0|    struct demuxer_params params = {
  218|      0|        .init_fragment = src->tl->init_fragment,
  219|      0|        .skip_lavf_probing = src->tl->dash,
  220|      0|        .stream_flags = demuxer->stream_origin,
  221|      0|    };
  222|      0|    src->current->d = demux_open_url(src->current->url, &params,
  223|      0|                                     demuxer->cancel, demuxer->global);
  224|      0|    if (!src->current->d && !demux_cancel_test(demuxer))
  ------------------
  |  Branch (224:9): [True: 0, False: 0]
  |  Branch (224:29): [True: 0, False: 0]
  ------------------
  225|      0|        MP_ERR(demuxer, "failed to load segment\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  226|      0|    if (src->current->d)
  ------------------
  |  Branch (226:9): [True: 0, False: 0]
  ------------------
  227|      0|        update_slave_stats(demuxer, src->current->d);
  228|      0|    associate_streams(demuxer, src, src->current);
  229|      0|}
demux_timeline.c:do_read_next_packet:
  264|  68.7k|{
  265|  68.7k|    if (src->next)
  ------------------
  |  Branch (265:9): [True: 0, False: 68.7k]
  ------------------
  266|      0|        return;
  267|       |
  268|  68.7k|    struct segment *seg = src->current;
  269|  68.7k|    if (!seg || !seg->d) {
  ------------------
  |  Branch (269:9): [True: 0, False: 68.7k]
  |  Branch (269:17): [True: 0, False: 68.7k]
  ------------------
  270|      0|        src->eof_reached = true;
  271|      0|        return;
  272|      0|    }
  273|       |
  274|  68.7k|    struct demux_packet *pkt = demux_read_any_packet(seg->d);
  275|  68.7k|    if (!pkt || (!src->no_clip && pkt->pts >= seg->end))
  ------------------
  |  Branch (275:9): [True: 62.3k, False: 6.35k]
  |  Branch (275:18): [True: 6.35k, False: 0]
  |  Branch (275:35): [True: 0, False: 6.35k]
  ------------------
  276|  62.3k|        src->eos_packets += 1;
  277|       |
  278|  68.7k|    update_slave_stats(demuxer, seg->d);
  279|       |
  280|       |    // Test for EOF. Do this here to properly run into EOF even if other
  281|       |    // streams are disabled etc. If it somehow doesn't manage to reach the end
  282|       |    // after demuxing a high (bit arbitrary) number of packets, assume one of
  283|       |    // the streams went EOF early.
  284|  68.7k|    bool eos_reached = src->eos_packets > 0;
  285|  68.7k|    if (eos_reached && src->eos_packets < 100) {
  ------------------
  |  Branch (285:9): [True: 62.3k, False: 6.35k]
  |  Branch (285:24): [True: 62.3k, False: 0]
  ------------------
  286|   185k|        for (int n = 0; n < src->num_streams; n++) {
  ------------------
  |  Branch (286:25): [True: 122k, False: 62.3k]
  ------------------
  287|   122k|            struct virtual_stream *vs = src->streams[n];
  288|   122k|            if (vs->selected) {
  ------------------
  |  Branch (288:17): [True: 122k, False: 0]
  ------------------
  289|   122k|                int max_packets = 0;
  290|   122k|                if (vs->sh->type == STREAM_AUDIO)
  ------------------
  |  Branch (290:21): [True: 60.3k, False: 62.3k]
  ------------------
  291|  60.3k|                    max_packets = 1;
  292|   122k|                if (vs->sh->type == STREAM_VIDEO)
  ------------------
  |  Branch (292:21): [True: 62.3k, False: 60.3k]
  ------------------
  293|  62.3k|                    max_packets = 16;
  294|   122k|                eos_reached &= vs->eos_packets >= max_packets;
  295|   122k|            }
  296|   122k|        }
  297|  62.3k|    }
  298|       |
  299|  68.7k|    src->eof_reached = false;
  300|       |
  301|  68.7k|    if (eos_reached || !pkt) {
  ------------------
  |  Branch (301:9): [True: 0, False: 68.7k]
  |  Branch (301:24): [True: 62.3k, False: 6.35k]
  ------------------
  302|  62.3k|        talloc_free(pkt);
  ------------------
  |  |   47|  62.3k|#define talloc_free                     ta_free
  ------------------
  303|       |
  304|  62.3k|        struct segment *next = NULL;
  305|  28.9M|        for (int n = 0; n < src->num_segments - 1; n++) {
  ------------------
  |  Branch (305:25): [True: 28.9M, False: 423]
  ------------------
  306|  28.9M|            if (src->segments[n] == seg) {
  ------------------
  |  Branch (306:17): [True: 61.9k, False: 28.8M]
  ------------------
  307|  61.9k|                next = src->segments[n + 1];
  308|  61.9k|                break;
  309|  61.9k|            }
  310|  28.9M|        }
  311|  62.3k|        if (!next) {
  ------------------
  |  Branch (311:13): [True: 423, False: 61.9k]
  ------------------
  312|    423|            src->eof_reached = true;
  313|    423|            return;
  314|    423|        }
  315|  61.9k|        switch_segment(demuxer, src, next, next->start, 0, true);
  316|  61.9k|        return; // reader will retry
  317|  62.3k|    }
  318|       |
  319|  6.35k|    if (pkt->stream < 0 || pkt->stream >= seg->num_stream_map)
  ------------------
  |  Branch (319:9): [True: 0, False: 6.35k]
  |  Branch (319:28): [True: 0, False: 6.35k]
  ------------------
  320|      0|        goto drop;
  321|       |
  322|  6.35k|    if (!src->no_clip || src->delay_open) {
  ------------------
  |  Branch (322:9): [True: 6.35k, False: 0]
  |  Branch (322:26): [True: 0, False: 0]
  ------------------
  323|  6.35k|        pkt->segmented = true;
  324|  6.35k|        if (!pkt->codec)
  ------------------
  |  Branch (324:13): [True: 6.35k, False: 0]
  ------------------
  325|  6.35k|            pkt->codec = demux_get_stream(seg->d, pkt->stream)->codec;
  326|  6.35k|    }
  327|  6.35k|    if (!src->no_clip) {
  ------------------
  |  Branch (327:9): [True: 6.35k, False: 0]
  ------------------
  328|  6.35k|        if (pkt->start == MP_NOPTS_VALUE || pkt->start < seg->start)
  ------------------
  |  |   38|  12.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (328:13): [True: 6.35k, False: 0]
  |  Branch (328:45): [True: 0, False: 0]
  ------------------
  329|  6.35k|            pkt->start = seg->start;
  330|  6.35k|        if (pkt->end == MP_NOPTS_VALUE || pkt->end > seg->end)
  ------------------
  |  |   38|  12.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (330:13): [True: 6.35k, False: 0]
  |  Branch (330:43): [True: 0, False: 0]
  ------------------
  331|  6.35k|            pkt->end = seg->end;
  332|  6.35k|    }
  333|       |
  334|  6.35k|    struct virtual_stream *vs = seg->stream_map[pkt->stream];
  335|  6.35k|    if (!vs)
  ------------------
  |  Branch (335:9): [True: 0, False: 6.35k]
  ------------------
  336|      0|        goto drop;
  337|       |
  338|       |    // for refresh seeks, demux.c prefers monotonically increasing packet pos
  339|       |    // since the packet pos is meaningless anyway for timeline, use it
  340|  6.35k|    if (pkt->pos >= 0)
  ------------------
  |  Branch (340:9): [True: 6.35k, False: 0]
  ------------------
  341|  6.35k|        pkt->pos |= (seg->index & 0x7FFFULL) << 48;
  342|       |
  343|  6.35k|    if (pkt->pts != MP_NOPTS_VALUE && !src->no_clip && pkt->pts >= seg->end) {
  ------------------
  |  |   38|  12.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (343:9): [True: 2.22k, False: 4.12k]
  |  Branch (343:39): [True: 2.22k, False: 0]
  |  Branch (343:56): [True: 0, False: 2.22k]
  ------------------
  344|       |        // Trust the keyframe flag. Might not always be a good idea, but will
  345|       |        // be sufficient at least with mkv. The problem is that this flag is
  346|       |        // not well-defined in libavformat and is container-dependent.
  347|      0|        if (pkt->keyframe || vs->eos_packets == INT_MAX) {
  ------------------
  |  Branch (347:13): [True: 0, False: 0]
  |  Branch (347:30): [True: 0, False: 0]
  ------------------
  348|      0|            vs->eos_packets = INT_MAX;
  349|      0|            goto drop;
  350|      0|        } else {
  351|      0|            vs->eos_packets += 1;
  352|      0|        }
  353|      0|    }
  354|       |
  355|  6.35k|    double dts = pkt->dts != MP_NOPTS_VALUE ? pkt->dts : pkt->pts;
  ------------------
  |  |   38|  6.35k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (355:18): [True: 2.22k, False: 4.12k]
  ------------------
  356|  6.35k|    if (src->dts == MP_NOPTS_VALUE || (dts != MP_NOPTS_VALUE && dts > src->dts))
  ------------------
  |  |   38|  12.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                  if (src->dts == MP_NOPTS_VALUE || (dts != MP_NOPTS_VALUE && dts > src->dts))
  ------------------
  |  |   38|  4.48k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (356:9): [True: 4.11k, False: 2.24k]
  |  Branch (356:40): [True: 2.17k, False: 67]
  |  Branch (356:65): [True: 2.17k, False: 0]
  ------------------
  357|  6.28k|        src->dts = dts;
  358|       |
  359|  6.35k|    pkt->stream = vs->sh->index;
  360|  6.35k|    src->next = pkt;
  361|  6.35k|    return;
  362|       |
  363|      0|drop:
  364|      0|    talloc_free(pkt);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  365|      0|}
demux_timeline.c:d_close:
  686|    436|{
  687|    436|    struct priv *p = demuxer->priv;
  688|       |
  689|    872|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (689:21): [True: 436, False: 436]
  ------------------
  690|    436|        struct virtual_source *src = p->sources[x];
  691|       |
  692|    436|        src->current = NULL;
  693|    436|        TA_FREEP(&src->next);
  ------------------
  |  |   81|    436|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|    436|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  694|    436|        close_lazy_segments(demuxer, src);
  695|    436|    }
  696|       |
  697|    436|    if (p->owns_tl) {
  ------------------
  |  Branch (697:9): [True: 436, False: 0]
  ------------------
  698|    436|        struct demuxer *master = p->tl->demuxer;
  699|    436|        timeline_destroy(p->tl);
  700|    436|        demux_free(master);
  701|    436|    }
  702|    436|}
demux_timeline.c:close_lazy_segments:
  195|    436|{
  196|       |    // unload previous segment
  197|  63.0k|    for (int n = 0; n < src->num_segments; n++) {
  ------------------
  |  Branch (197:21): [True: 62.6k, False: 436]
  ------------------
  198|  62.6k|        struct segment *seg = src->segments[n];
  199|  62.6k|        if (seg != src->current && seg->d && seg->lazy) {
  ------------------
  |  Branch (199:13): [True: 62.6k, False: 0]
  |  Branch (199:36): [True: 62.6k, False: 0]
  |  Branch (199:46): [True: 0, False: 62.6k]
  ------------------
  200|      0|            TA_FREEP(&src->next); // might depend on one of the sub-demuxers
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  201|      0|            demux_free(seg->d);
  202|      0|            seg->d = NULL;
  203|      0|        }
  204|  62.6k|    }
  205|    436|}
demux_timeline.c:d_seek:
  416|     13|{
  417|     13|    struct priv *p = demuxer->priv;
  418|       |
  419|     13|    seek_pts = seek_pts * ((flags & SEEK_FACTOR) ? p->duration : 1);
  ------------------
  |  |   92|     13|#define SEEK_FACTOR   (1 << 1)      // argument is in range [0,1]
  ------------------
  |  Branch (419:28): [True: 0, False: 13]
  ------------------
  420|     13|    flags &= SEEK_FORWARD | SEEK_HR;
  ------------------
  |  |   93|     13|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
                  flags &= SEEK_FORWARD | SEEK_HR;
  ------------------
  |  |   97|     13|#define SEEK_HR       (1 << 5)      // hr-seek (this is a weak hint only)
  ------------------
  421|       |
  422|       |    // The intention is to seek audio streams to the same target as video
  423|       |    // streams if they are separate streams. Video streams usually have more
  424|       |    // coarse keyframe snapping, which could leave video without audio.
  425|     13|    struct virtual_source *master = NULL;
  426|     13|    bool has_slaves = false;
  427|     26|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (427:21): [True: 13, False: 13]
  ------------------
  428|     13|        struct virtual_source *src = p->sources[x];
  429|       |
  430|     13|        bool any_audio = false, any_video = false;
  431|     26|        for (int i = 0; i < src->num_streams; i++) {
  ------------------
  |  Branch (431:25): [True: 13, False: 13]
  ------------------
  432|     13|            struct virtual_stream *str = src->streams[i];
  433|     13|            if (str->selected) {
  ------------------
  |  Branch (433:17): [True: 13, False: 0]
  ------------------
  434|     13|                if (str->sh->type == STREAM_VIDEO)
  ------------------
  |  Branch (434:21): [True: 0, False: 13]
  ------------------
  435|      0|                    any_video = true;
  436|     13|                if (str->sh->type == STREAM_AUDIO)
  ------------------
  |  Branch (436:21): [True: 13, False: 0]
  ------------------
  437|     13|                    any_audio = true;
  438|     13|            }
  439|     13|        }
  440|       |
  441|     13|        if (any_video)
  ------------------
  |  Branch (441:13): [True: 0, False: 13]
  ------------------
  442|      0|            master = src;
  443|       |        // A true slave stream is audio-only; this also prevents that the master
  444|       |        // stream is considered a slave stream.
  445|     13|        if (any_audio && !any_video)
  ------------------
  |  Branch (445:13): [True: 13, False: 0]
  |  Branch (445:26): [True: 13, False: 0]
  ------------------
  446|     13|            has_slaves = true;
  447|     13|    }
  448|       |
  449|     13|    if (!has_slaves)
  ------------------
  |  Branch (449:9): [True: 0, False: 13]
  ------------------
  450|      0|        master = NULL;
  451|       |
  452|     13|    if (master) {
  ------------------
  |  Branch (452:9): [True: 0, False: 13]
  ------------------
  453|      0|        seek_source(demuxer, master, seek_pts, flags);
  454|      0|        do_read_next_packet(demuxer, master);
  455|      0|        if (master->next && master->next->pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (455:13): [True: 0, False: 0]
  |  Branch (455:29): [True: 0, False: 0]
  ------------------
  456|       |            // Assume we got a seek target. Actually apply the heuristic.
  457|      0|            MP_VERBOSE(demuxer, "adjust seek target from %f to %f\n", seek_pts,
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  458|      0|                       master->next->pts);
  459|      0|            seek_pts = master->next->pts;
  460|      0|            flags &= ~(unsigned)SEEK_FORWARD;
  ------------------
  |  |   93|      0|#define SEEK_FORWARD  (1 << 2)      // prefer later time if not exact
  ------------------
  461|      0|        }
  462|      0|    }
  463|       |
  464|     26|    for (int x = 0; x < p->num_sources; x++) {
  ------------------
  |  Branch (464:21): [True: 13, False: 13]
  ------------------
  465|     13|        struct virtual_source *src = p->sources[x];
  466|     13|        if (src != master && src->any_selected)
  ------------------
  |  Branch (466:13): [True: 13, False: 0]
  |  Branch (466:30): [True: 13, False: 0]
  ------------------
  467|     13|            seek_source(demuxer, src, seek_pts, flags);
  468|     13|    }
  469|     13|}
demux_timeline.c:seek_source:
  400|     13|{
  401|     13|    struct segment *new = src->segments[src->num_segments - 1];
  402|     13|    for (int n = 0; n < src->num_segments; n++) {
  ------------------
  |  Branch (402:21): [True: 13, False: 0]
  ------------------
  403|     13|        if (pts < src->segments[n]->end) {
  ------------------
  |  Branch (403:13): [True: 13, False: 0]
  ------------------
  404|     13|            new = src->segments[n];
  405|     13|            break;
  406|     13|        }
  407|     13|    }
  408|       |
  409|     13|    switch_segment(demuxer, src, new, pts, flags, false);
  410|       |
  411|     13|    src->dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|     13|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  412|     13|    TA_FREEP(&src->next);
  ------------------
  |  |   81|     13|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|     13|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  413|     13|}
demux_timeline.c:d_switched_tracks:
  705|    441|{
  706|    441|    reselect_streams(demuxer);
  707|    441|}

ebml_read_id:
   62|  24.4k|{
   63|  24.4k|    int i, len_mask = 0x80;
   64|  24.4k|    uint32_t id;
   65|       |
   66|  51.4k|    for (i = 0, id = stream_read_char(s); i < 4 && !(id & len_mask); i++)
  ------------------
  |  Branch (66:43): [True: 50.9k, False: 484]
  |  Branch (66:52): [True: 27.0k, False: 23.9k]
  ------------------
   67|  27.0k|        len_mask >>= 1;
   68|  24.4k|    if (i >= 4)
  ------------------
  |  Branch (68:9): [True: 484, False: 23.9k]
  ------------------
   69|    484|        return EBML_ID_INVALID;
  ------------------
  |  |   68|    484|#define EBML_ID_INVALID 0xffffffff
  ------------------
   70|  49.0k|    while (i--)
  ------------------
  |  Branch (70:12): [True: 25.0k, False: 23.9k]
  ------------------
   71|  25.0k|        id = (id << 8) | stream_read_char(s);
   72|  23.9k|    return id;
   73|  24.4k|}
ebml_read_length:
   79|     99|{
   80|     99|    int byte = stream_read_char(s);
   81|     99|    if (byte == STREAM_EOF || byte < 1)
  ------------------
  |  |   71|    198|#define STREAM_EOF (-256)
  ------------------
  |  Branch (81:9): [True: 0, False: 99]
  |  Branch (81:31): [True: 0, False: 99]
  ------------------
   82|      0|        return EBML_UINT_INVALID;
  ------------------
  |  |   78|      0|#define EBML_UINT_INVALID   UINT64_MAX
  ------------------
   83|       |
   84|     99|    uint8_t leading_zeros = 7 - mp_log2((uint8_t)byte);
   85|     99|    uint64_t len = (uint8_t)byte & ((1 << (8 - leading_zeros - 1)) - 1);
   86|    251|    for (uint8_t i = 0; i < leading_zeros; ++i) {
  ------------------
  |  Branch (86:25): [True: 152, False: 99]
  ------------------
   87|    152|        byte = stream_read_char(s);
   88|    152|        if (byte == STREAM_EOF)
  ------------------
  |  |   71|    152|#define STREAM_EOF (-256)
  ------------------
  |  Branch (88:13): [True: 0, False: 152]
  ------------------
   89|      0|            return EBML_UINT_INVALID;
  ------------------
  |  |   78|      0|#define EBML_UINT_INVALID   UINT64_MAX
  ------------------
   90|    152|        len = (len << 8) | (uint8_t)byte;
   91|    152|    }
   92|       |
   93|     99|    return len;
   94|     99|}
ebml_read_element:
  588|     99|{
  589|     99|    ctx->has_errors = false;
  590|     99|    int msglevel = ctx->no_error_messages ? MSGL_DEBUG : MSGL_WARN;
  ------------------
  |  Branch (590:20): [True: 99, False: 0]
  ------------------
  591|     99|    uint64_t length = ebml_read_length(s);
  592|     99|    if (s->eof) {
  ------------------
  |  Branch (592:9): [True: 0, False: 99]
  ------------------
  593|      0|        MP_MSG(ctx, msglevel, "Unexpected end of file "
  ------------------
  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  594|      0|                   "- partial or corrupt file?\n");
  595|      0|        return -1;
  596|      0|    }
  597|     99|    if (length == EBML_UINT_INVALID) {
  ------------------
  |  |   78|     99|#define EBML_UINT_INVALID   UINT64_MAX
  ------------------
  |  Branch (597:9): [True: 0, False: 99]
  ------------------
  598|      0|        MP_MSG(ctx, msglevel, "EBML element with unknown length - unsupported\n");
  ------------------
  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  599|      0|        return -1;
  600|      0|    }
  601|       |#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  602|       |    if (length > (512 << 20)) {
  603|       |#else
  604|     99|    if (length > (64 << 20)) {
  ------------------
  |  Branch (604:9): [True: 11, False: 88]
  ------------------
  605|     11|#endif
  606|     11|        MP_MSG(ctx, msglevel, "Element too big (%" PRIu64 " MiB) - skipping\n", length >> 20);
  ------------------
  |  |   82|     11|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  607|     11|        return -1;
  608|     11|    }
  609|     88|    ctx->talloc_ctx = talloc_size(NULL, length);
  ------------------
  |  |   43|     88|#define talloc_size                     ta_xalloc_size
  |  |  ------------------
  |  |  |  |  120|     88|#define ta_xalloc_size(...)             ta_oom_p(ta_alloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  153|     88|#define ta_alloc_size(...)      ta_dbg_set_loc(ta_alloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|     88|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|     88|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|     88|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  610|     88|    int read_len = stream_read(s, ctx->talloc_ctx, length);
  611|     88|    if (read_len < length)
  ------------------
  |  Branch (611:9): [True: 25, False: 63]
  ------------------
  612|     25|        MP_MSG(ctx, msglevel, "Unexpected end of file - partial or corrupt file?\n");
  ------------------
  |  |   82|     25|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  613|     88|    ebml_parse_element(ctx, target, ctx->talloc_ctx, read_len, desc, 0);
  614|     88|    if (ctx->has_errors)
  ------------------
  |  Branch (614:9): [True: 84, False: 4]
  ------------------
  615|     84|        MP_MSG(ctx, msglevel, "Error parsing element %s\n", desc->name);
  ------------------
  |  |   82|     84|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  616|     88|    return 0;
  617|     99|}
ebml.c:ebml_parse_element:
  320|     88|{
  321|     88|    mp_assert(type->type == EBML_TYPE_SUBELEMENTS);
  ------------------
  |  |   41|     88|#define mp_assert assert
  ------------------
  322|     88|    mp_assert(level < 8);
  ------------------
  |  |   41|     88|#define mp_assert assert
  ------------------
  323|     88|    MP_TRACE(ctx, "%.*sParsing element %s\n", level, "       ", type->name);
  ------------------
  |  |   90|     88|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     88|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  324|       |
  325|     88|    char *s = target;
  326|     88|    uint8_t *end = data + size;
  327|     88|    uint8_t *p = data;
  328|     88|    int num_elems[MAX_EBML_SUBELEMENTS] = {0};
  329|  2.22k|    while (p < end) {
  ------------------
  |  Branch (329:12): [True: 2.15k, False: 70]
  ------------------
  330|  2.15k|        uint8_t *startp = p;
  331|  2.15k|        int len;
  332|  2.15k|        uint32_t id = ebml_parse_id(p, end - p, &len);
  333|  2.15k|        if (len > end - p)
  ------------------
  |  Branch (333:13): [True: 0, False: 2.15k]
  ------------------
  334|      0|            goto past_end_error;
  335|  2.15k|        if (len < 0) {
  ------------------
  |  Branch (335:13): [True: 10, False: 2.14k]
  ------------------
  336|     10|            MP_ERR(ctx, "Error parsing subelement id\n");
  ------------------
  |  |   85|     10|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     10|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  337|     10|            goto other_error;
  338|     10|        }
  339|  2.14k|        p += len;
  340|  2.14k|        uint64_t length = ebml_parse_length(p, end - p, &len);
  341|  2.14k|        if (len > end - p)
  ------------------
  |  Branch (341:13): [True: 0, False: 2.14k]
  ------------------
  342|      0|            goto past_end_error;
  343|  2.14k|        if (len < 0) {
  ------------------
  |  Branch (343:13): [True: 8, False: 2.13k]
  ------------------
  344|      8|            MP_ERR(ctx, "Error parsing subelement length\n");
  ------------------
  |  |   85|      8|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      8|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  345|      8|            goto other_error;
  346|      8|        }
  347|  2.13k|        p += len;
  348|       |
  349|  2.13k|        int field_idx = -1;
  350|  17.0k|        for (int i = 0; i < type->field_count; i++)
  ------------------
  |  Branch (350:25): [True: 14.9k, False: 2.13k]
  ------------------
  351|  14.9k|            if (type->fields[i].id == id) {
  ------------------
  |  Branch (351:17): [True: 0, False: 14.9k]
  ------------------
  352|      0|                field_idx = i;
  353|      0|                num_elems[i]++;
  354|      0|                if (num_elems[i] >= 0x70000000) {
  ------------------
  |  Branch (354:21): [True: 0, False: 0]
  ------------------
  355|      0|                    MP_ERR(ctx, "Too many EBML subelements.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  356|      0|                    goto other_error;
  357|      0|                }
  358|      0|                break;
  359|      0|            }
  360|       |
  361|  2.13k|        if (length > end - p) {
  ------------------
  |  Branch (361:13): [True: 66, False: 2.07k]
  ------------------
  362|     66|            if (field_idx >= 0 && type->fields[field_idx].desc->type
  ------------------
  |  Branch (362:17): [True: 0, False: 66]
  |  Branch (362:35): [True: 0, False: 0]
  ------------------
  363|      0|                != EBML_TYPE_SUBELEMENTS) {
  364|      0|                MP_ERR(ctx, "Subelement content goes "
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  365|      0|                       "past end of containing element\n");
  366|      0|                goto other_error;
  367|      0|            }
  368|       |            // Try to parse what is possible from inside this partial element
  369|     66|            ctx->has_errors = true;
  370|     66|            length = end - p;
  371|     66|        }
  372|  2.13k|        p += length;
  373|       |
  374|  2.13k|        continue;
  375|       |
  376|      0|    past_end_error:
  377|      0|        MP_ERR(ctx, "Subelement headers go past end of containing element\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  378|     18|    other_error:
  379|     18|        ctx->has_errors = true;
  380|     18|        end = startp;
  381|     18|        break;
  382|      0|    }
  383|       |
  384|    704|    for (int i = 0; i < type->field_count; i++) {
  ------------------
  |  Branch (384:21): [True: 616, False: 88]
  ------------------
  385|    616|        if (num_elems[i] && type->fields[i].multiple) {
  ------------------
  |  Branch (385:13): [True: 0, False: 616]
  |  Branch (385:29): [True: 0, False: 0]
  ------------------
  386|      0|            char *ptr = s + type->fields[i].offset;
  387|      0|            switch (type->fields[i].desc->type) {
  388|      0|            case EBML_TYPE_SUBELEMENTS: {
  ------------------
  |  Branch (388:13): [True: 0, False: 0]
  ------------------
  389|      0|                size_t max = 1000000000 / type->fields[i].desc->size;
  390|      0|                if (num_elems[i] > max) {
  ------------------
  |  Branch (390:21): [True: 0, False: 0]
  ------------------
  391|      0|                    MP_ERR(ctx, "Too many subelements.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  392|      0|                    num_elems[i] = max;
  393|      0|                }
  394|      0|                int sz = num_elems[i] * type->fields[i].desc->size;
  395|      0|                *(generic_struct **) ptr = talloc_zero_size(ctx->talloc_ctx, sz);
  ------------------
  |  |   44|      0|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|      0|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|      0|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  396|      0|                break;
  397|      0|            }
  398|      0|            case EBML_TYPE_UINT:
  ------------------
  |  Branch (398:13): [True: 0, False: 0]
  ------------------
  399|      0|                *(uint64_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  400|      0|                                                       uint64_t, num_elems[i]);
  401|      0|                break;
  402|      0|            case EBML_TYPE_SINT:
  ------------------
  |  Branch (402:13): [True: 0, False: 0]
  ------------------
  403|      0|                *(int64_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  404|      0|                                                      int64_t, num_elems[i]);
  405|      0|                break;
  406|      0|            case EBML_TYPE_FLOAT:
  ------------------
  |  Branch (406:13): [True: 0, False: 0]
  ------------------
  407|      0|                *(double **) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  408|      0|                                                     double, num_elems[i]);
  409|      0|                break;
  410|      0|            case EBML_TYPE_STR:
  ------------------
  |  Branch (410:13): [True: 0, False: 0]
  ------------------
  411|      0|                *(char ***) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  412|      0|                                                    char *, num_elems[i]);
  413|      0|                break;
  414|      0|            case EBML_TYPE_BINARY:
  ------------------
  |  Branch (414:13): [True: 0, False: 0]
  ------------------
  415|      0|                *(struct bstr **) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  416|      0|                                                          struct bstr,
  417|      0|                                                          num_elems[i]);
  418|      0|                break;
  419|      0|            case EBML_TYPE_EBML_ID:
  ------------------
  |  Branch (419:13): [True: 0, False: 0]
  ------------------
  420|      0|                *(int32_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  421|      0|                                                      uint32_t, num_elems[i]);
  422|      0|                break;
  423|      0|            default:
  ------------------
  |  Branch (423:13): [True: 0, False: 0]
  ------------------
  424|      0|                MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
  425|      0|            }
  426|      0|        }
  427|    616|    }
  428|       |
  429|  2.22k|    while (data < end) {
  ------------------
  |  Branch (429:12): [True: 2.13k, False: 88]
  ------------------
  430|  2.13k|        int len;
  431|  2.13k|        uint32_t id = ebml_parse_id(data, end - data, &len);
  432|  2.13k|        if (len < 0 || len > end - data) {
  ------------------
  |  Branch (432:13): [True: 0, False: 2.13k]
  |  Branch (432:24): [True: 0, False: 2.13k]
  ------------------
  433|      0|            MP_ERR(ctx, "Error parsing subelement\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  434|      0|            break;
  435|      0|        }
  436|  2.13k|        data += len;
  437|  2.13k|        uint64_t length = ebml_parse_length(data, end - data, &len);
  438|  2.13k|        if (len < 0 || len > end - data) {
  ------------------
  |  Branch (438:13): [True: 0, False: 2.13k]
  |  Branch (438:24): [True: 0, False: 2.13k]
  ------------------
  439|      0|            MP_ERR(ctx, "Error parsing subelement length\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  440|      0|            break;
  441|      0|        }
  442|  2.13k|        data += len;
  443|  2.13k|        if (length > end - data) {
  ------------------
  |  Branch (443:13): [True: 66, False: 2.07k]
  ------------------
  444|       |            // Try to parse what is possible from inside this partial element
  445|     66|            length = end - data;
  446|     66|            MP_ERR(ctx, "Next subelement content goes "
  ------------------
  |  |   85|     66|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     66|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  447|     66|                   "past end of containing element, will be truncated\n");
  448|     66|        }
  449|  2.13k|        int field_idx = -1;
  450|  17.0k|        for (int i = 0; i < type->field_count; i++)
  ------------------
  |  Branch (450:25): [True: 14.9k, False: 2.13k]
  ------------------
  451|  14.9k|            if (type->fields[i].id == id) {
  ------------------
  |  Branch (451:17): [True: 0, False: 14.9k]
  ------------------
  452|      0|                field_idx = i;
  453|      0|                break;
  454|      0|            }
  455|  2.13k|        if (field_idx < 0) {
  ------------------
  |  Branch (455:13): [True: 2.13k, False: 0]
  ------------------
  456|  2.13k|            if (id == 0xec) {
  ------------------
  |  Branch (456:17): [True: 126, False: 2.01k]
  ------------------
  457|    126|                MP_TRACE(ctx, "%.*sIgnoring Void element "
  ------------------
  |  |   90|    126|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    126|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  458|    126|                         "size: %"PRIu64"\n", level+1, "        ", length);
  459|  2.01k|            } else if (id == 0xbf) {
  ------------------
  |  Branch (459:24): [True: 583, False: 1.42k]
  ------------------
  460|    583|                MP_TRACE(ctx, "%.*sIgnoring CRC-32 "
  ------------------
  |  |   90|    583|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    583|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  461|    583|                         "element size: %"PRIu64"\n", level+1, "        ",
  462|    583|                         length);
  463|  1.42k|            } else {
  464|  1.42k|                MP_DBG(ctx, "Ignoring unrecognized "
  ------------------
  |  |   89|  1.42k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.42k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  465|  1.42k|                       "subelement. ID: %x size: %"PRIu64"\n", id, length);
  466|  1.42k|            }
  467|  2.13k|            data += length;
  468|  2.13k|            continue;
  469|  2.13k|        }
  470|      0|        const struct ebml_field_desc *fd = &type->fields[field_idx];
  471|      0|        const struct ebml_elem_desc *ed = fd->desc;
  472|      0|        bool multiple = fd->multiple;
  473|      0|        int *countptr = (int *) (s + fd->count_offset);
  474|      0|        if (*countptr >= num_elems[field_idx]) {
  ------------------
  |  Branch (474:13): [True: 0, False: 0]
  ------------------
  475|       |            // Shouldn't happen on any sane file without bugs
  476|      0|            MP_ERR(ctx, "Too many subelements.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  477|      0|            ctx->has_errors = true;
  478|      0|            data += length;
  479|      0|            continue;
  480|      0|        }
  481|      0|        if (*countptr > 0 && !multiple) {
  ------------------
  |  Branch (481:13): [True: 0, False: 0]
  |  Branch (481:30): [True: 0, False: 0]
  ------------------
  482|      0|            MP_WARN(ctx, "Another subelement of type "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  483|      0|                    "%x %s (size: %"PRIu64"). Only one allowed. Ignoring.\n",
  484|      0|                    id, ed->name, length);
  485|      0|            ctx->has_errors = true;
  486|      0|            data += length;
  487|      0|            continue;
  488|      0|        }
  489|      0|        MP_TRACE(ctx, "%.*sParsing %x %s size: %"PRIu64
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  490|      0|                 " value: ", level+1, "        ", id, ed->name, length);
  491|       |
  492|      0|        char *fieldptr = s + fd->offset;
  493|      0|        switch (ed->type) {
  494|      0|        case EBML_TYPE_SUBELEMENTS:
  ------------------
  |  Branch (494:9): [True: 0, False: 0]
  ------------------
  495|      0|            MP_TRACE(ctx, "subelements\n");
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  496|      0|            char *subelptr;
  497|      0|            if (multiple) {
  ------------------
  |  Branch (497:17): [True: 0, False: 0]
  ------------------
  498|      0|                char *array_start = (char *) *(generic_struct **) fieldptr;
  499|      0|                subelptr = array_start + *countptr * ed->size;
  500|      0|            } else
  501|      0|                subelptr = fieldptr;
  502|      0|            ebml_parse_element(ctx, subelptr, data, length, ed, level + 1);
  503|      0|            break;
  504|       |
  505|      0|        case EBML_TYPE_UINT:;
  ------------------
  |  Branch (505:9): [True: 0, False: 0]
  ------------------
  506|      0|            uint64_t *uintptr;
  507|      0|#define GETPTR(subelptr, fieldtype)                                     \
  508|      0|            if (multiple)                                               \
  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  510|      0|            else                                                        \
  511|      0|                subelptr = (fieldtype *) fieldptr
  512|      0|            GETPTR(uintptr, uint64_t);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  513|      0|            if (length < 1 || length > 8) {
  ------------------
  |  Branch (513:17): [True: 0, False: 0]
  |  Branch (513:31): [True: 0, False: 0]
  ------------------
  514|      0|                MP_ERR(ctx, "uint invalid length %"PRIu64"\n", length);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  515|      0|                goto error;
  516|      0|            }
  517|      0|            *uintptr = ebml_parse_uint(data, length);
  518|      0|            MP_TRACE(ctx, "uint %"PRIu64"\n", *uintptr);
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  519|      0|            break;
  520|       |
  521|      0|        case EBML_TYPE_SINT:;
  ------------------
  |  Branch (521:9): [True: 0, False: 0]
  ------------------
  522|      0|            int64_t *sintptr;
  523|      0|            GETPTR(sintptr, int64_t);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  524|      0|            if (length > 8) {
  ------------------
  |  Branch (524:17): [True: 0, False: 0]
  ------------------
  525|      0|                MP_ERR(ctx, "sint invalid length %"PRIu64"\n", length);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  526|      0|                goto error;
  527|      0|            }
  528|      0|            *sintptr = ebml_parse_sint(data, length);
  529|      0|            MP_TRACE(ctx, "sint %"PRId64"\n", *sintptr);
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  530|      0|            break;
  531|       |
  532|      0|        case EBML_TYPE_FLOAT:;
  ------------------
  |  Branch (532:9): [True: 0, False: 0]
  ------------------
  533|      0|            double *floatptr;
  534|      0|            GETPTR(floatptr, double);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  535|      0|            if (length != 0 && length != 4 && length != 8) {
  ------------------
  |  Branch (535:17): [True: 0, False: 0]
  |  Branch (535:32): [True: 0, False: 0]
  |  Branch (535:47): [True: 0, False: 0]
  ------------------
  536|      0|                MP_ERR(ctx, "float invalid length %"PRIu64"\n", length);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  537|      0|                goto error;
  538|      0|            }
  539|      0|            *floatptr = ebml_parse_float(data, length);
  540|      0|            MP_DBG(ctx, "float %f\n", *floatptr);
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  541|      0|            break;
  542|       |
  543|      0|        case EBML_TYPE_STR:
  ------------------
  |  Branch (543:9): [True: 0, False: 0]
  ------------------
  544|      0|            if (length > 1024 * 1024) {
  ------------------
  |  Branch (544:17): [True: 0, False: 0]
  ------------------
  545|      0|                MP_ERR(ctx, "Not reading overly long string element.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  546|      0|                break;
  547|      0|            }
  548|      0|            char **strptr;
  549|      0|            GETPTR(strptr, char *);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  550|      0|            *strptr = talloc_strndup(ctx->talloc_ctx, data, length);
  ------------------
  |  |   51|      0|#define talloc_strndup                  ta_xstrndup
  ------------------
  551|      0|            MP_TRACE(ctx, "string \"%s\"\n", *strptr);
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  552|      0|            break;
  553|       |
  554|      0|        case EBML_TYPE_BINARY:;
  ------------------
  |  Branch (554:9): [True: 0, False: 0]
  ------------------
  555|      0|            if (length > 0x80000000) {
  ------------------
  |  Branch (555:17): [True: 0, False: 0]
  ------------------
  556|      0|                MP_ERR(ctx, "Not reading overly long EBML element.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  557|      0|                break;
  558|      0|            }
  559|      0|            struct bstr *binptr;
  560|      0|            GETPTR(binptr, struct bstr);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  561|      0|            binptr->start = data;
  562|      0|            binptr->len = length;
  563|      0|            MP_TRACE(ctx, "binary %zd bytes\n", binptr->len);
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  564|      0|            break;
  565|       |
  566|      0|        case EBML_TYPE_EBML_ID:;
  ------------------
  |  Branch (566:9): [True: 0, False: 0]
  ------------------
  567|      0|            uint32_t *idptr;
  568|      0|            GETPTR(idptr, uint32_t);
  ------------------
  |  |  508|      0|            if (multiple)                                               \
  |  |  ------------------
  |  |  |  Branch (508:17): [True: 0, False: 0]
  |  |  ------------------
  |  |  509|      0|                subelptr = *(fieldtype **) fieldptr + *countptr;        \
  |  |  510|      0|            else                                                        \
  |  |  511|      0|                subelptr = (fieldtype *) fieldptr
  ------------------
  569|      0|            *idptr = ebml_parse_id(data, end - data, &len);
  570|      0|            if (len != length) {
  ------------------
  |  Branch (570:17): [True: 0, False: 0]
  ------------------
  571|      0|                MP_ERR(ctx, "ebml_id broken value\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  572|      0|                goto error;
  573|      0|            }
  574|      0|            MP_TRACE(ctx, "ebml_id %x\n", (unsigned)*idptr);
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  575|      0|            break;
  576|      0|        default:
  ------------------
  |  Branch (576:9): [True: 0, False: 0]
  ------------------
  577|      0|            MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
  578|      0|        }
  579|      0|        *countptr += 1;
  580|      0|    error:
  581|      0|        data += length;
  582|      0|    }
  583|     88|}
ebml.c:ebml_parse_id:
  231|  4.29k|{
  232|  4.29k|    *length = -1;
  233|  4.29k|    uint8_t *end = data + data_len;
  234|  4.29k|    if (data == end)
  ------------------
  |  Branch (234:9): [True: 0, False: 4.29k]
  ------------------
  235|      0|        return EBML_ID_INVALID;
  ------------------
  |  |   68|      0|#define EBML_ID_INVALID 0xffffffff
  ------------------
  236|  4.29k|    int len = 1;
  237|  4.29k|    uint32_t id = *data++;
  238|  5.03k|    for (int len_mask = 0x80; !(id & len_mask); len_mask >>= 1) {
  ------------------
  |  Branch (238:31): [True: 750, False: 4.28k]
  ------------------
  239|    750|        len++;
  240|    750|        if (len > 4)
  ------------------
  |  Branch (240:13): [True: 10, False: 740]
  ------------------
  241|     10|            return EBML_ID_INVALID;
  ------------------
  |  |   68|     10|#define EBML_ID_INVALID 0xffffffff
  ------------------
  242|    750|    }
  243|  4.28k|    *length = len;
  244|  4.99k|    while (--len && data < end)
  ------------------
  |  Branch (244:12): [True: 710, False: 4.28k]
  |  Branch (244:21): [True: 710, False: 0]
  ------------------
  245|    710|        id = (id << 8) | *data++;
  246|  4.28k|    return id;
  247|  4.29k|}
ebml.c:ebml_parse_length:
  250|  4.28k|{
  251|  4.28k|    *length = -1;
  252|  4.28k|    uint8_t *end = data + data_len;
  253|  4.28k|    if (data == end)
  ------------------
  |  Branch (253:9): [True: 0, False: 4.28k]
  ------------------
  254|      0|        return -1;
  255|  4.28k|    uint64_t r = *data++;
  256|  4.28k|    int len = 1;
  257|  4.28k|    int len_mask;
  258|  4.64k|    for (len_mask = 0x80; !(r & len_mask); len_mask >>= 1) {
  ------------------
  |  Branch (258:27): [True: 368, False: 4.28k]
  ------------------
  259|    368|        len++;
  260|    368|        if (len > 8)
  ------------------
  |  Branch (260:13): [True: 0, False: 368]
  ------------------
  261|      0|            return -1;
  262|    368|    }
  263|  4.28k|    r &= len_mask - 1;
  264|       |
  265|  4.28k|    int num_allones = 0;
  266|  4.28k|    if (r == len_mask - 1)
  ------------------
  |  Branch (266:9): [True: 12, False: 4.26k]
  ------------------
  267|     12|        num_allones++;
  268|  4.64k|    for (int i = 1; i < len; i++) {
  ------------------
  |  Branch (268:21): [True: 368, False: 4.28k]
  ------------------
  269|    368|        if (data == end)
  ------------------
  |  Branch (269:13): [True: 0, False: 368]
  ------------------
  270|      0|            return -1;
  271|    368|        if (*data == 255)
  ------------------
  |  Branch (271:13): [True: 16, False: 352]
  ------------------
  272|     16|            num_allones++;
  273|    368|        r = (r << 8) | *data++;
  274|    368|    }
  275|       |    // According to Matroska specs this means "unknown length"
  276|       |    // Could be supported if there are any actual files using it
  277|  4.28k|    if (num_allones == len)
  ------------------
  |  Branch (277:9): [True: 8, False: 4.27k]
  ------------------
  278|      8|        return -1;
  279|  4.27k|    *length = len;
  280|  4.27k|    return r;
  281|  4.28k|}

demux_packet_unref_contents:
   41|   126k|{
   42|   126k|    if (dp->avpacket) {
  ------------------
  |  Branch (42:9): [True: 126k, False: 0]
  ------------------
   43|   126k|        mp_assert(!dp->is_cached);
  ------------------
  |  |   41|   126k|#define mp_assert assert
  ------------------
   44|   126k|        av_packet_free(&dp->avpacket);
   45|   126k|        dp->buffer = NULL;
   46|   126k|        dp->len = 0;
   47|   126k|        dp->is_wrapped_avframe = false;
   48|   126k|    }
   49|   126k|}
new_demux_packet_from_avpacket:
   84|  2.83M|{
   85|  2.83M|    if (avpkt->size > 1000000000)
  ------------------
  |  Branch (85:9): [True: 0, False: 2.83M]
  ------------------
   86|      0|        return NULL;
   87|  2.83M|    struct demux_packet *dp = packet_create(pool);
   88|  2.83M|    int r = -1;
   89|  2.83M|    if (avpkt->data) {
  ------------------
  |  Branch (89:9): [True: 2.83M, False: 18.4E]
  ------------------
   90|       |        // We hope that this function won't need/access AVPacket input padding,
   91|       |        // because otherwise new_demux_packet_from() wouldn't work.
   92|  2.83M|        r = av_packet_ref(dp->avpacket, avpkt);
   93|  18.4E|    } else {
   94|  18.4E|        r = av_new_packet(dp->avpacket, avpkt->size);
   95|  18.4E|    }
   96|  2.83M|    if (r < 0) {
  ------------------
  |  Branch (96:9): [True: 0, False: 2.83M]
  ------------------
   97|      0|        talloc_free(dp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
   98|      0|        return NULL;
   99|      0|    }
  100|  2.83M|    dp->buffer = dp->avpacket->data;
  101|  2.83M|    dp->len = dp->avpacket->size;
  102|  2.83M|    return dp;
  103|  2.83M|}
new_demux_packet_from_buf:
  108|  71.9k|{
  109|  71.9k|    if (!buf)
  ------------------
  |  Branch (109:9): [True: 71.9k, False: 0]
  ------------------
  110|  71.9k|        return NULL;
  111|      0|    if (buf->size > 1000000000)
  ------------------
  |  Branch (111:9): [True: 0, False: 0]
  ------------------
  112|      0|        return NULL;
  113|       |
  114|      0|    struct demux_packet *dp = packet_create(pool);
  115|      0|    dp->avpacket->buf = av_buffer_ref(buf);
  116|      0|    if (!dp->avpacket->buf) {
  ------------------
  |  Branch (116:9): [True: 0, False: 0]
  ------------------
  117|      0|        talloc_free(dp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  118|      0|        return NULL;
  119|      0|    }
  120|      0|    dp->avpacket->data = dp->buffer = buf->data;
  121|      0|    dp->avpacket->size = dp->len = buf->size;
  122|      0|    return dp;
  123|      0|}
new_demux_packet:
  136|    223|{
  137|    223|    if (len > INT_MAX)
  ------------------
  |  Branch (137:9): [True: 0, False: 223]
  ------------------
  138|      0|        return NULL;
  139|       |
  140|    223|    struct demux_packet *dp = packet_create(pool);
  141|    223|    int r = av_new_packet(dp->avpacket, len);
  142|    223|    if (r < 0) {
  ------------------
  |  Branch (142:9): [True: 0, False: 223]
  ------------------
  143|      0|        talloc_free(dp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  144|      0|        return NULL;
  145|      0|    }
  146|    223|    dp->buffer = dp->avpacket->data;
  147|    223|    dp->len = len;
  148|    223|    return dp;
  149|    223|}
free_demux_packet:
  161|   126k|{
  162|   126k|    talloc_free(dp);
  ------------------
  |  |   47|   126k|#define talloc_free                     ta_free
  ------------------
  163|   126k|}
demux_packet_copy_attribs:
  166|  1.42M|{
  167|  1.42M|    dst->pts = src->pts;
  168|  1.42M|    dst->dts = src->dts;
  169|  1.42M|    dst->duration = src->duration;
  170|  1.42M|    dst->pos = src->pos;
  171|  1.42M|    dst->is_wrapped_avframe = src->is_wrapped_avframe;
  172|  1.42M|    dst->segmented = src->segmented;
  173|  1.42M|    dst->start = src->start;
  174|  1.42M|    dst->end = src->end;
  175|  1.42M|    dst->codec = src->codec;
  176|  1.42M|    dst->back_restart = src->back_restart;
  177|  1.42M|    dst->back_preroll = src->back_preroll;
  178|  1.42M|    dst->keyframe = src->keyframe;
  179|  1.42M|    dst->stream = src->stream;
  180|  1.42M|}
demux_copy_packet:
  183|  1.42M|{
  184|  1.42M|    struct demux_packet *new = NULL;
  185|  1.42M|    if (dp->avpacket) {
  ------------------
  |  Branch (185:9): [True: 1.42M, False: 0]
  ------------------
  186|  1.42M|        new = new_demux_packet_from_avpacket(pool, dp->avpacket);
  187|  1.42M|    } else {
  188|       |        // Some packets might be not created by new_demux_packet*().
  189|      0|        new = new_demux_packet_from(pool, dp->buffer, dp->len);
  190|      0|    }
  191|  1.42M|    if (!new)
  ------------------
  |  Branch (191:9): [True: 0, False: 1.42M]
  ------------------
  192|      0|        return NULL;
  193|  1.42M|    demux_packet_copy_attribs(new, dp);
  194|  1.42M|    return new;
  195|  1.42M|}
demux_packet_estimate_total_size:
  208|  1.42M|{
  209|  1.42M|    size_t size = ROUND_ALLOC(sizeof(struct demux_packet));
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  210|  1.42M|    size += 8 * sizeof(void *); // ta  overhead
  211|  1.42M|    size += 10 * sizeof(void *); // additional estimate for ta_ext_header
  212|  1.42M|    if (dp->avpacket) {
  ------------------
  |  Branch (212:9): [True: 1.42M, False: 0]
  ------------------
  213|  1.42M|        mp_assert(!dp->is_cached);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
  214|  1.42M|        size += ROUND_ALLOC(dp->len);
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  215|  1.42M|        if (dp->is_wrapped_avframe) {
  ------------------
  |  Branch (215:13): [True: 0, False: 1.42M]
  ------------------
  216|      0|            mp_require(dp->buffer);
  ------------------
  |  |   42|      0|#define mp_require assert
  ------------------
  217|       |
  218|      0|            const AVFrame *frame = (AVFrame *)dp->buffer;
  219|      0|            if (frame->hw_frames_ctx) {
  ------------------
  |  Branch (219:17): [True: 0, False: 0]
  ------------------
  220|      0|                const AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data;
  221|      0|                int r = av_image_get_buffer_size(hwctx->sw_format, hwctx->width, hwctx->height, 16);
  222|      0|                mp_require(r >= 0);
  ------------------
  |  |   42|      0|#define mp_require assert
  ------------------
  223|      0|                size += ROUND_ALLOC(r);
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  224|      0|            }
  225|      0|            for (int i = 0; i < MP_ARRAY_SIZE(frame->buf) && frame->buf[i]; ++i)
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (225:29): [True: 0, False: 0]
  |  Branch (225:62): [True: 0, False: 0]
  ------------------
  226|      0|                size += ROUND_ALLOC(frame->buf[i]->size);
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  227|       |
  228|      0|            size += ROUND_ALLOC(frame->nb_extended_buf * sizeof(frame->extended_buf[0]));
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  229|      0|            for (int i = 0; i < frame->nb_extended_buf; ++i) {
  ------------------
  |  Branch (229:29): [True: 0, False: 0]
  ------------------
  230|      0|                size += ROUND_ALLOC(sizeof(*frame->extended_buf[i]));
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  231|      0|                size += ROUND_ALLOC(frame->extended_buf[i]->size);
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  232|      0|            }
  233|       |
  234|      0|            size += ROUND_ALLOC(frame->nb_side_data * sizeof(frame->side_data[0]));
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  235|      0|            for (int i = 0; i < frame->nb_side_data; ++i) {
  ------------------
  |  Branch (235:29): [True: 0, False: 0]
  ------------------
  236|      0|                size += ROUND_ALLOC(sizeof(*frame->side_data[i]));
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  237|      0|                size += ROUND_ALLOC(frame->side_data[i]->size);
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|      0|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  238|      0|            }
  239|      0|        }
  240|  1.42M|        size += ROUND_ALLOC(sizeof(AVPacket));
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  241|  1.42M|        size += 8 * sizeof(void *); // ta  overhead
  242|  1.42M|        size += ROUND_ALLOC(sizeof(AVBufferRef));
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  243|  1.42M|        size += ROUND_ALLOC(64); // upper bound estimate on sizeof(AVBuffer)
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  244|  1.42M|        size += ROUND_ALLOC(dp->avpacket->side_data_elems *
  ------------------
  |  |  197|  1.42M|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  245|  1.42M|                            sizeof(dp->avpacket->side_data[0]));
  246|  1.42M|        for (int n = 0; n < dp->avpacket->side_data_elems; n++)
  ------------------
  |  Branch (246:25): [True: 0, False: 1.42M]
  ------------------
  247|  1.42M|            size += ROUND_ALLOC(dp->avpacket->side_data[n].size);
  ------------------
  |  |  197|      0|#define ROUND_ALLOC(s) MP_ALIGN_UP((s), 16)
  |  |  ------------------
  |  |  |  |   52|  1.42M|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  |  |  ------------------
  ------------------
  248|  1.42M|    }
  249|  1.42M|    return size;
  250|  1.42M|}
packet.c:packet_create:
   58|  2.83M|{
   59|  2.83M|    struct demux_packet *dp = pool ? demux_packet_pool_pop(pool) : NULL;
  ------------------
  |  Branch (59:31): [True: 2.83M, False: 18.4E]
  ------------------
   60|  2.83M|    struct AVPacket *avpkt = dp ? dp->avpacket : NULL;
  ------------------
  |  Branch (60:30): [True: 2.71M, False: 126k]
  ------------------
   61|  2.83M|    if (!dp)
  ------------------
  |  Branch (61:9): [True: 126k, False: 2.71M]
  ------------------
   62|   126k|        dp = talloc(NULL, struct demux_packet);
  ------------------
  |  |   26|   126k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|   126k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   126k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   63|  2.83M|    talloc_set_destructor(dp, packet_destroy);
  ------------------
  |  |   41|  2.83M|#define talloc_set_destructor           ta_set_destructor
  ------------------
   64|  2.83M|    *dp = (struct demux_packet) {
   65|  2.83M|        .pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  2.83M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   66|  2.83M|        .dts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  2.83M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   67|  2.83M|        .duration = -1,
   68|  2.83M|        .pos = -1,
   69|  2.83M|        .start = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  2.83M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   70|  2.83M|        .end = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  2.83M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   71|  2.83M|        .stream = -1,
   72|  2.83M|        .animated = -1,
   73|  2.83M|    };
   74|  2.83M|    dp->avpacket = avpkt ? avpkt : av_packet_alloc();
  ------------------
  |  Branch (74:20): [True: 2.71M, False: 126k]
  ------------------
   75|  2.83M|    MP_HANDLE_OOM(dp->avpacket);
  ------------------
  |  |  176|  2.83M|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  2.83M|        void *oom_p_ = (x);     \
  |  |  178|  2.83M|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 2.83M]
  |  |  ------------------
  |  |  179|  2.83M|            abort();            \
  |  |  180|  2.83M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   76|  2.83M|    return dp;
   77|  2.83M|}
packet.c:packet_destroy:
   52|   126k|{
   53|   126k|    struct demux_packet *dp = ptr;
   54|   126k|    demux_packet_unref_contents(dp);
   55|   126k|}

demux_packet_pool_init:
   50|  5.81k|{
   51|  5.81k|    struct demux_packet_pool *pool = talloc(global, struct demux_packet_pool);
  ------------------
  |  |   26|  5.81k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   52|  5.81k|    talloc_set_destructor(pool, uninit);
  ------------------
  |  |   41|  5.81k|#define talloc_set_destructor           ta_set_destructor
  ------------------
   53|  5.81k|    mp_mutex_init(&pool->lock);
   54|  5.81k|    pool->packets = NULL;
   55|       |
   56|  5.81k|    mp_assert(!global->packet_pool);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   57|  5.81k|    global->packet_pool = pool;
   58|  5.81k|}
demux_packet_pool_get:
   61|   611k|{
   62|       |    // Currently all clients use the same packet pool. There is no additional
   63|       |    // state for each client, may be extended in the future.
   64|   611k|    return global->packet_pool;
   65|   611k|}
demux_packet_pool_clear:
   68|  5.81k|{
   69|  5.81k|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   70|  5.81k|    struct demux_packet *dp = pool->packets;
   71|  5.81k|    pool->packets = NULL;
   72|  5.81k|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   73|  5.81k|    free_demux_packets(dp);
   74|  5.81k|}
demux_packet_pool_push:
   78|  2.84M|{
   79|  2.84M|    if (!dp)
  ------------------
  |  Branch (79:9): [True: 8.71k, False: 2.83M]
  ------------------
   80|  8.71k|        return;
   81|  2.83M|    dp->next = NULL;
   82|  2.83M|    demux_packet_pool_prepend(pool, dp, dp);
   83|  2.83M|}
demux_packet_pool_prepend:
   87|  3.07M|{
   88|  3.07M|    if (!head)
  ------------------
  |  Branch (88:9): [True: 238k, False: 2.83M]
  ------------------
   89|   238k|        return;
   90|  2.83M|    mp_assert(tail);
  ------------------
  |  |   41|  2.83M|#define mp_assert assert
  ------------------
   91|  2.83M|    mp_assert(head != tail ? !!head->next : !head->next);
  ------------------
  |  |   41|  2.83M|#define mp_assert assert
  ------------------
   92|       |
   93|  2.83M|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  2.83M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   94|  2.83M|    tail->next = pool->packets;
   95|  2.83M|    pool->packets = head;
   96|       |#if HAVE_DISABLE_PACKET_POOL
   97|       |    struct demux_packet *dp = pool->packets;
   98|       |    pool->packets = NULL;
   99|       |#endif
  100|  2.83M|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  2.83M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  101|       |
  102|       |#if HAVE_DISABLE_PACKET_POOL
  103|       |    free_demux_packets(dp);
  104|       |#endif
  105|  2.83M|}
demux_packet_pool_pop:
  108|  2.83M|{
  109|  2.83M|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  2.83M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  110|  2.83M|    struct demux_packet *dp = pool->packets;
  111|  2.83M|    if (dp) {
  ------------------
  |  Branch (111:9): [True: 2.71M, False: 126k]
  ------------------
  112|  2.71M|        pool->packets = dp->next;
  113|  2.71M|        dp->next = NULL;
  114|  2.71M|    }
  115|  2.83M|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  2.83M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  116|       |
  117|       |    // Clear the packet from possible external references. This is done in the
  118|       |    // pop function instead of prepend to distribute the load of clearing packets.
  119|       |    // packet_create() is called at a reasonable rate, so it's fine to clear
  120|       |    // a single packet at a time. This avoids the need to clear potentially
  121|       |    // hundreds of thousands of packets at once when file playback is stopped,
  122|       |    // which would require a significant amount of time to iterate over all packets.
  123|  2.83M|    if (dp) {
  ------------------
  |  Branch (123:9): [True: 2.71M, False: 126k]
  ------------------
  124|  2.71M|        if (dp->avpacket)
  ------------------
  |  Branch (124:13): [True: 2.71M, False: 9]
  ------------------
  125|  2.71M|            av_packet_unref(dp->avpacket);
  126|  2.71M|        ta_free_children(dp);
  127|  2.71M|    }
  128|       |
  129|  2.83M|    return dp;
  130|  2.83M|}
packet_pool.c:uninit:
   34|  5.81k|{
   35|  5.81k|    struct demux_packet_pool *pool = p;
   36|  5.81k|    demux_packet_pool_clear(pool);
   37|  5.81k|    mp_mutex_destroy(&pool->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
   38|  5.81k|}
packet_pool.c:free_demux_packets:
   41|  5.81k|{
   42|   132k|    while (dp) {
  ------------------
  |  Branch (42:12): [True: 126k, False: 5.81k]
  ------------------
   43|   126k|        struct demux_packet *next = dp->next;
   44|   126k|        free_demux_packet(dp);
   45|   126k|        dp = next;
   46|   126k|    }
   47|  5.81k|}

timeline_load:
    9|  21.5k|{
   10|  21.5k|    if (!demuxer->desc->load_timeline)
  ------------------
  |  Branch (10:9): [True: 20.9k, False: 573]
  ------------------
   11|  20.9k|        return NULL;
   12|       |
   13|    573|    struct timeline *tl = talloc_ptrtype(NULL, tl);
  ------------------
  |  |   34|    573|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|    573|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    573|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   14|    573|    *tl = (struct timeline){
   15|    573|        .global = global,
   16|    573|        .log = log,
   17|    573|        .cancel = demuxer->cancel,
   18|    573|        .demuxer = demuxer,
   19|    573|        .format = "unknown",
   20|    573|        .stream_origin = demuxer->stream_origin,
   21|    573|    };
   22|       |
   23|    573|    demuxer->desc->load_timeline(tl);
   24|       |
   25|    573|    if (tl->num_pars)
  ------------------
  |  Branch (25:9): [True: 436, False: 137]
  ------------------
   26|    436|        return tl;
   27|    137|    timeline_destroy(tl);
   28|    137|    return NULL;
   29|    573|}
timeline_destroy:
   32|    573|{
   33|    573|    if (!tl)
  ------------------
  |  Branch (33:9): [True: 0, False: 573]
  ------------------
   34|      0|        return;
   35|  16.5k|    for (int n = 0; n < tl->num_sources; n++) {
  ------------------
  |  Branch (35:21): [True: 16.0k, False: 573]
  ------------------
   36|  16.0k|        struct demuxer *d = tl->sources[n];
   37|  16.0k|        if (d != tl->demuxer)
  ------------------
  |  Branch (37:13): [True: 16.0k, False: 3]
  ------------------
   38|  16.0k|            demux_free(d);
   39|  16.0k|    }
   40|    573|    talloc_free(tl);
  ------------------
  |  |   47|    573|#define talloc_free                     ta_free
  ------------------
   41|    573|}

mp_async_queue_create:
   72|  1.34k|{
   73|  1.34k|    struct mp_async_queue *r = talloc_zero(NULL, struct mp_async_queue);
  ------------------
  |  |   27|  1.34k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.34k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.34k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   74|  1.34k|    r->q = talloc_zero(NULL, struct async_queue);
  ------------------
  |  |   27|  1.34k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.34k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.34k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   75|  1.34k|    *r->q = (struct async_queue){
   76|  1.34k|        .refcount = 1,
   77|  1.34k|    };
   78|  1.34k|    mp_mutex_init(&r->q->lock);
   79|  1.34k|    talloc_set_destructor(r, on_free_queue);
  ------------------
  |  |   41|  1.34k|#define talloc_set_destructor           ta_set_destructor
  ------------------
   80|  1.34k|    mp_async_queue_set_config(r, (struct mp_async_queue_config){0});
   81|  1.34k|    return r;
   82|  1.34k|}
mp_async_queue_set_config:
  135|  2.69k|{
  136|  2.69k|    struct async_queue *q = queue->q;
  137|       |
  138|  2.69k|    cfg.max_bytes = MPCLAMP(cfg.max_bytes, 1, (size_t)-1 / 2);
  ------------------
  |  |   45|  2.69k|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 1.34k, False: 1.34k]
  |  |  |  Branch (45:56): [True: 0, False: 1.34k]
  |  |  ------------------
  ------------------
  139|       |
  140|  2.69k|    mp_assert(cfg.sample_unit == AQUEUE_UNIT_FRAME ||
  ------------------
  |  |   41|  2.69k|#define mp_assert assert
  ------------------
  141|  2.69k|           cfg.sample_unit == AQUEUE_UNIT_SAMPLES);
  142|       |
  143|  2.69k|    cfg.max_samples = MPMAX(cfg.max_samples, 1);
  ------------------
  |  |   43|  2.69k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 1.34k, False: 1.34k]
  |  |  ------------------
  ------------------
  144|       |
  145|  2.69k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  2.69k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  146|  2.69k|    bool recompute = q->cfg.sample_unit != cfg.sample_unit;
  147|  2.69k|    q->cfg = cfg;
  148|  2.69k|    if (recompute)
  ------------------
  |  Branch (148:9): [True: 1.34k, False: 1.34k]
  ------------------
  149|  1.34k|        recompute_sizes(q);
  150|  2.69k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  2.69k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  151|  2.69k|}
mp_async_queue_reset:
  154|  1.13k|{
  155|  1.13k|    reset_queue(queue->q);
  156|  1.13k|}
mp_async_queue_is_full:
  168|  23.7k|{
  169|  23.7k|    struct async_queue *q = queue->q;
  170|  23.7k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  23.7k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  171|  23.7k|    bool res = is_full(q);
  172|  23.7k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  23.7k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  173|  23.7k|    return res;
  174|  23.7k|}
mp_async_queue_resume_reading:
  191|  2.48k|{
  192|  2.48k|    struct async_queue *q = queue->q;
  193|       |
  194|  2.48k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  2.48k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  195|  2.48k|    if (!q->active || !q->reading) {
  ------------------
  |  Branch (195:9): [True: 2.48k, False: 0]
  |  Branch (195:23): [True: 0, False: 0]
  ------------------
  196|  2.48k|        q->active = true;
  197|  2.48k|        q->reading = true;
  198|       |        // Possibly start producer/consumer.
  199|  7.45k|        for (int n = 0; n < 2; n++) {
  ------------------
  |  Branch (199:25): [True: 4.97k, False: 2.48k]
  ------------------
  200|  4.97k|            if (q->conn[n])
  ------------------
  |  Branch (200:17): [True: 2.80k, False: 2.16k]
  ------------------
  201|  2.80k|                mp_filter_wakeup(q->conn[n]);
  202|  4.97k|        }
  203|  2.48k|    }
  204|  2.48k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  2.48k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  205|  2.48k|}
mp_async_queue_get_samples:
  208|  5.98k|{
  209|  5.98k|    struct async_queue *q = queue->q;
  210|  5.98k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  5.98k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  211|  5.98k|    int64_t res = q->samples_size;
  212|  5.98k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  5.98k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  213|  5.98k|    return res;
  214|  5.98k|}
mp_async_queue_get_frames:
  217|  1.00k|{
  218|  1.00k|    struct async_queue *q = queue->q;
  219|  1.00k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  1.00k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  220|  1.00k|    int res = q->num_frames;
  221|  1.00k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  1.00k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  222|  1.00k|    return res;
  223|  1.00k|}
mp_async_queue_set_notifier:
  338|  1.36k|{
  339|  1.36k|    mp_assert(mp_filter_get_info(f) == &info_in);
  ------------------
  |  |   41|  1.36k|#define mp_assert assert
  ------------------
  340|  1.36k|    struct priv *p = f->priv;
  341|  1.36k|    if (p->notify != notify) {
  ------------------
  |  Branch (341:9): [True: 1.36k, False: 0]
  ------------------
  342|  1.36k|        p->notify = notify;
  343|  1.36k|        if (notify)
  ------------------
  |  Branch (343:13): [True: 1.36k, False: 0]
  ------------------
  344|  1.36k|            mp_filter_wakeup(notify);
  345|  1.36k|    }
  346|  1.36k|}
mp_async_queue_create_filter:
  351|  2.70k|{
  352|  2.70k|    bool is_in = dir == MP_PIN_IN;
  353|  2.70k|    mp_assert(queue);
  ------------------
  |  |   41|  2.70k|#define mp_assert assert
  ------------------
  354|       |
  355|  2.70k|    struct mp_filter *f = mp_filter_create(parent, is_in ? &info_in : &info_out);
  ------------------
  |  Branch (355:52): [True: 1.36k, False: 1.34k]
  ------------------
  356|  2.70k|    if (!f)
  ------------------
  |  Branch (356:9): [True: 0, False: 2.70k]
  ------------------
  357|      0|        return NULL;
  358|       |
  359|  2.70k|    struct priv *p = f->priv;
  360|       |
  361|  2.70k|    struct async_queue *q = queue->q;
  362|       |
  363|  2.70k|    mp_filter_add_pin(f, dir, is_in ? "in" : "out");
  ------------------
  |  Branch (363:31): [True: 1.36k, False: 1.34k]
  ------------------
  364|       |
  365|  2.70k|    atomic_fetch_add(&q->refcount, 1);
  366|  2.70k|    p->q = q;
  367|       |
  368|  2.70k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  2.70k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  369|  2.70k|    int slot = is_in ? 0 : 1;
  ------------------
  |  Branch (369:16): [True: 1.36k, False: 1.34k]
  ------------------
  370|  2.70k|    mp_assert(!q->conn[slot]); // fails if already connected on this end
  ------------------
  |  |   41|  2.70k|#define mp_assert assert
  ------------------
  371|  2.70k|    q->conn[slot] = f;
  372|  2.70k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  2.70k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  373|       |
  374|  2.70k|    return f;
  375|  2.70k|}
f_async_queue.c:on_free_queue:
   66|  1.34k|{
   67|  1.34k|    struct mp_async_queue *q = p;
   68|  1.34k|    unref_queue(q->q);
   69|  1.34k|}
f_async_queue.c:unref_queue:
   53|  4.05k|{
   54|  4.05k|    if (!q)
  ------------------
  |  Branch (54:9): [True: 0, False: 4.05k]
  ------------------
   55|      0|        return;
   56|  4.05k|    int count = atomic_fetch_add(&q->refcount, -1) - 1;
   57|  4.05k|    mp_assert(count >= 0);
  ------------------
  |  |   41|  4.05k|#define mp_assert assert
  ------------------
   58|  4.05k|    if (count == 0) {
  ------------------
  |  Branch (58:9): [True: 1.34k, False: 2.70k]
  ------------------
   59|  1.34k|        reset_queue(q);
   60|  1.34k|        mp_mutex_destroy(&q->lock);
  ------------------
  |  |  130|  1.34k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
   61|  1.34k|        talloc_free(q);
  ------------------
  |  |   47|  1.34k|#define talloc_free                     ta_free
  ------------------
   62|  1.34k|    }
   63|  4.05k|}
f_async_queue.c:recompute_sizes:
  125|  1.34k|{
  126|  1.34k|    q->eof_count = 0;
  127|  1.34k|    q->samples_size = 0;
  128|  1.34k|    q->byte_size = 0;
  129|  1.34k|    for (int n = 0; n < q->num_frames; n++)
  ------------------
  |  Branch (129:21): [True: 0, False: 1.34k]
  ------------------
  130|      0|        account_frame(q, q->frames[n], 1);
  131|  1.34k|}
f_async_queue.c:account_frame:
  114|   746k|{
  115|   746k|    mp_assert(dir == 1 || dir == -1);
  ------------------
  |  |   41|   746k|#define mp_assert assert
  ------------------
  116|       |
  117|   746k|    q->samples_size += dir * frame_get_samples(q, frame);
  118|   746k|    q->byte_size += dir * mp_frame_approx_size(frame);
  119|       |
  120|   746k|    if (frame.type == MP_FRAME_EOF)
  ------------------
  |  Branch (120:9): [True: 1.34k, False: 744k]
  ------------------
  121|  1.34k|        q->eof_count += dir;
  122|   746k|}
f_async_queue.c:frame_get_samples:
   85|   746k|{
   86|   746k|    int64_t res = 1;
   87|   746k|    if (frame.type == MP_FRAME_AUDIO && q->cfg.sample_unit == AQUEUE_UNIT_SAMPLES) {
  ------------------
  |  Branch (87:9): [True: 744k, False: 1.34k]
  |  Branch (87:41): [True: 744k, False: 0]
  ------------------
   88|   744k|        struct mp_aframe *aframe = frame.data;
   89|   744k|        res = mp_aframe_get_size(aframe);
   90|   744k|    }
   91|   746k|    if (mp_frame_is_signaling(frame))
  ------------------
  |  Branch (91:9): [True: 1.34k, False: 744k]
  ------------------
   92|  1.34k|        return 0;
   93|   744k|    return res;
   94|   746k|}
f_async_queue.c:reset_queue:
   36|  2.48k|{
   37|  2.48k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  2.48k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   38|  2.48k|    q->active = q->reading = false;
   39|  4.88k|    for (int n = 0; n < q->num_frames; n++)
  ------------------
  |  Branch (39:21): [True: 2.39k, False: 2.48k]
  ------------------
   40|  2.39k|        mp_frame_unref(&q->frames[n]);
   41|  2.48k|    q->num_frames = 0;
   42|  2.48k|    q->eof_count = 0;
   43|  2.48k|    q->samples_size = 0;
   44|  2.48k|    q->byte_size = 0;
   45|  7.45k|    for (int n = 0; n < 2; n++) {
  ------------------
  |  Branch (45:21): [True: 4.97k, False: 2.48k]
  ------------------
   46|  4.97k|        if (q->conn[n])
  ------------------
  |  Branch (46:13): [True: 1.45k, False: 3.51k]
  ------------------
   47|  1.45k|            mp_filter_wakeup(q->conn[n]);
   48|  4.97k|    }
   49|  2.48k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  2.48k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   50|  2.48k|}
f_async_queue.c:is_full:
   97|   775k|{
   98|   775k|    if (q->samples_size >= q->cfg.max_samples || q->byte_size >= q->cfg.max_bytes)
  ------------------
  |  Branch (98:9): [True: 1.63k, False: 774k]
  |  Branch (98:50): [True: 0, False: 774k]
  ------------------
   99|  1.63k|        return true;
  100|   774k|    if (q->num_frames >= 2 && q->cfg.max_duration > 0) {
  ------------------
  |  Branch (100:9): [True: 50.1k, False: 724k]
  |  Branch (100:31): [True: 0, False: 50.1k]
  ------------------
  101|      0|        double pts1 = mp_frame_get_pts(q->frames[q->num_frames - 1]);
  102|      0|        double pts2 = mp_frame_get_pts(q->frames[0]);
  103|      0|        if (pts1 != MP_NOPTS_VALUE && pts2 != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                      if (pts1 != MP_NOPTS_VALUE && pts2 != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (103:13): [True: 0, False: 0]
  |  Branch (103:39): [True: 0, False: 0]
  ------------------
  104|      0|            pts2 - pts1 >= q->cfg.max_duration)
  ------------------
  |  Branch (104:13): [True: 0, False: 0]
  ------------------
  105|      0|            return true;
  106|      0|    }
  107|   774k|    return false;
  108|   774k|}
f_async_queue.c:destroy:
  231|  2.70k|{
  232|  2.70k|    struct priv *p = f->priv;
  233|  2.70k|    struct async_queue *q = p->q;
  234|       |
  235|  2.70k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|  2.70k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  236|  8.12k|    for (int n = 0; n < 2; n++) {
  ------------------
  |  Branch (236:21): [True: 5.41k, False: 2.70k]
  ------------------
  237|  5.41k|        if (q->conn[n] == f)
  ------------------
  |  Branch (237:13): [True: 2.70k, False: 2.70k]
  ------------------
  238|  2.70k|            q->conn[n] = NULL;
  239|  5.41k|    }
  240|  2.70k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|  2.70k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  241|       |
  242|  2.70k|    unref_queue(q);
  243|  2.70k|}
f_async_queue.c:process_in:
  246|   377k|{
  247|   377k|    struct priv *p = f->priv;
  248|   377k|    struct async_queue *q = p->q;
  249|   377k|    mp_assert(q->conn[0] == f);
  ------------------
  |  |   41|   377k|#define mp_assert assert
  ------------------
  250|       |
  251|   377k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|   377k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  252|   377k|    if (!q->reading) {
  ------------------
  |  Branch (252:9): [True: 0, False: 377k]
  ------------------
  253|       |        // mp_async_queue_reset()/reset_queue() is usually called asynchronously,
  254|       |        // so we might have requested a frame earlier, and now can't use it.
  255|       |        // Discard it; the expectation is that this is a benign logical race
  256|       |        // condition, and the filter graph will be reset anyway.
  257|      0|        if (mp_pin_out_has_data(f->ppins[0])) {
  ------------------
  |  Branch (257:13): [True: 0, False: 0]
  ------------------
  258|      0|            struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  259|      0|            mp_frame_unref(&frame);
  260|      0|            MP_DBG(f, "discarding frame due to async reset\n");
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  261|      0|        }
  262|   377k|    } else if (!is_full(q) && mp_pin_out_request_data(f->ppins[0])) {
  ------------------
  |  Branch (262:16): [True: 377k, False: 62]
  |  Branch (262:31): [True: 374k, False: 3.51k]
  ------------------
  263|   374k|        struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  264|   374k|        account_frame(q, frame, 1);
  265|   374k|        MP_TARRAY_INSERT_AT(q, q->frames, q->num_frames, 0, frame);
  ------------------
  |  |  115|   374k|    do {                                            \
  |  |  116|   374k|        size_t at_ = (at);                          \
  |  |  117|   374k|        assert(at_ <= (idxvar));                    \
  |  |  118|   374k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|   374k|    do {                                            \
  |  |  |  |   97|   374k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|   374k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|   374k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|   374k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.65k, False: 371k]
  |  |  |  |  ------------------
  |  |  |  |   99|   374k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.65k|    do {                                                        \
  |  |  |  |  |  |   89|  2.65k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.65k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.65k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.65k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.65k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.65k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.65k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|   374k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|   374k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|   374k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|   374k|        (idxvar)++;                                 \
  |  |  122|   374k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|   374k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  266|       |        // Notify reader that we have new frames.
  267|   374k|        if (q->conn[1])
  ------------------
  |  Branch (267:13): [True: 374k, False: 0]
  ------------------
  268|   374k|            mp_filter_wakeup(q->conn[1]);
  269|   374k|        bool full = is_full(q);
  270|   374k|        if (!full)
  ------------------
  |  Branch (270:13): [True: 373k, False: 735]
  ------------------
  271|   373k|            mp_pin_out_request_data_next(f->ppins[0]);
  272|   374k|        if (p->notify && full)
  ------------------
  |  Branch (272:13): [True: 374k, False: 0]
  |  Branch (272:26): [True: 735, False: 373k]
  ------------------
  273|    735|            mp_filter_wakeup(p->notify);
  274|   374k|    }
  275|   377k|    if (p->notify && !q->num_frames)
  ------------------
  |  Branch (275:9): [True: 377k, False: 0]
  |  Branch (275:22): [True: 3.09k, False: 374k]
  ------------------
  276|  3.09k|        mp_filter_wakeup(p->notify);
  277|   377k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|   377k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  278|   377k|}
f_async_queue.c:process_out:
  281|   718k|{
  282|   718k|    struct priv *p = f->priv;
  283|   718k|    struct async_queue *q = p->q;
  284|   718k|    mp_assert(q->conn[1] == f);
  ------------------
  |  |   41|   718k|#define mp_assert assert
  ------------------
  285|       |
  286|   718k|    if (!mp_pin_in_needs_data(f->ppins[0]))
  ------------------
  |  Branch (286:9): [True: 1.96k, False: 716k]
  ------------------
  287|  1.96k|        return;
  288|       |
  289|   716k|    mp_mutex_lock(&q->lock);
  ------------------
  |  |  131|   716k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  290|   716k|    if (q->active && !q->reading) {
  ------------------
  |  Branch (290:9): [True: 716k, False: 0]
  |  Branch (290:22): [True: 0, False: 716k]
  ------------------
  291|      0|        q->reading = true;
  292|      0|        mp_filter_wakeup(q->conn[0]);
  293|      0|    }
  294|   716k|    if (q->active && q->num_frames) {
  ------------------
  |  Branch (294:9): [True: 716k, False: 0]
  |  Branch (294:22): [True: 371k, False: 344k]
  ------------------
  295|   371k|        struct mp_frame frame = q->frames[q->num_frames - 1];
  296|   371k|        q->num_frames -= 1;
  297|   371k|        account_frame(q, frame, -1);
  298|   371k|        mp_assert(q->samples_size >= 0);
  ------------------
  |  |   41|   371k|#define mp_assert assert
  ------------------
  299|   371k|        mp_pin_in_write(f->ppins[0], frame);
  300|       |        // Notify writer that we need new frames.
  301|   371k|        if (q->conn[0])
  ------------------
  |  Branch (301:13): [True: 368k, False: 3.21k]
  ------------------
  302|   368k|            mp_filter_wakeup(q->conn[0]);
  303|   371k|    }
  304|   716k|    mp_mutex_unlock(&q->lock);
  ------------------
  |  |  133|   716k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  305|   716k|}

mp_deint_create:
  195|  2.93k|{
  196|  2.93k|    struct mp_filter *f = mp_filter_create(parent, &deint_filter);
  197|  2.93k|    if (!f)
  ------------------
  |  Branch (197:9): [True: 0, False: 2.93k]
  ------------------
  198|      0|        return NULL;
  199|       |
  200|  2.93k|    struct deint_priv *p = f->priv;
  201|       |
  202|  2.93k|    p->sub.in = mp_filter_add_pin(f, MP_PIN_IN, "in");
  203|  2.93k|    p->sub.out = mp_filter_add_pin(f, MP_PIN_OUT, "out");
  204|       |
  205|  2.93k|    p->opts = m_config_cache_alloc(f, f->global, &filter_conf);
  206|       |
  207|  2.93k|    return f;
  208|  2.93k|}
mp_autorotate_create:
  321|  2.93k|{
  322|  2.93k|    struct mp_filter *f = mp_filter_create(parent, &rotate_filter);
  323|  2.93k|    if (!f)
  ------------------
  |  Branch (323:9): [True: 0, False: 2.93k]
  ------------------
  324|      0|        return NULL;
  325|       |
  326|  2.93k|    struct rotate_priv *p = f->priv;
  327|  2.93k|    p->prev_rotate = -1;
  328|       |
  329|  2.93k|    p->sub.in = mp_filter_add_pin(f, MP_PIN_IN, "in");
  330|  2.93k|    p->sub.out = mp_filter_add_pin(f, MP_PIN_OUT, "out");
  331|       |
  332|  2.93k|    return f;
  333|  2.93k|}
mp_autovflip_create:
  442|  2.93k|{
  443|  2.93k|    struct mp_filter *f = mp_filter_create(parent, &vflip_filter);
  444|  2.93k|    if (!f)
  ------------------
  |  Branch (444:9): [True: 0, False: 2.93k]
  ------------------
  445|      0|        return NULL;
  446|       |
  447|  2.93k|    struct vflip_priv *p = f->priv;
  448|  2.93k|    p->prev_vflip = -1;
  449|       |
  450|  2.93k|    p->sub.in = mp_filter_add_pin(f, MP_PIN_IN, "in");
  451|  2.93k|    p->sub.out = mp_filter_add_pin(f, MP_PIN_OUT, "out");
  452|       |
  453|  2.93k|    return f;
  454|  2.93k|}
mp_autoaspeed_create:
  565|  1.95k|{
  566|  1.95k|    struct mp_filter *f = mp_filter_create(parent, &aspeed_filter);
  567|  1.95k|    if (!f)
  ------------------
  |  Branch (567:9): [True: 0, False: 1.95k]
  ------------------
  568|      0|        return NULL;
  569|       |
  570|  1.95k|    struct aspeed_priv *p = f->priv;
  571|  1.95k|    p->cur_speed = 1.0;
  572|  1.95k|    p->cur_speed_drop = 1.0;
  573|       |
  574|  1.95k|    p->sub.in = mp_filter_add_pin(f, MP_PIN_IN, "in");
  575|  1.95k|    p->sub.out = mp_filter_add_pin(f, MP_PIN_OUT, "out");
  576|       |
  577|  1.95k|    return f;
  578|  1.95k|}
f_auto_filters.c:deint_destroy:
  161|  2.93k|{
  162|  2.93k|    struct deint_priv *p = f->priv;
  163|       |
  164|  2.93k|    mp_subfilter_reset(&p->sub);
  165|  2.93k|    TA_FREEP(&p->sub.filter);
  ------------------
  |  |   81|  2.93k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  2.93k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  166|  2.93k|}
f_auto_filters.c:deint_process:
   30|   151k|{
   31|   151k|    struct deint_priv *p = f->priv;
   32|       |
   33|   151k|    if (!mp_subfilter_read(&p->sub))
  ------------------
  |  Branch (33:9): [True: 77.4k, False: 74.0k]
  ------------------
   34|  77.4k|        return;
   35|       |
   36|  74.0k|    struct mp_frame frame = p->sub.frame;
   37|       |
   38|  74.0k|    if (mp_frame_is_signaling(frame)) {
  ------------------
  |  Branch (38:9): [True: 2.02k, False: 71.9k]
  ------------------
   39|  2.02k|        mp_subfilter_continue(&p->sub);
   40|  2.02k|        return;
   41|  2.02k|    }
   42|       |
   43|  71.9k|    if (frame.type != MP_FRAME_VIDEO) {
  ------------------
  |  Branch (43:9): [True: 0, False: 71.9k]
  ------------------
   44|      0|        MP_ERR(f, "video input required!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   45|      0|        mp_filter_internal_mark_failed(f);
   46|      0|        return;
   47|      0|    }
   48|       |
   49|  71.9k|    struct mp_image *img = frame.data;
   50|  71.9k|    bool interlaced = img->fields & MP_IMGFIELD_INTERLACED;
  ------------------
  |  |   39|  71.9k|#define MP_IMGFIELD_INTERLACED 0x20
  ------------------
   51|       |
   52|  71.9k|    m_config_cache_update(p->opts);
   53|  71.9k|    struct filter_opts *opts = p->opts->opts;
   54|  71.9k|    bool should_deinterlace = (opts->deinterlace == -1 && interlaced) ||
  ------------------
  |  Branch (54:32): [True: 0, False: 71.9k]
  |  Branch (54:59): [True: 0, False: 0]
  ------------------
   55|  71.9k|                               opts->deinterlace == 1;
  ------------------
  |  Branch (55:32): [True: 0, False: 71.9k]
  ------------------
   56|       |
   57|  71.9k|    if (!should_deinterlace)
  ------------------
  |  Branch (57:9): [True: 71.9k, False: 0]
  ------------------
   58|  71.9k|        mp_subfilter_destroy(&p->sub);
   59|       |
   60|  71.9k|    if (img->imgfmt == p->prev_imgfmt && p->deinterlace_active == should_deinterlace) {
  ------------------
  |  Branch (60:9): [True: 65.4k, False: 6.54k]
  |  Branch (60:42): [True: 65.4k, False: 0]
  ------------------
   61|  65.4k|        mp_subfilter_continue(&p->sub);
   62|  65.4k|        return;
   63|  65.4k|    }
   64|       |
   65|  6.54k|    if (!mp_subfilter_drain_destroy(&p->sub))
  ------------------
  |  Branch (65:9): [True: 0, False: 6.54k]
  ------------------
   66|      0|        return;
   67|       |
   68|  6.54k|    mp_assert(!p->sub.filter);
  ------------------
  |  |   41|  6.54k|#define mp_assert assert
  ------------------
   69|       |
   70|  6.54k|    p->prev_imgfmt = img->imgfmt;
   71|  6.54k|    p->deinterlace_active = should_deinterlace;
   72|  6.54k|    if (!p->deinterlace_active) {
  ------------------
  |  Branch (72:9): [True: 6.54k, False: 0]
  ------------------
   73|  6.54k|        mp_subfilter_continue(&p->sub);
   74|  6.54k|        return;
   75|  6.54k|    }
   76|       |
   77|      0|    char *field_parity;
   78|      0|    switch (opts->field_parity) {
   79|      0|    case MP_FIELD_PARITY_TFF:
  ------------------
  |  |   33|      0|#define MP_FIELD_PARITY_TFF 0
  ------------------
  |  Branch (79:5): [True: 0, False: 0]
  ------------------
   80|      0|        field_parity = "tff";
   81|      0|        break;
   82|      0|    case MP_FIELD_PARITY_BFF:
  ------------------
  |  |   34|      0|#define MP_FIELD_PARITY_BFF 1
  ------------------
  |  Branch (82:5): [True: 0, False: 0]
  ------------------
   83|      0|        field_parity = "bff";
   84|      0|        break;
   85|      0|    default:
  ------------------
  |  Branch (85:5): [True: 0, False: 0]
  ------------------
   86|      0|        field_parity = "auto";
   87|      0|    }
   88|       |
   89|      0|    bool has_filter = true;
   90|      0|    if (img->imgfmt == IMGFMT_VDPAU) {
  ------------------
  |  Branch (90:9): [True: 0, False: 0]
  ------------------
   91|      0|        char *args[] = {"deint", "yes",
   92|      0|                        "parity", field_parity, NULL};
   93|      0|        p->sub.filter =
   94|      0|            mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vdpaupp", args);
   95|      0|    } else if (img->imgfmt == IMGFMT_D3D11) {
  ------------------
  |  Branch (95:16): [True: 0, False: 0]
  ------------------
   96|      0|        char *args[] = {"deint", "yes",
   97|      0|                        "parity", field_parity, NULL};
   98|      0|        p->sub.filter =
   99|      0|            mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "d3d11vpp", args);
  100|      0|    } else if (img->imgfmt == IMGFMT_CUDA) {
  ------------------
  |  Branch (100:16): [True: 0, False: 0]
  ------------------
  101|      0|        char *args[] = {"mode", "send_field",
  102|      0|                        "parity", field_parity, NULL};
  103|      0|        p->sub.filter =
  104|      0|            mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "bwdif_cuda", args);
  105|      0|    } else if (img->imgfmt == IMGFMT_VULKAN) {
  ------------------
  |  Branch (105:16): [True: 0, False: 0]
  ------------------
  106|      0|        char *args[] = {"mode", "send_field",
  107|      0|                        "parity", field_parity, NULL};
  108|      0|        p->sub.filter =
  109|      0|            mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "bwdif_vulkan", args);
  110|      0|    } else if (img->imgfmt == IMGFMT_VAAPI) {
  ------------------
  |  Branch (110:16): [True: 0, False: 0]
  ------------------
  111|      0|        char *args[] = {"deint", "motion-adaptive",
  112|      0|                        "parity", field_parity, NULL};
  113|      0|        p->sub.filter =
  114|      0|            mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vavpp", args);
  115|      0|    } else {
  116|      0|        has_filter = false;
  117|      0|    }
  118|       |
  119|      0|    if (!p->sub.filter) {
  ------------------
  |  Branch (119:9): [True: 0, False: 0]
  ------------------
  120|      0|        if (has_filter)
  ------------------
  |  Branch (120:13): [True: 0, False: 0]
  ------------------
  121|      0|            MP_ERR(f, "creating deinterlacer failed\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  122|       |
  123|      0|        struct mp_filter *subf = mp_bidir_dummy_filter_create(f);
  124|      0|        struct mp_filter *filters[2] = {0};
  125|       |
  126|      0|        struct mp_autoconvert *ac = mp_autoconvert_create(subf);
  127|      0|        if (ac) {
  ------------------
  |  Branch (127:13): [True: 0, False: 0]
  ------------------
  128|      0|            filters[0] = ac->f;
  129|       |            // We know vf_bwdif does not support hw inputs.
  130|      0|            mp_autoconvert_add_all_sw_imgfmts(ac);
  131|       |
  132|      0|            if (!mp_autoconvert_probe_input_video(ac, img)) {
  ------------------
  |  Branch (132:17): [True: 0, False: 0]
  ------------------
  133|      0|                MP_ERR(f, "no deinterlace filter available for format %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  134|      0|                       mp_imgfmt_to_name(img->imgfmt));
  135|      0|                talloc_free(subf);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  136|      0|                mp_subfilter_continue(&p->sub);
  137|      0|                return;
  138|      0|            }
  139|      0|        }
  140|       |
  141|      0|        char *args[] = {"mode", "send_field",
  142|      0|                        "parity", field_parity, NULL};
  143|      0|        filters[1] =
  144|      0|            mp_create_user_filter(subf, MP_OUTPUT_CHAIN_VIDEO, "bwdif", args);
  145|       |
  146|      0|        mp_chain_filters(subf->ppins[0], subf->ppins[1], filters, 2);
  147|      0|        p->sub.filter = subf;
  148|      0|    }
  149|       |
  150|      0|    mp_subfilter_continue(&p->sub);
  151|      0|}
f_auto_filters.c:deint_command:
  169|  74.0k|{
  170|  74.0k|    struct deint_priv *p = f->priv;
  171|       |
  172|  74.0k|    if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
  ------------------
  |  Branch (172:9): [True: 74.0k, False: 0]
  ------------------
  173|  74.0k|        cmd->is_active = !!p->sub.filter;
  174|  74.0k|        return true;
  175|  74.0k|    }
  176|      0|    return false;
  177|  74.0k|}
f_auto_filters.c:rotate_destroy:
  293|  2.93k|{
  294|  2.93k|    struct rotate_priv *p = f->priv;
  295|       |
  296|  2.93k|    mp_subfilter_reset(&p->sub);
  297|  2.93k|    TA_FREEP(&p->sub.filter);
  ------------------
  |  |   81|  2.93k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  2.93k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  298|  2.93k|}
f_auto_filters.c:rotate_process:
  218|   151k|{
  219|   151k|    struct rotate_priv *p = f->priv;
  220|       |
  221|   151k|    if (!mp_subfilter_read(&p->sub))
  ------------------
  |  Branch (221:9): [True: 77.4k, False: 74.0k]
  ------------------
  222|  77.4k|        return;
  223|       |
  224|  74.0k|    struct mp_frame frame = p->sub.frame;
  225|       |
  226|  74.0k|    if (mp_frame_is_signaling(frame)) {
  ------------------
  |  Branch (226:9): [True: 2.02k, False: 71.9k]
  ------------------
  227|  2.02k|        mp_subfilter_continue(&p->sub);
  228|  2.02k|        return;
  229|  2.02k|    }
  230|       |
  231|  71.9k|    if (frame.type != MP_FRAME_VIDEO) {
  ------------------
  |  Branch (231:9): [True: 0, False: 71.9k]
  ------------------
  232|      0|        MP_ERR(f, "video input required!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  233|      0|        return;
  234|      0|    }
  235|       |
  236|  71.9k|    struct mp_image *img = frame.data;
  237|       |
  238|  71.9k|    if (img->params.rotate == p->prev_rotate &&
  ------------------
  |  Branch (238:9): [True: 71.4k, False: 561]
  ------------------
  239|  71.9k|        img->imgfmt == p->prev_imgfmt)
  ------------------
  |  Branch (239:9): [True: 65.4k, False: 5.98k]
  ------------------
  240|  65.4k|    {
  241|  65.4k|        img->params.rotate = p->target_rotate;
  242|  65.4k|        mp_subfilter_continue(&p->sub);
  243|  65.4k|        return;
  244|  65.4k|    }
  245|       |
  246|  6.54k|    if (!mp_subfilter_drain_destroy(&p->sub))
  ------------------
  |  Branch (246:9): [True: 0, False: 6.54k]
  ------------------
  247|      0|        return;
  248|       |
  249|  6.54k|    mp_assert(!p->sub.filter);
  ------------------
  |  |   41|  6.54k|#define mp_assert assert
  ------------------
  250|       |
  251|  6.54k|    int rotate = p->prev_rotate = img->params.rotate;
  252|  6.54k|    p->target_rotate = rotate;
  253|  6.54k|    p->prev_imgfmt = img->imgfmt;
  254|       |
  255|  6.54k|    struct mp_stream_info *info = mp_filter_find_stream_info(f);
  256|  6.54k|    if (rotate == 0 || (info && info->rotate90 && !(rotate % 90))) {
  ------------------
  |  Branch (256:9): [True: 6.54k, False: 0]
  |  Branch (256:25): [True: 0, False: 0]
  |  Branch (256:33): [True: 0, False: 0]
  |  Branch (256:51): [True: 0, False: 0]
  ------------------
  257|  6.54k|        mp_subfilter_continue(&p->sub);
  258|  6.54k|        return;
  259|  6.54k|    }
  260|       |
  261|      0|    if (!mp_sws_supports_input(img->imgfmt)) {
  ------------------
  |  Branch (261:9): [True: 0, False: 0]
  ------------------
  262|      0|        MP_ERR(f, "Video rotation with this format not supported\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  263|      0|        mp_subfilter_continue(&p->sub);
  264|      0|        return;
  265|      0|    }
  266|       |
  267|      0|    double angle = rotate / 360.0 * M_PI * 2;
  268|      0|    char *args[] = {"angle", mp_tprintf(30, "%f", angle),
  ------------------
  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  ------------------
  269|      0|                    "ow", mp_tprintf(30, "rotw(%f)", angle),
  ------------------
  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  ------------------
  270|      0|                    "oh", mp_tprintf(30, "roth(%f)", angle),
  ------------------
  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  ------------------
  271|      0|                    NULL};
  272|      0|    p->sub.filter =
  273|      0|        mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "rotate", args);
  274|       |
  275|      0|    if (p->sub.filter) {
  ------------------
  |  Branch (275:9): [True: 0, False: 0]
  ------------------
  276|      0|        MP_INFO(f, "Inserting rotation filter.\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  277|      0|        p->target_rotate = 0;
  278|      0|    } else {
  279|      0|        MP_ERR(f, "could not create rotation filter\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  280|      0|    }
  281|       |
  282|      0|    mp_subfilter_continue(&p->sub);
  283|      0|}
f_auto_filters.c:rotate_command:
  301|  74.0k|{
  302|  74.0k|    struct rotate_priv *p = f->priv;
  303|       |
  304|  74.0k|    if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
  ------------------
  |  Branch (304:9): [True: 74.0k, False: 0]
  ------------------
  305|  74.0k|        cmd->is_active = !!p->sub.filter;
  306|  74.0k|        return true;
  307|  74.0k|    }
  308|      0|    return false;
  309|  74.0k|}
f_auto_filters.c:vflip_destroy:
  414|  2.93k|{
  415|  2.93k|    struct vflip_priv *p = f->priv;
  416|       |
  417|  2.93k|    mp_subfilter_reset(&p->sub);
  418|  2.93k|    TA_FREEP(&p->sub.filter);
  ------------------
  |  |   81|  2.93k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  2.93k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  419|  2.93k|}
f_auto_filters.c:vflip_process:
  343|   151k|{
  344|   151k|    struct vflip_priv *p = f->priv;
  345|       |
  346|   151k|    if (!mp_subfilter_read(&p->sub))
  ------------------
  |  Branch (346:9): [True: 77.4k, False: 74.0k]
  ------------------
  347|  77.4k|        return;
  348|       |
  349|  74.0k|    struct mp_frame frame = p->sub.frame;
  350|       |
  351|  74.0k|    if (mp_frame_is_signaling(frame)) {
  ------------------
  |  Branch (351:9): [True: 2.02k, False: 71.9k]
  ------------------
  352|  2.02k|        mp_subfilter_continue(&p->sub);
  353|  2.02k|        return;
  354|  2.02k|    }
  355|       |
  356|  71.9k|    if (frame.type != MP_FRAME_VIDEO) {
  ------------------
  |  Branch (356:9): [True: 0, False: 71.9k]
  ------------------
  357|      0|        MP_ERR(f, "video input required!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  358|      0|        return;
  359|      0|    }
  360|       |
  361|  71.9k|    struct mp_image *img = frame.data;
  362|       |
  363|  71.9k|    if (img->params.vflip == p->prev_vflip &&
  ------------------
  |  Branch (363:9): [True: 71.4k, False: 561]
  ------------------
  364|  71.9k|        img->imgfmt == p->prev_imgfmt)
  ------------------
  |  Branch (364:9): [True: 65.4k, False: 5.98k]
  ------------------
  365|  65.4k|    {
  366|  65.4k|        img->params.vflip = p->target_vflip;
  367|  65.4k|        mp_subfilter_continue(&p->sub);
  368|  65.4k|        return;
  369|  65.4k|    }
  370|       |
  371|  6.54k|    if (!mp_subfilter_drain_destroy(&p->sub))
  ------------------
  |  Branch (371:9): [True: 0, False: 6.54k]
  ------------------
  372|      0|        return;
  373|       |
  374|  6.54k|    mp_assert(!p->sub.filter);
  ------------------
  |  |   41|  6.54k|#define mp_assert assert
  ------------------
  375|       |
  376|  6.54k|    int vflip = p->prev_vflip = img->params.vflip;
  377|  6.54k|    p->target_vflip = vflip;
  378|  6.54k|    p->prev_imgfmt = img->imgfmt;
  379|       |
  380|  6.54k|    struct mp_stream_info *info = mp_filter_find_stream_info(f);
  381|  6.54k|    if (!vflip || (info && info->vflip)) {
  ------------------
  |  Branch (381:9): [True: 6.54k, False: 0]
  |  Branch (381:20): [True: 0, False: 0]
  |  Branch (381:28): [True: 0, False: 0]
  ------------------
  382|  6.54k|        mp_subfilter_continue(&p->sub);
  383|  6.54k|        return;
  384|  6.54k|    }
  385|       |
  386|      0|    if (!mp_sws_supports_input(img->imgfmt)) {
  ------------------
  |  Branch (386:9): [True: 0, False: 0]
  ------------------
  387|      0|        MP_ERR(f, "Video vflip with this format not supported\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  388|      0|        mp_subfilter_continue(&p->sub);
  389|      0|        return;
  390|      0|    }
  391|       |
  392|      0|    char *args[] = {NULL};
  393|       |
  394|      0|    p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vflip", args);
  395|       |
  396|      0|    if (p->sub.filter) {
  ------------------
  |  Branch (396:9): [True: 0, False: 0]
  ------------------
  397|      0|        MP_INFO(f, "Inserting vflip filter.\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  398|      0|        p->target_vflip = 0;
  399|      0|    } else {
  400|      0|        MP_ERR(f, "could not create vflip filter\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  401|      0|    }
  402|       |
  403|      0|    mp_subfilter_continue(&p->sub);
  404|      0|}
f_auto_filters.c:vflip_command:
  422|  74.0k|{
  423|  74.0k|    struct vflip_priv *p = f->priv;
  424|       |
  425|  74.0k|    if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
  ------------------
  |  Branch (425:9): [True: 74.0k, False: 0]
  ------------------
  426|  74.0k|        cmd->is_active = !!p->sub.filter;
  427|  74.0k|        return true;
  428|  74.0k|    }
  429|      0|    return false;
  430|  74.0k|}
f_auto_filters.c:aspeed_destroy:
  548|  1.95k|{
  549|  1.95k|    struct aspeed_priv *p = f->priv;
  550|       |
  551|  1.95k|    mp_subfilter_reset(&p->sub);
  552|  1.95k|    TA_FREEP(&p->sub.filter);
  ------------------
  |  |   81|  1.95k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  1.95k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  553|  1.95k|}
f_auto_filters.c:aspeed_process:
  463|   753k|{
  464|   753k|    struct aspeed_priv *p = f->priv;
  465|       |
  466|   753k|    if (!mp_subfilter_read(&p->sub))
  ------------------
  |  Branch (466:9): [True: 377k, False: 375k]
  ------------------
  467|   377k|        return;
  468|       |
  469|   375k|    if (!p->sub.filter)
  ------------------
  |  Branch (469:9): [True: 375k, False: 0]
  ------------------
  470|   375k|        p->current_filter = 0;
  471|       |
  472|   375k|    double speed = p->cur_speed * p->cur_speed_drop;
  473|       |
  474|   375k|    int req_filter = 0;
  475|   375k|    if (fabs(speed - 1.0) >= 1e-8) {
  ------------------
  |  Branch (475:9): [True: 0, False: 375k]
  ------------------
  476|      0|        req_filter = p->cur_speed_drop == 1.0 ? 1 : 2;
  ------------------
  |  Branch (476:22): [True: 0, False: 0]
  ------------------
  477|      0|        if (p->sub.frame.type == MP_FRAME_AUDIO &&
  ------------------
  |  Branch (477:13): [True: 0, False: 0]
  ------------------
  478|      0|            !af_fmt_is_pcm(mp_aframe_get_format(p->sub.frame.data)))
  ------------------
  |  Branch (478:13): [True: 0, False: 0]
  ------------------
  479|      0|            req_filter = 2;
  480|      0|    }
  481|       |
  482|   375k|    if (req_filter != p->current_filter) {
  ------------------
  |  Branch (482:9): [True: 0, False: 375k]
  ------------------
  483|      0|        if (p->sub.filter)
  ------------------
  |  Branch (483:13): [True: 0, False: 0]
  ------------------
  484|      0|            MP_VERBOSE(f, "removing audio speed filter\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  485|      0|        if (!mp_subfilter_drain_destroy(&p->sub))
  ------------------
  |  Branch (485:13): [True: 0, False: 0]
  ------------------
  486|      0|            return;
  487|       |
  488|      0|        if (req_filter) {
  ------------------
  |  Branch (488:13): [True: 0, False: 0]
  ------------------
  489|      0|            if (req_filter == 1) {
  ------------------
  |  Branch (489:17): [True: 0, False: 0]
  ------------------
  490|      0|                MP_VERBOSE(f, "adding scaletempo2\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  491|      0|                p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
  492|      0|                                                      "scaletempo2", NULL);
  493|      0|            } else if (req_filter == 2) {
  ------------------
  |  Branch (493:24): [True: 0, False: 0]
  ------------------
  494|      0|                MP_VERBOSE(f, "adding drop\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  495|      0|                p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
  496|      0|                                                      "drop", NULL);
  497|      0|            }
  498|      0|            if (!p->sub.filter) {
  ------------------
  |  Branch (498:17): [True: 0, False: 0]
  ------------------
  499|      0|                MP_ERR(f, "could not create filter\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  500|      0|                mp_subfilter_continue(&p->sub);
  501|      0|                return;
  502|      0|            }
  503|      0|            p->current_filter = req_filter;
  504|      0|        }
  505|      0|    }
  506|       |
  507|   375k|    if (p->sub.filter) {
  ------------------
  |  Branch (507:9): [True: 0, False: 375k]
  ------------------
  508|      0|        struct mp_filter_command cmd = {
  509|      0|            .type = MP_FILTER_COMMAND_SET_SPEED,
  510|      0|            .speed = speed,
  511|      0|        };
  512|      0|        mp_filter_command(p->sub.filter, &cmd);
  513|      0|    }
  514|       |
  515|   375k|    mp_subfilter_continue(&p->sub);
  516|   375k|}
f_auto_filters.c:aspeed_command:
  519|   380k|{
  520|   380k|    struct aspeed_priv *p = f->priv;
  521|       |
  522|   380k|    if (cmd->type == MP_FILTER_COMMAND_SET_SPEED) {
  ------------------
  |  Branch (522:9): [True: 1.82k, False: 379k]
  ------------------
  523|  1.82k|        p->cur_speed = cmd->speed;
  524|  1.82k|        return true;
  525|  1.82k|    }
  526|       |
  527|   379k|    if (cmd->type == MP_FILTER_COMMAND_SET_SPEED_DROP) {
  ------------------
  |  Branch (527:9): [True: 1.82k, False: 377k]
  ------------------
  528|  1.82k|        p->cur_speed_drop = cmd->speed;
  529|  1.82k|        return true;
  530|  1.82k|    }
  531|       |
  532|   377k|    if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
  ------------------
  |  Branch (532:9): [True: 375k, False: 1.82k]
  ------------------
  533|   375k|        cmd->is_active = !!p->sub.filter;
  534|   375k|        return true;
  535|   375k|    }
  536|       |
  537|  1.82k|    return false;
  538|   377k|}

mp_autoconvert_clear:
   61|  15.5k|{
   62|  15.5k|    struct priv *p = c->f->priv;
   63|       |
   64|  15.5k|    p->num_imgfmts = 0;
   65|  15.5k|    p->imgparams_set = false;
   66|  15.5k|    p->num_afmts = 0;
   67|  15.5k|    p->num_srates = 0;
   68|  15.5k|    p->chmaps = (struct mp_chmap_sel){0};
   69|  15.5k|    p->force_update = true;
   70|  15.5k|}
mp_autoconvert_add_imgfmt:
   73|  7.92M|{
   74|  7.92M|    struct priv *p = c->f->priv;
   75|       |
   76|  7.92M|    MP_TARRAY_GROW(p, p->imgfmts, p->num_imgfmts);
  ------------------
  |  |   96|  7.92M|    do {                                            \
  |  |   97|  7.92M|        size_t nextidx_ = (nextidx);                \
  |  |   98|  7.92M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  7.92M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  7.92M|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 26.3k, False: 7.89M]
  |  |  ------------------
  |  |   99|  7.92M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  26.3k|    do {                                                        \
  |  |  |  |   89|  26.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  26.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  26.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  26.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  26.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  26.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  26.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  7.92M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   77|  7.92M|    MP_TARRAY_GROW(p, p->subfmts, p->num_imgfmts);
  ------------------
  |  |   96|  7.92M|    do {                                            \
  |  |   97|  7.92M|        size_t nextidx_ = (nextidx);                \
  |  |   98|  7.92M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  7.92M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  7.92M|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 26.3k, False: 7.89M]
  |  |  ------------------
  |  |   99|  7.92M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  26.3k|    do {                                                        \
  |  |  |  |   89|  26.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  26.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  26.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  26.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  26.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  26.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  26.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  7.92M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   78|       |
   79|  7.92M|    p->imgfmts[p->num_imgfmts] = imgfmt;
   80|  7.92M|    p->subfmts[p->num_imgfmts] = subfmt;
   81|       |
   82|  7.92M|    p->num_imgfmts += 1;
   83|  7.92M|    p->force_update = true;
   84|  7.92M|}
mp_autoconvert_add_afmt:
  112|  1.36k|{
  113|  1.36k|    struct priv *p = c->f->priv;
  114|       |
  115|  1.36k|    MP_TARRAY_APPEND(p, p->afmts, p->num_afmts, afmt);
  ------------------
  |  |  105|  1.36k|    do {                                            \
  |  |  106|  1.36k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.36k|    do {                                            \
  |  |  |  |   97|  1.36k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.36k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.36k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.36k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 732, False: 629]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.36k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    732|    do {                                                        \
  |  |  |  |  |  |   89|    732|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    732|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    732|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    732|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    732|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    732|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    732|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.36k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.36k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.36k|        (idxvar)++;                                 \
  |  |  109|  1.36k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  116|  1.36k|    p->force_update = true;
  117|  1.36k|}
mp_autoconvert_add_chmap:
  120|  1.36k|{
  121|  1.36k|    struct priv *p = c->f->priv;
  122|       |
  123|  1.36k|    mp_chmap_sel_add_map(&p->chmaps, chmap);
  124|  1.36k|    p->force_update = true;
  125|  1.36k|}
mp_autoconvert_add_srate:
  128|  1.36k|{
  129|  1.36k|    struct priv *p = c->f->priv;
  130|       |
  131|  1.36k|    MP_TARRAY_APPEND(p, p->srates, p->num_srates, rate);
  ------------------
  |  |  105|  1.36k|    do {                                            \
  |  |  106|  1.36k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.36k|    do {                                            \
  |  |  |  |   97|  1.36k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.36k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.36k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.36k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 732, False: 629]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.36k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    732|    do {                                                        \
  |  |  |  |  |  |   89|    732|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    732|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    732|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    732|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    732|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    732|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    732|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.36k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.36k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.36k|        (idxvar)++;                                 \
  |  |  109|  1.36k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  132|       |    // Some other API we call expects a 0-terminated sample rates array.
  133|  1.36k|    MP_TARRAY_GROW(p, p->srates, p->num_srates);
  ------------------
  |  |   96|  1.36k|    do {                                            \
  |  |   97|  1.36k|        size_t nextidx_ = (nextidx);                \
  |  |   98|  1.36k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  1.36k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  1.36k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 1.36k]
  |  |  ------------------
  |  |   99|  1.36k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  1.36k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  134|  1.36k|    p->srates[p->num_srates] = 0;
  135|  1.36k|    p->force_update = true;
  136|  1.36k|}
mp_autoconvert_format_change_continue:
  501|  1.36k|{
  502|  1.36k|    struct priv *p = c->f->priv;
  503|       |
  504|  1.36k|    if (p->format_change_blocked) {
  ------------------
  |  Branch (504:9): [True: 1.36k, False: 0]
  ------------------
  505|  1.36k|        p->format_change_cont = true;
  506|  1.36k|        p->format_change_blocked = false;
  507|  1.36k|        mp_filter_wakeup(c->f);
  508|  1.36k|    }
  509|  1.36k|}
mp_autoconvert_create:
  560|  4.88k|{
  561|  4.88k|    struct mp_filter *f = mp_filter_create(parent, &autoconvert_filter);
  562|  4.88k|    if (!f)
  ------------------
  |  Branch (562:9): [True: 0, False: 4.88k]
  ------------------
  563|      0|        return NULL;
  564|       |
  565|  4.88k|    mp_filter_add_pin(f, MP_PIN_IN, "in");
  566|  4.88k|    mp_filter_add_pin(f, MP_PIN_OUT, "out");
  567|       |
  568|  4.88k|    struct priv *p = f->priv;
  569|  4.88k|    p->public.f = f;
  570|  4.88k|    p->log = f->log;
  571|  4.88k|    p->audio_speed = 1.0;
  572|  4.88k|    p->sub.in = f->ppins[0];
  573|  4.88k|    p->sub.out = f->ppins[1];
  574|       |
  575|  4.88k|    return &p->public;
  576|  4.88k|}
f_autoconvert.c:build_image_converter:
  141|  9.26k|{
  142|  9.26k|    struct mp_filter *f = c->f;
  143|  9.26k|    struct priv *p = f->priv;
  144|       |
  145|  9.26k|    *f_out = NULL;
  146|       |
  147|  9.26k|    if (!p->num_imgfmts)
  ------------------
  |  Branch (147:9): [True: 0, False: 9.26k]
  ------------------
  148|      0|        return true;
  149|       |
  150|  90.0k|    for (int n = 0; n < p->num_imgfmts; n++) {
  ------------------
  |  Branch (150:21): [True: 90.0k, False: 0]
  ------------------
  151|  90.0k|        bool samefmt = img->params.imgfmt == p->imgfmts[n];
  152|  90.0k|        bool samesubffmt = img->params.hw_subfmt == p->subfmts[n];
  153|       |        /*
  154|       |         * In practice, `p->subfmts` is not usually populated today, in which
  155|       |         * case we must actively probe formats below to establish if the VO can
  156|       |         * accept the subfmt being used by the hwdec.
  157|       |         */
  158|  90.0k|        if (samefmt && samesubffmt) {
  ------------------
  |  Branch (158:13): [True: 9.26k, False: 80.7k]
  |  Branch (158:24): [True: 9.26k, False: 0]
  ------------------
  159|  9.26k|            if (p->imgparams_set) {
  ------------------
  |  Branch (159:17): [True: 0, False: 9.26k]
  ------------------
  160|      0|                if (!mp_image_params_static_equal(&p->imgparams, &img->params))
  ------------------
  |  Branch (160:21): [True: 0, False: 0]
  ------------------
  161|      0|                    break;
  162|      0|            }
  163|  9.26k|            return true;
  164|  9.26k|        }
  165|  90.0k|    }
  166|       |
  167|      0|    struct mp_filter *conv = mp_filter_create(f, &convert_filter);
  168|      0|    if (!conv)
  ------------------
  |  Branch (168:9): [True: 0, False: 0]
  ------------------
  169|      0|        return false;
  170|       |
  171|      0|    mp_filter_add_pin(conv, MP_PIN_IN, "in");
  172|      0|    mp_filter_add_pin(conv, MP_PIN_OUT, "out");
  173|       |
  174|       |    // 0: hw->sw download
  175|       |    // 1: swscale
  176|       |    // 2: sw->hw upload
  177|      0|    struct mp_filter *filters[3] = {0};
  178|      0|    bool need_sws = true;
  179|      0|    bool force_sws_params = false;
  180|      0|    struct mp_image_params imgpar = img->params;
  181|       |
  182|      0|    int *fmts = p->imgfmts;
  183|      0|    int num_fmts = p->num_imgfmts;
  184|      0|    int hwupload_fmt = 0;
  185|       |
  186|      0|    bool imgfmt_is_sw = !IMGFMT_IS_HWACCEL(img->imgfmt);
  ------------------
  |  |  327|      0|#define IMGFMT_IS_HWACCEL(fmt) (!!(mp_imgfmt_get_desc(fmt).flags & MP_IMGFLAG_HWACCEL))
  |  |  ------------------
  |  |  |  |   70|      0|#define MP_IMGFLAG_HWACCEL      MP_IMGFLAG_TYPE_HW
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define MP_IMGFLAG_TYPE_HW      (8 << 10)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  187|       |
  188|       |    // This should not happen. But not enough guarantee to make it an assert().
  189|      0|    if (imgfmt_is_sw != !img->hwctx)
  ------------------
  |  Branch (189:9): [True: 0, False: 0]
  ------------------
  190|      0|        mp_warn(log, "Unexpected AVFrame/imgfmt hardware context mismatch.\n");
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
  191|       |
  192|      0|    bool dst_all_hw = true;
  193|      0|    bool dst_have_sw = false;
  194|      0|    bool has_src_hw_fmt = false;
  195|      0|    for (int n = 0; n < num_fmts; n++) {
  ------------------
  |  Branch (195:21): [True: 0, False: 0]
  ------------------
  196|      0|        bool is_hw = IMGFMT_IS_HWACCEL(fmts[n]);
  ------------------
  |  |  327|      0|#define IMGFMT_IS_HWACCEL(fmt) (!!(mp_imgfmt_get_desc(fmt).flags & MP_IMGFLAG_HWACCEL))
  |  |  ------------------
  |  |  |  |   70|      0|#define MP_IMGFLAG_HWACCEL      MP_IMGFLAG_TYPE_HW
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define MP_IMGFLAG_TYPE_HW      (8 << 10)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  197|      0|        dst_all_hw &= is_hw;
  198|      0|        dst_have_sw |= !is_hw;
  199|      0|        has_src_hw_fmt |= is_hw && fmts[n] == imgpar.imgfmt;
  ------------------
  |  Branch (199:27): [True: 0, False: 0]
  |  Branch (199:36): [True: 0, False: 0]
  ------------------
  200|      0|    }
  201|       |
  202|       |    // Source is hw, some targets are sw -> try to download.
  203|      0|    bool hw_to_sw = !imgfmt_is_sw && dst_have_sw;
  ------------------
  |  Branch (203:21): [True: 0, False: 0]
  |  Branch (203:38): [True: 0, False: 0]
  ------------------
  204|       |
  205|      0|    if (has_src_hw_fmt) {
  ------------------
  |  Branch (205:9): [True: 0, False: 0]
  ------------------
  206|      0|        int src_fmt = img->params.hw_subfmt;
  207|       |        /*
  208|       |         * If the source format is a hardware format, and our output supports
  209|       |         * that hardware format, we prioritize preserving the use of that
  210|       |         * hardware format. In most cases, the sub format will also be supported
  211|       |         * and no conversion will be required, but in some cases, the hwdec
  212|       |         * may be able to output formats that the VO cannot display, and
  213|       |         * hardware format conversion becomes necessary.
  214|       |         */
  215|      0|        struct mp_hwupload upload = mp_hwupload_create(conv, imgpar.imgfmt,
  216|      0|                                                       src_fmt,
  217|      0|                                                       true);
  218|      0|        if (upload.successful_init) {
  ------------------
  |  Branch (218:13): [True: 0, False: 0]
  ------------------
  219|      0|            if (upload.f) {
  ------------------
  |  Branch (219:17): [True: 0, False: 0]
  ------------------
  220|      0|                mp_info(log, "Converting %s[%s] -> %s[%s]\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  221|      0|                        mp_imgfmt_to_name(imgpar.imgfmt),
  222|      0|                        mp_imgfmt_to_name(src_fmt),
  223|      0|                        mp_imgfmt_to_name(imgpar.imgfmt),
  224|      0|                        mp_imgfmt_to_name(upload.selected_sw_imgfmt));
  225|      0|                filters[2] = upload.f;
  226|      0|            }
  227|      0|            hw_to_sw = false;
  228|      0|            need_sws = false;
  229|      0|        } else {
  230|      0|            mp_err(log, "Failed to create HW uploader for format %s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  231|      0|                   mp_imgfmt_to_name(src_fmt));
  232|      0|        }
  233|      0|    } else if (dst_all_hw && num_fmts > 0) {
  ------------------
  |  Branch (233:16): [True: 0, False: 0]
  |  Branch (233:30): [True: 0, False: 0]
  ------------------
  234|      0|        bool upload_created = false;
  235|      0|        int sw_fmt = imgfmt_is_sw ? img->imgfmt : img->params.hw_subfmt;
  ------------------
  |  Branch (235:22): [True: 0, False: 0]
  ------------------
  236|       |
  237|      0|        for (int i = 0; i < num_fmts; i++) {
  ------------------
  |  Branch (237:25): [True: 0, False: 0]
  ------------------
  238|       |            // We can probably use this! Very lazy and very approximate.
  239|      0|            struct mp_hwupload upload = mp_hwupload_create(conv, fmts[i],
  240|      0|                                                           sw_fmt, false);
  241|      0|            if (upload.successful_init) {
  ------------------
  |  Branch (241:17): [True: 0, False: 0]
  ------------------
  242|      0|                mp_info(log, "HW-uploading to %s\n", mp_imgfmt_to_name(fmts[i]));
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  243|      0|                filters[2] = upload.f;
  244|      0|                hwupload_fmt = upload.selected_sw_imgfmt;
  245|      0|                fmts = &hwupload_fmt;
  246|      0|                num_fmts = hwupload_fmt ? 1 : 0;
  ------------------
  |  Branch (246:28): [True: 0, False: 0]
  ------------------
  247|      0|                hw_to_sw = false;
  248|       |
  249|       |                // We cannot do format conversions when transferring between
  250|       |                // two hardware devices, so reject this format if that would be
  251|       |                // required.
  252|      0|                if (!imgfmt_is_sw && hwupload_fmt != sw_fmt) {
  ------------------
  |  Branch (252:21): [True: 0, False: 0]
  |  Branch (252:38): [True: 0, False: 0]
  ------------------
  253|      0|                    mp_err(log, "Format %s is not supported by %s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  254|      0|                           mp_imgfmt_to_name(sw_fmt),
  255|      0|                           mp_imgfmt_to_name(p->imgfmts[i]));
  256|      0|                    continue;
  257|      0|                }
  258|      0|                upload_created = true;
  259|      0|                break;
  260|      0|            }
  261|      0|        }
  262|      0|        if (!upload_created) {
  ------------------
  |  Branch (262:13): [True: 0, False: 0]
  ------------------
  263|      0|            mp_err(log, "Failed to create HW uploader for format %s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  264|      0|                   mp_imgfmt_to_name(sw_fmt));
  265|      0|        }
  266|      0|    }
  267|       |
  268|      0|    int src_fmt = img->imgfmt;
  269|      0|    if (hw_to_sw) {
  ------------------
  |  Branch (269:9): [True: 0, False: 0]
  ------------------
  270|      0|        mp_info(log, "HW-downloading from %s\n", mp_imgfmt_to_name(img->imgfmt));
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  271|      0|        int res_fmt = mp_image_hw_download_get_sw_format(img);
  272|      0|        if (!res_fmt) {
  ------------------
  |  Branch (272:13): [True: 0, False: 0]
  ------------------
  273|      0|            mp_err(log, "cannot copy surface of this format to CPU memory\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  274|      0|            goto fail;
  275|      0|        }
  276|      0|        struct mp_hwdownload *hwd = mp_hwdownload_create(conv);
  277|      0|        if (hwd) {
  ------------------
  |  Branch (277:13): [True: 0, False: 0]
  ------------------
  278|      0|            filters[0] = hwd->f;
  279|      0|            src_fmt = res_fmt;
  280|       |            // Downloading from hw will obviously change the parameters. We
  281|       |            // stupidly don't know the result parameters, but if it's
  282|       |            // sufficiently sane, it will only do the following.
  283|      0|            imgpar.imgfmt = src_fmt;
  284|      0|            imgpar.hw_subfmt = 0;
  285|       |            // Try to compensate for in-sane cases.
  286|      0|            mp_image_params_guess_csp(&imgpar);
  287|      0|        }
  288|      0|    }
  289|       |
  290|      0|    if (p->imgparams_set) {
  ------------------
  |  Branch (290:9): [True: 0, False: 0]
  ------------------
  291|      0|        force_sws_params |= !mp_image_params_equal(&imgpar, &p->imgparams);
  292|      0|        need_sws |= force_sws_params;
  293|      0|    }
  294|      0|    if (!imgfmt_is_sw && dst_all_hw) {
  ------------------
  |  Branch (294:9): [True: 0, False: 0]
  |  Branch (294:26): [True: 0, False: 0]
  ------------------
  295|       |        // This is a hw -> hw upload, so the sw format must already be
  296|       |        // mutually understood. No conversion can be done.
  297|      0|        need_sws = false;
  298|      0|    }
  299|       |
  300|      0|    if (need_sws) {
  ------------------
  |  Branch (300:9): [True: 0, False: 0]
  ------------------
  301|       |        // Create a new conversion filter.
  302|      0|        struct mp_sws_filter *sws = mp_sws_filter_create(conv);
  303|      0|        if (!sws) {
  ------------------
  |  Branch (303:13): [True: 0, False: 0]
  ------------------
  304|      0|            mp_err(log, "error creating conversion filter\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  305|      0|            goto fail;
  306|      0|        }
  307|       |
  308|      0|        sws->force_scaler = c->force_scaler;
  309|       |
  310|      0|        int out = mp_sws_find_best_out_format(sws, src_fmt, fmts, num_fmts);
  311|      0|        if (!out) {
  ------------------
  |  Branch (311:13): [True: 0, False: 0]
  ------------------
  312|      0|            mp_err(log, "can't find video conversion for %s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  313|      0|                   mp_imgfmt_to_name(src_fmt));
  314|      0|            goto fail;
  315|      0|        }
  316|       |
  317|      0|        if (out == src_fmt && !force_sws_params) {
  ------------------
  |  Branch (317:13): [True: 0, False: 0]
  |  Branch (317:31): [True: 0, False: 0]
  ------------------
  318|       |            // Can happen if hwupload goes to same format.
  319|      0|            talloc_free(sws->f);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  320|      0|        } else {
  321|      0|            sws->out_format = out;
  322|      0|            sws->out_params = p->imgparams;
  323|      0|            sws->use_out_params = force_sws_params;
  324|      0|            mp_info(log, "Converting %s -> %s\n", mp_imgfmt_to_name(src_fmt),
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  325|      0|                    mp_imgfmt_to_name(sws->out_format));
  326|      0|            filters[1] = sws->f;
  327|      0|        }
  328|      0|    }
  329|       |
  330|      0|    mp_chain_filters(conv->ppins[0], conv->ppins[1], filters, 3);
  331|       |
  332|      0|    *f_out = conv;
  333|      0|    return true;
  334|       |
  335|      0|fail:
  336|      0|    talloc_free(conv);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  337|      0|    return false;
  338|      0|}
f_autoconvert.c:autoconvert_destroy:
  543|  4.88k|{
  544|  4.88k|    struct priv *p = f->priv;
  545|       |
  546|  4.88k|    mp_subfilter_reset(&p->sub);
  547|  4.88k|    TA_FREEP(&p->sub.filter);
  ------------------
  |  |   81|  4.88k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  4.88k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  548|  4.88k|}
f_autoconvert.c:autoconvert_process:
  481|   906k|{
  482|   906k|    struct priv *p = f->priv;
  483|       |
  484|   906k|    if (!mp_subfilter_read(&p->sub))
  ------------------
  |  Branch (484:9): [True: 455k, False: 450k]
  ------------------
  485|   455k|        return;
  486|       |
  487|   450k|    if (p->sub.frame.type == MP_FRAME_VIDEO) {
  ------------------
  |  Branch (487:9): [True: 71.9k, False: 378k]
  ------------------
  488|  71.9k|        handle_video_frame(f);
  489|  71.9k|        return;
  490|  71.9k|    }
  491|       |
  492|   378k|    if (p->sub.frame.type == MP_FRAME_AUDIO) {
  ------------------
  |  Branch (492:9): [True: 374k, False: 3.83k]
  ------------------
  493|   374k|        handle_audio_frame(f);
  494|   374k|        return;
  495|   374k|    }
  496|       |
  497|  3.83k|    mp_subfilter_continue(&p->sub);
  498|  3.83k|}
f_autoconvert.c:handle_video_frame:
  350|  71.9k|{
  351|  71.9k|    struct priv *p = f->priv;
  352|       |
  353|  71.9k|    struct mp_image *img = p->sub.frame.data;
  354|       |
  355|  71.9k|    if (p->force_update)
  ------------------
  |  Branch (355:9): [True: 9.26k, False: 62.7k]
  ------------------
  356|  9.26k|        p->in_imgfmt = p->in_subfmt = 0;
  357|       |
  358|  71.9k|    if (img->imgfmt == p->in_imgfmt && img->params.hw_subfmt == p->in_subfmt) {
  ------------------
  |  Branch (358:9): [True: 62.7k, False: 9.26k]
  |  Branch (358:40): [True: 62.7k, False: 0]
  ------------------
  359|  62.7k|        mp_subfilter_continue(&p->sub);
  360|  62.7k|        return;
  361|  62.7k|    }
  362|       |
  363|  9.26k|    if (!mp_subfilter_drain_destroy(&p->sub)) {
  ------------------
  |  Branch (363:9): [True: 0, False: 9.26k]
  ------------------
  364|      0|        MP_VERBOSE(f, "Sub-filter requires draining but we must destroy it now.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  365|      0|        mp_subfilter_destroy(&p->sub);
  366|      0|    }
  367|       |
  368|  9.26k|    p->in_imgfmt = img->params.imgfmt;
  369|  9.26k|    p->in_subfmt = img->params.hw_subfmt;
  370|  9.26k|    p->force_update = false;
  371|       |
  372|  9.26k|    struct mp_filter *conv = NULL;
  373|  9.26k|    if (build_image_converter(&p->public, p->log, img, &conv)) {
  ------------------
  |  Branch (373:9): [True: 9.26k, False: 0]
  ------------------
  374|  9.26k|        p->sub.filter = conv;
  375|  9.26k|        mp_subfilter_continue(&p->sub);
  376|  9.26k|    } else {
  377|      0|        mp_filter_internal_mark_failed(f);
  378|      0|    }
  379|  9.26k|}
f_autoconvert.c:handle_audio_frame:
  382|   374k|{
  383|   374k|    struct priv *p = f->priv;
  384|       |
  385|   374k|    struct mp_aframe *aframe = p->sub.frame.data;
  386|       |
  387|   374k|    int afmt = mp_aframe_get_format(aframe);
  388|   374k|    int srate = mp_aframe_get_rate(aframe);
  389|   374k|    struct mp_chmap chmap = {0};
  390|   374k|    mp_aframe_get_chmap(aframe, &chmap);
  391|       |
  392|   374k|    if (p->resampling_forced && !af_fmt_is_pcm(afmt)) {
  ------------------
  |  Branch (392:9): [True: 0, False: 374k]
  |  Branch (392:33): [True: 0, False: 0]
  ------------------
  393|      0|        MP_WARN(p, "ignoring request to resample non-PCM audio for speed change\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  394|      0|        p->resampling_forced = false;
  395|      0|    }
  396|       |
  397|   374k|    bool format_change = afmt != p->in_afmt ||
  ------------------
  |  Branch (397:26): [True: 1.46k, False: 373k]
  ------------------
  398|   374k|                         srate != p->in_srate ||
  ------------------
  |  Branch (398:26): [True: 974, False: 372k]
  ------------------
  399|   374k|                         !mp_chmap_equals(&chmap, &p->in_chmap) ||
  ------------------
  |  Branch (399:26): [True: 284, False: 372k]
  ------------------
  400|   374k|                         p->force_update;
  ------------------
  |  Branch (400:26): [True: 0, False: 372k]
  ------------------
  401|       |
  402|   374k|    if (!format_change && (!p->resampling_forced || p->sub.filter))
  ------------------
  |  Branch (402:9): [True: 372k, False: 2.72k]
  |  Branch (402:28): [True: 372k, False: 0]
  |  Branch (402:53): [True: 0, False: 0]
  ------------------
  403|   372k|        goto cont;
  404|       |
  405|  2.72k|    if (!mp_subfilter_drain_destroy(&p->sub))
  ------------------
  |  Branch (405:9): [True: 0, False: 2.72k]
  ------------------
  406|      0|        return;
  407|       |
  408|  2.72k|    if (format_change && p->public.on_audio_format_change) {
  ------------------
  |  Branch (408:9): [True: 2.72k, False: 0]
  |  Branch (408:26): [True: 2.72k, False: 0]
  ------------------
  409|  2.72k|        if (p->format_change_blocked)
  ------------------
  |  Branch (409:13): [True: 0, False: 2.72k]
  ------------------
  410|      0|            return;
  411|       |
  412|  2.72k|        if (!p->format_change_cont) {
  ------------------
  |  Branch (412:13): [True: 1.36k, False: 1.36k]
  ------------------
  413|  1.36k|            p->format_change_blocked = true;
  414|  1.36k|            p->public.
  415|  1.36k|                on_audio_format_change(p->public.on_audio_format_change_opaque);
  416|  1.36k|            return;
  417|  1.36k|        }
  418|  1.36k|        p->format_change_cont = false;
  419|  1.36k|    }
  420|       |
  421|  1.36k|    p->in_afmt = afmt;
  422|  1.36k|    p->in_srate = srate;
  423|  1.36k|    p->in_chmap = chmap;
  424|  1.36k|    p->force_update = false;
  425|       |
  426|  1.36k|    int out_afmt = 0;
  427|  1.36k|    int best_score = 0;
  428|  2.72k|    for (int n = 0; n < p->num_afmts; n++) {
  ------------------
  |  Branch (428:21): [True: 1.36k, False: 1.36k]
  ------------------
  429|  1.36k|        int score = af_format_conversion_score(p->afmts[n], afmt);
  430|  1.36k|        if (!out_afmt || score > best_score) {
  ------------------
  |  Branch (430:13): [True: 1.36k, False: 0]
  |  Branch (430:26): [True: 0, False: 0]
  ------------------
  431|  1.36k|            best_score = score;
  432|  1.36k|            out_afmt = p->afmts[n];
  433|  1.36k|        }
  434|  1.36k|    }
  435|  1.36k|    if (!out_afmt)
  ------------------
  |  Branch (435:9): [True: 0, False: 1.36k]
  ------------------
  436|      0|        out_afmt = afmt;
  437|       |
  438|       |    // (The p->srates array is 0-terminated already.)
  439|  1.36k|    int out_srate = af_select_best_samplerate(srate, p->srates);
  440|  1.36k|    if (out_srate <= 0)
  ------------------
  |  Branch (440:9): [True: 0, False: 1.36k]
  ------------------
  441|      0|        out_srate = p->num_srates ? p->srates[0] : srate;
  ------------------
  |  Branch (441:21): [True: 0, False: 0]
  ------------------
  442|       |
  443|  1.36k|    struct mp_chmap out_chmap = chmap;
  444|  1.36k|    if (p->chmaps.num_chmaps) {
  ------------------
  |  Branch (444:9): [True: 1.36k, False: 0]
  ------------------
  445|  1.36k|        if (!mp_chmap_sel_adjust(&p->chmaps, &out_chmap))
  ------------------
  |  Branch (445:13): [True: 0, False: 1.36k]
  ------------------
  446|      0|            out_chmap = p->chmaps.chmaps[0]; // violently force fallback
  447|  1.36k|    }
  448|       |
  449|  1.36k|    if (out_afmt == p->in_afmt && out_srate == p->in_srate &&
  ------------------
  |  Branch (449:9): [True: 1.36k, False: 0]
  |  Branch (449:35): [True: 1.36k, False: 0]
  ------------------
  450|  1.36k|        mp_chmap_equals(&out_chmap, &p->in_chmap) && !p->resampling_forced)
  ------------------
  |  Branch (450:9): [True: 1.36k, False: 0]
  |  Branch (450:54): [True: 1.36k, False: 0]
  ------------------
  451|  1.36k|    {
  452|  1.36k|        goto cont;
  453|  1.36k|    }
  454|       |
  455|      0|    MP_VERBOSE(p, "inserting resampler\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  456|       |
  457|      0|    struct mp_swresample *s = mp_swresample_create(f, NULL);
  458|      0|    if (!s)
  ------------------
  |  Branch (458:9): [True: 0, False: 0]
  ------------------
  459|      0|        abort();
  460|       |
  461|      0|    s->out_format = out_afmt;
  462|      0|    s->out_rate = out_srate;
  463|      0|    s->out_channels = out_chmap;
  464|       |
  465|      0|    p->sub.filter = s->f;
  466|       |
  467|   373k|cont:
  468|       |
  469|   373k|    if (p->sub.filter) {
  ------------------
  |  Branch (469:9): [True: 0, False: 373k]
  ------------------
  470|      0|        struct mp_filter_command cmd = {
  471|      0|            .type = MP_FILTER_COMMAND_SET_SPEED_RESAMPLE,
  472|      0|            .speed = p->audio_speed,
  473|      0|        };
  474|      0|        mp_filter_command(p->sub.filter, &cmd);
  475|      0|    }
  476|       |
  477|   373k|    mp_subfilter_continue(&p->sub);
  478|   373k|}
f_autoconvert.c:autoconvert_command:
  512|   454k|{
  513|   454k|    struct priv *p = f->priv;
  514|       |
  515|   454k|    if (cmd->type == MP_FILTER_COMMAND_SET_SPEED_RESAMPLE) {
  ------------------
  |  Branch (515:9): [True: 1.82k, False: 453k]
  ------------------
  516|  1.82k|        p->audio_speed = cmd->speed;
  517|       |        // If we needed resampling once, keep forcing resampling, as it might be
  518|       |        // quickly changing between 1.0 and other values for A/V compensation.
  519|  1.82k|        if (p->audio_speed != 1.0)
  ------------------
  |  Branch (519:13): [True: 0, False: 1.82k]
  ------------------
  520|      0|            p->resampling_forced = true;
  521|  1.82k|        return true;
  522|  1.82k|    }
  523|       |
  524|   453k|    if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
  ------------------
  |  Branch (524:9): [True: 449k, False: 3.64k]
  ------------------
  525|   449k|        cmd->is_active = !!p->sub.filter;
  526|   449k|        return true;
  527|   449k|    }
  528|       |
  529|  3.64k|    return false;
  530|   453k|}

mp_decoder_wrapper_control:
  348|  3.54k|{
  349|  3.54k|    struct priv *p = d->f->priv;
  350|  3.54k|    int res = CONTROL_UNKNOWN;
  ------------------
  |  |   71|  3.54k|#define CONTROL_UNKNOWN -1
  ------------------
  351|  3.54k|    thread_lock(p);
  352|  3.54k|    if (cmd == VDCTRL_GET_HWDEC) {
  ------------------
  |  Branch (352:9): [True: 0, False: 3.54k]
  ------------------
  353|      0|        res = update_cached_values(p);
  354|      0|        mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  355|      0|        *(char **)arg = p->cur_hwdec;
  356|      0|        mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  357|  3.54k|    } else {
  358|  3.54k|        if (p->decoder && p->decoder->control)
  ------------------
  |  Branch (358:13): [True: 3.54k, False: 0]
  |  Branch (358:27): [True: 3.54k, False: 0]
  ------------------
  359|  3.54k|            res = p->decoder->control(p->decoder->f, cmd, arg);
  360|  3.54k|        update_cached_values(p);
  361|  3.54k|    }
  362|  3.54k|    thread_unlock(p);
  363|  3.54k|    return res;
  364|  3.54k|}
mp_decoder_wrapper_reinit:
  487|  4.88k|{
  488|  4.88k|    struct priv *p = d->f->priv;
  489|  4.88k|    thread_lock(p);
  490|  4.88k|    bool res = reinit_decoder(p);
  491|  4.88k|    thread_unlock(p);
  492|  4.88k|    return res;
  493|  4.88k|}
mp_decoder_wrapper_get_container_fps:
  513|  2.02k|{
  514|  2.02k|    struct priv *p = d->f->priv;
  515|  2.02k|    thread_lock(p);
  516|  2.02k|    double res = p->fps;
  517|  2.02k|    thread_unlock(p);
  518|  2.02k|    return res;
  519|  2.02k|}
mp_decoder_wrapper_set_spdif_flag:
  522|  1.95k|{
  523|  1.95k|    struct priv *p = d->f->priv;
  524|  1.95k|    mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|  1.95k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  525|  1.95k|    p->try_spdif = spdif;
  526|  1.95k|    mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|  1.95k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  527|  1.95k|}
mp_decoder_wrapper_get_pts_reset:
  538|  3.43k|{
  539|  3.43k|    struct priv *p = d->f->priv;
  540|  3.43k|    mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|  3.43k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  541|  3.43k|    bool res = p->pts_reset;
  542|  3.43k|    mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|  3.43k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  543|  3.43k|    return res;
  544|  3.43k|}
mp_decoder_wrapper_set_play_dir:
  547|  6.77k|{
  548|  6.77k|    struct priv *p = d->f->priv;
  549|  6.77k|    thread_lock(p);
  550|  6.77k|    p->play_dir = dir;
  551|  6.77k|    thread_unlock(p);
  552|  6.77k|}
mp_decoder_wrapper_create:
 1206|  4.88k|{
 1207|  4.88k|    struct mp_filter *public_f = mp_filter_create(parent, &decode_wrapper_filter);
 1208|  4.88k|    if (!public_f)
  ------------------
  |  Branch (1208:9): [True: 0, False: 4.88k]
  ------------------
 1209|      0|        return NULL;
 1210|       |
 1211|  4.88k|    struct priv *p = public_f->priv;
 1212|  4.88k|    p->public.f = public_f;
 1213|       |
 1214|  4.88k|    mp_mutex_init(&p->cache_lock);
 1215|  4.88k|    p->opt_cache = m_config_cache_alloc(p, public_f->global, &dec_wrapper_conf);
 1216|  4.88k|    p->opts = p->opt_cache->opts;
 1217|  4.88k|    p->header = src;
 1218|  4.88k|    p->codec = p->header->codec;
 1219|  4.88k|    p->play_dir = 1;
 1220|  4.88k|    mp_filter_add_pin(public_f, MP_PIN_OUT, "out");
 1221|       |
 1222|  4.88k|    if (p->header->type == STREAM_VIDEO) {
  ------------------
  |  Branch (1222:9): [True: 2.93k, False: 1.95k]
  ------------------
 1223|  2.93k|        p->log = mp_log_new(p, parent->global->log, "!vd");
 1224|       |
 1225|  2.93k|        p->fps = src->codec->fps;
 1226|       |
 1227|  2.93k|        MP_VERBOSE(p, "Container reported FPS: %f\n", p->fps);
  ------------------
  |  |   88|  2.93k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.93k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1228|       |
 1229|  2.93k|        if (p->opts->fps_override) {
  ------------------
  |  Branch (1229:13): [True: 0, False: 2.93k]
  ------------------
 1230|      0|            p->fps = p->opts->fps_override;
 1231|      0|            MP_INFO(p, "Container FPS forced to %5.3f.\n", p->fps);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1232|      0|            MP_INFO(p, "Use --no-correct-pts to force FPS based timing.\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1233|      0|        }
 1234|       |
 1235|  2.93k|        p->queue_opts = p->opts->vdec_queue_opts;
 1236|  2.93k|    } else if (p->header->type == STREAM_AUDIO) {
  ------------------
  |  Branch (1236:16): [True: 1.95k, False: 0]
  ------------------
 1237|  1.95k|        p->log = mp_log_new(p, parent->global->log, "!ad");
 1238|  1.95k|        p->queue_opts = p->opts->adec_queue_opts;
 1239|  1.95k|    } else {
 1240|      0|        goto error;
 1241|      0|    }
 1242|       |
 1243|  4.88k|    if (p->queue_opts && p->queue_opts->use_queue) {
  ------------------
  |  Branch (1243:9): [True: 4.88k, False: 0]
  |  Branch (1243:26): [True: 0, False: 4.88k]
  ------------------
 1244|      0|        p->queue = mp_async_queue_create();
 1245|      0|        p->dec_dispatch = mp_dispatch_create(p);
 1246|      0|        p->dec_root_filter = mp_filter_create_root(public_f->global);
 1247|      0|        mp_filter_graph_set_wakeup_cb(p->dec_root_filter, wakeup_dec_thread, p);
 1248|      0|        mp_dispatch_set_onlock_fn(p->dec_dispatch, onlock_dec_thread, p);
 1249|       |
 1250|      0|        struct mp_stream_info *sinfo = mp_filter_find_stream_info(parent);
 1251|      0|        if (sinfo) {
  ------------------
  |  Branch (1251:13): [True: 0, False: 0]
  ------------------
 1252|      0|            p->dec_root_filter->stream_info = &p->stream_info;
 1253|      0|            p->stream_info = (struct mp_stream_info){
 1254|      0|                .dr_vo = sinfo->dr_vo,
 1255|      0|                .hwdec_devs = sinfo->hwdec_devs,
 1256|      0|            };
 1257|      0|        }
 1258|       |
 1259|      0|        update_queue_config(p);
 1260|      0|    }
 1261|       |
 1262|  4.88k|    p->decf = mp_filter_create(p->dec_root_filter ? p->dec_root_filter : public_f,
  ------------------
  |  Branch (1262:32): [True: 0, False: 4.88k]
  ------------------
 1263|  4.88k|                               &decf_filter);
 1264|  4.88k|    if (!p->decf)
  ------------------
  |  Branch (1264:9): [True: 0, False: 4.88k]
  ------------------
 1265|      0|        goto error;
 1266|  4.88k|    p->decf->priv = p;
 1267|  4.88k|    p->decf->log = public_f->log = p->log;
 1268|  4.88k|    mp_filter_add_pin(p->decf, MP_PIN_OUT, "out");
 1269|       |
 1270|  4.88k|    struct mp_filter *demux = mp_demux_in_create(p->decf, p->header);
 1271|  4.88k|    if (!demux)
  ------------------
  |  Branch (1271:9): [True: 0, False: 4.88k]
  ------------------
 1272|      0|        goto error;
 1273|  4.88k|    p->demux = demux->pins[0];
 1274|       |
 1275|  4.88k|    decf_reset(p->decf);
 1276|       |
 1277|  4.88k|    if (p->queue) {
  ------------------
  |  Branch (1277:9): [True: 0, False: 4.88k]
  ------------------
 1278|      0|        struct mp_filter *f_in =
 1279|      0|            mp_async_queue_create_filter(public_f, MP_PIN_OUT, p->queue);
 1280|      0|        struct mp_filter *f_out =
 1281|      0|            mp_async_queue_create_filter(p->decf, MP_PIN_IN, p->queue);
 1282|      0|        mp_pin_connect(public_f->ppins[0], f_in->pins[0]);
 1283|      0|        mp_pin_connect(f_out->pins[0], p->decf->pins[0]);
 1284|       |
 1285|      0|        p->dec_thread_valid = true;
 1286|      0|        if (mp_thread_create(&p->dec_thread, dec_thread, p)) {
  ------------------
  |  |  211|      0|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1287|      0|            p->dec_thread_valid = false;
 1288|      0|            goto error;
 1289|      0|        }
 1290|  4.88k|    } else {
 1291|  4.88k|        mp_pin_connect(public_f->ppins[0], p->decf->pins[0]);
 1292|  4.88k|    }
 1293|       |
 1294|  4.88k|    public_f_reset(public_f);
 1295|       |
 1296|  4.88k|    return &p->public;
 1297|      0|error:
 1298|      0|    talloc_free(public_f);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1299|      0|    return NULL;
 1300|  4.88k|}
lavc_process:
 1305|  3.32M|{
 1306|  3.32M|    if (!mp_pin_in_needs_data(f->ppins[1]))
  ------------------
  |  Branch (1306:9): [True: 9.38k, False: 3.31M]
  ------------------
 1307|  9.38k|        return;
 1308|       |
 1309|  3.31M|    struct mp_frame frame = {0};
 1310|  3.31M|    int ret_recv = receive(f, &frame);
 1311|  3.31M|    if (frame.type) {
  ------------------
  |  Branch (1311:9): [True: 445k, False: 2.87M]
  ------------------
 1312|   445k|        state->eof_returned = false;
 1313|   445k|        mp_pin_in_write(f->ppins[1], frame);
 1314|  2.87M|    } else if (ret_recv == AVERROR_EOF) {
  ------------------
  |  Branch (1314:16): [True: 8.71k, False: 2.86M]
  ------------------
 1315|  8.71k|        if (!state->eof_returned)
  ------------------
  |  Branch (1315:13): [True: 8.71k, False: 0]
  ------------------
 1316|  8.71k|            mp_pin_in_write(f->ppins[1], MP_EOF_FRAME);
  ------------------
  |  |   59|  8.71k|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|  8.71k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
 1317|  8.71k|        state->eof_returned = true;
 1318|  8.71k|        state->packets_sent = false;
 1319|  2.86M|    } else if (ret_recv == AVERROR(EAGAIN)) {
  ------------------
  |  Branch (1319:16): [True: 2.85M, False: 9.72k]
  ------------------
 1320|       |        // Need to feed a packet.
 1321|  2.85M|        frame = mp_pin_out_read(f->ppins[0]);
 1322|  2.85M|        struct demux_packet *pkt = NULL;
 1323|  2.85M|        if (frame.type == MP_FRAME_PACKET) {
  ------------------
  |  Branch (1323:13): [True: 1.41M, False: 1.43M]
  ------------------
 1324|  1.41M|            pkt = frame.data;
 1325|  1.43M|        } else if (frame.type != MP_FRAME_EOF) {
  ------------------
  |  Branch (1325:20): [True: 1.42M, False: 10.1k]
  ------------------
 1326|  1.42M|            if (frame.type) {
  ------------------
  |  Branch (1326:17): [True: 0, False: 1.42M]
  ------------------
 1327|      0|                MP_ERR(f, "unexpected frame type\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1328|      0|                mp_frame_unref(&frame);
 1329|      0|                mp_filter_internal_mark_failed(f);
 1330|      0|            }
 1331|  1.42M|            return;
 1332|  1.42M|        } else if (!state->packets_sent) {
  ------------------
  |  Branch (1332:20): [True: 1.45k, False: 8.71k]
  ------------------
 1333|       |            // EOF only; just return it, without requiring send/receive to
 1334|       |            // pass it through properly.
 1335|  1.45k|            mp_pin_in_write(f->ppins[1], MP_EOF_FRAME);
  ------------------
  |  |   59|  1.45k|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|  1.45k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
 1336|  1.45k|            return;
 1337|  1.45k|        }
 1338|  1.42M|        int ret_send = send(f, pkt);
 1339|  1.42M|        if (ret_send == AVERROR(EAGAIN)) {
  ------------------
  |  Branch (1339:13): [True: 0, False: 1.42M]
  ------------------
 1340|       |            // Should never happen, but can happen with broken decoders.
 1341|      0|            MP_WARN(f, "could not consume packet\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1342|      0|            mp_pin_out_unread(f->ppins[0], frame);
 1343|      0|            mp_filter_wakeup(f);
 1344|      0|            return;
 1345|      0|        }
 1346|  1.42M|        state->packets_sent = true;
 1347|  1.42M|        demux_packet_pool_push(f->packet_pool, pkt);
 1348|  1.42M|        mp_filter_internal_mark_progress(f);
 1349|  1.42M|    } else {
 1350|       |        // Decoding error, or hwdec fallback recovery. Just try again.
 1351|  9.72k|        mp_filter_internal_mark_progress(f);
 1352|  9.72k|    }
 1353|  3.31M|}
f_decoder_wrapper.c:thread_lock:
  278|  17.2k|{
  279|  17.2k|    if (p->dec_dispatch)
  ------------------
  |  Branch (279:9): [True: 0, False: 17.2k]
  ------------------
  280|      0|        mp_dispatch_lock(p->dec_dispatch);
  281|       |
  282|  17.2k|    mp_assert(!p->dec_thread_lock);
  ------------------
  |  |   41|  17.2k|#define mp_assert assert
  ------------------
  283|  17.2k|    p->dec_thread_lock = true;
  284|  17.2k|}
f_decoder_wrapper.c:update_cached_values:
  261|  13.9k|{
  262|  13.9k|    int res = CONTROL_UNKNOWN;
  ------------------
  |  |   71|  13.9k|#define CONTROL_UNKNOWN -1
  ------------------
  263|  13.9k|    mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|  13.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  264|       |
  265|  13.9k|    p->cur_hwdec = NULL;
  266|  13.9k|    if (p->decoder && p->decoder->control)
  ------------------
  |  Branch (266:9): [True: 12.9k, False: 1.04k]
  |  Branch (266:23): [True: 11.1k, False: 1.81k]
  ------------------
  267|  11.1k|        res = p->decoder->control(p->decoder->f, VDCTRL_GET_HWDEC, &p->cur_hwdec);
  268|       |
  269|  13.9k|    mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|  13.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  270|  13.9k|    return res;
  271|  13.9k|}
f_decoder_wrapper.c:thread_unlock:
  288|  17.2k|{
  289|  17.2k|    mp_assert(p->dec_thread_lock);
  ------------------
  |  |   41|  17.2k|#define mp_assert assert
  ------------------
  290|  17.2k|    p->dec_thread_lock = false;
  291|       |
  292|  17.2k|    if (p->dec_dispatch)
  ------------------
  |  Branch (292:9): [True: 0, False: 17.2k]
  ------------------
  293|      0|        mp_dispatch_unlock(p->dec_dispatch);
  294|  17.2k|}
f_decoder_wrapper.c:reinit_decoder:
  398|  10.4k|{
  399|  10.4k|    if (p->decoder)
  ------------------
  |  Branch (399:9): [True: 5.53k, False: 4.88k]
  ------------------
  400|  5.53k|        talloc_free(p->decoder->f);
  ------------------
  |  |   47|  5.53k|#define talloc_free                     ta_free
  ------------------
  401|  10.4k|    p->decoder = NULL;
  402|       |
  403|  10.4k|    reset_decoder(p);
  404|  10.4k|    p->has_broken_packet_pts = -10; // needs 10 packets to reach decision
  405|       |
  406|  10.4k|    const struct mp_decoder_fns *driver = NULL;
  407|  10.4k|    struct mp_decoder_list *list = NULL;
  408|  10.4k|    char *user_list = NULL;
  409|  10.4k|    char *fallback = NULL;
  410|       |
  411|  10.4k|    if (p->codec->type == STREAM_VIDEO) {
  ------------------
  |  Branch (411:9): [True: 8.46k, False: 1.95k]
  ------------------
  412|  8.46k|        driver = &vd_lavc;
  413|  8.46k|        user_list = p->opts->video_decoders;
  414|  8.46k|        fallback = "h264";
  415|  8.46k|    } else if (p->codec->type == STREAM_AUDIO) {
  ------------------
  |  Branch (415:16): [True: 1.95k, False: 0]
  ------------------
  416|  1.95k|        driver = &ad_lavc;
  417|  1.95k|        user_list = p->opts->audio_decoders;
  418|  1.95k|        fallback = "aac";
  419|       |
  420|  1.95k|        mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|  1.95k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  421|  1.95k|        bool try_spdif = p->try_spdif;
  422|  1.95k|        mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|  1.95k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  423|       |
  424|  1.95k|        if (try_spdif && p->codec->codec) {
  ------------------
  |  Branch (424:13): [True: 1.95k, False: 0]
  |  Branch (424:26): [True: 1.95k, False: 0]
  ------------------
  425|  1.95k|            struct mp_decoder_list *spdif =
  426|  1.95k|                select_spdif_codec(p->codec->codec, p->opts->audio_spdif);
  427|  1.95k|            if (spdif->num_entries) {
  ------------------
  |  Branch (427:17): [True: 0, False: 1.95k]
  ------------------
  428|      0|                driver = &ad_spdif;
  429|      0|                list = spdif;
  430|  1.95k|            } else {
  431|  1.95k|                talloc_free(spdif);
  ------------------
  |  |   47|  1.95k|#define talloc_free                     ta_free
  ------------------
  432|  1.95k|            }
  433|  1.95k|        }
  434|  1.95k|    }
  435|       |
  436|  10.4k|    if (!driver)
  ------------------
  |  Branch (436:9): [True: 0, False: 10.4k]
  ------------------
  437|      0|        return false;
  438|       |
  439|  10.4k|    if (!list) {
  ------------------
  |  Branch (439:9): [True: 10.4k, False: 0]
  ------------------
  440|  10.4k|        struct mp_decoder_list *full = talloc_zero(NULL, struct mp_decoder_list);
  ------------------
  |  |   27|  10.4k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  10.4k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  10.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  441|  10.4k|        driver->add_decoders(full);
  442|  10.4k|        const char *codec = p->codec->codec;
  443|  10.4k|        if (codec && strcmp(codec, "null") == 0)
  ------------------
  |  Branch (443:13): [True: 10.4k, False: 0]
  |  Branch (443:22): [True: 0, False: 10.4k]
  ------------------
  444|      0|            codec = fallback;
  445|  10.4k|        list = mp_select_decoders(p->log, full, codec, user_list);
  446|  10.4k|        talloc_free(full);
  ------------------
  |  |   47|  10.4k|#define talloc_free                     ta_free
  ------------------
  447|  10.4k|    }
  448|       |
  449|  10.4k|    mp_print_decoders(p->log, MSGL_V, "Codec list:", list);
  450|       |
  451|  10.5k|    for (int n = 0; n < list->num_entries; n++) {
  ------------------
  |  Branch (451:21): [True: 9.53k, False: 1.04k]
  ------------------
  452|  9.53k|        struct mp_decoder_entry *sel = &list->entries[n];
  453|  9.53k|        MP_VERBOSE(p, "Opening decoder %s\n", sel->decoder);
  ------------------
  |  |   88|  9.53k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.53k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  454|       |
  455|  9.53k|        p->decoder = driver->create(p->decf, p->codec, sel->decoder);
  456|  9.53k|        if (p->decoder) {
  ------------------
  |  Branch (456:13): [True: 9.38k, False: 150]
  ------------------
  457|  9.38k|            p->codec->decoder = talloc_strdup(p, sel->decoder);
  ------------------
  |  |   50|  9.38k|#define talloc_strdup                   ta_xstrdup
  ------------------
  458|  9.38k|            p->codec->decoder_desc = talloc_strdup(p, sel->desc && sel->desc[0] ? sel->desc : NULL);
  ------------------
  |  |   50|  9.38k|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (458:55): [True: 9.38k, False: 0]
  |  Branch (458:68): [True: 9.38k, False: 0]
  ------------------
  459|  9.38k|            MP_VERBOSE(p, "Selected decoder: %s", sel->decoder);
  ------------------
  |  |   88|  9.38k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.38k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  460|  9.38k|            if (p->codec->decoder_desc)
  ------------------
  |  Branch (460:17): [True: 9.38k, False: 0]
  ------------------
  461|  9.38k|                MP_VERBOSE(p, " - %s", p->codec->decoder_desc);
  ------------------
  |  |   88|  9.38k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.38k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  462|  9.38k|            MP_VERBOSE(p, "\n");
  ------------------
  |  |   88|  9.38k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.38k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  463|  9.38k|            break;
  464|  9.38k|        }
  465|       |
  466|    150|        MP_WARN(p, "Decoder init failed for %s\n", sel->decoder);
  ------------------
  |  |   86|    150|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    150|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  467|    150|    }
  468|       |
  469|  10.4k|    if (!p->decoder) {
  ------------------
  |  Branch (469:9): [True: 1.04k, False: 9.38k]
  ------------------
  470|  1.04k|        MP_ERR(p, "Failed to initialize a decoder for codec '%s'.\n",
  ------------------
  |  |   85|  1.04k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.08k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 1.04k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  471|  1.04k|               p->codec->codec ? p->codec->codec : "<?>");
  472|  1.04k|    }
  473|       |
  474|  10.4k|    update_cached_values(p);
  475|       |
  476|  10.4k|    talloc_free(list);
  ------------------
  |  |   47|  10.4k|#define talloc_free                     ta_free
  ------------------
  477|  10.4k|    return !!p->decoder;
  478|  10.4k|}
f_decoder_wrapper.c:reset_decoder:
  301|  26.5k|{
  302|  26.5k|    p->first_packet_pdts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  26.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  303|  26.5k|    p->start_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  26.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  304|  26.5k|    p->codec_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  26.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  305|  26.5k|    p->codec_dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  26.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  306|  26.5k|    p->num_codec_pts_problems = 0;
  307|  26.5k|    p->num_codec_dts_problems = 0;
  308|  26.5k|    p->has_broken_decoded_pts = 0;
  309|  26.5k|    p->packets_without_output = 0;
  310|  26.5k|    mp_frame_unref(&p->packet);
  311|  26.5k|    p->packet_fed = false;
  312|  26.5k|    p->preroll_discard = false;
  313|  26.5k|    talloc_free(p->new_segment);
  ------------------
  |  |   47|  26.5k|#define talloc_free                     ta_free
  ------------------
  314|  26.5k|    p->new_segment = NULL;
  315|  26.5k|    p->start = p->end = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  26.5k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  316|       |
  317|  26.5k|    if (p->decoder)
  ------------------
  |  Branch (317:9): [True: 6.33k, False: 20.1k]
  ------------------
  318|  6.33k|        mp_filter_reset(p->decoder->f);
  319|  26.5k|}
f_decoder_wrapper.c:public_f_destroy:
 1155|  4.88k|{
 1156|  4.88k|    struct priv *p = f->priv;
 1157|  4.88k|    mp_assert(p->public.f == f);
  ------------------
  |  |   41|  4.88k|#define mp_assert assert
  ------------------
 1158|       |
 1159|  4.88k|    if (p->dec_thread_valid) {
  ------------------
  |  Branch (1159:9): [True: 0, False: 4.88k]
  ------------------
 1160|      0|        mp_assert(p->dec_dispatch);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1161|      0|        thread_lock(p);
 1162|      0|        p->request_terminate_dec_thread = 1;
 1163|      0|        mp_dispatch_interrupt(p->dec_dispatch);
 1164|      0|        thread_unlock(p);
 1165|      0|        mp_thread_join(p->dec_thread);
  ------------------
  |  |  212|      0|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
 1166|      0|        p->dec_thread_valid = false;
 1167|      0|    }
 1168|       |
 1169|  4.88k|    mp_filter_free_children(f);
 1170|       |
 1171|  4.88k|    talloc_free(p->dec_root_filter);
  ------------------
  |  |   47|  4.88k|#define talloc_free                     ta_free
  ------------------
 1172|  4.88k|    talloc_free(p->queue);
  ------------------
  |  |   47|  4.88k|#define talloc_free                     ta_free
  ------------------
 1173|  4.88k|    mp_mutex_destroy(&p->cache_lock);
  ------------------
  |  |  130|  4.88k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
 1174|  4.88k|}
f_decoder_wrapper.c:decf_destroy:
  367|  4.88k|{
  368|  4.88k|    struct priv *p = f->priv;
  369|  4.88k|    mp_assert(p->decf == f);
  ------------------
  |  |   41|  4.88k|#define mp_assert assert
  ------------------
  370|       |
  371|  4.88k|    if (p->decoder) {
  ------------------
  |  Branch (371:9): [True: 3.84k, False: 1.04k]
  ------------------
  372|  3.84k|        MP_DBG(f, "Uninit decoder.\n");
  ------------------
  |  |   89|  3.84k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.84k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  373|  3.84k|        talloc_free(p->decoder->f);
  ------------------
  |  |   47|  3.84k|#define talloc_free                     ta_free
  ------------------
  374|  3.84k|        p->decoder = NULL;
  375|  3.84k|        p->codec->decoder = NULL;
  376|  3.84k|        p->codec->decoder_desc = NULL;
  377|  3.84k|    }
  378|       |
  379|  4.88k|    decf_reset(f);
  380|  4.88k|    mp_frame_unref(&p->decoded_coverart);
  381|  4.88k|}
f_decoder_wrapper.c:decf_process:
 1108|  3.76M|{
 1109|  3.76M|    struct priv *p = f->priv;
 1110|  3.76M|    mp_assert(p->decf == f);
  ------------------
  |  |   41|  3.76M|#define mp_assert assert
  ------------------
 1111|       |
 1112|  3.76M|    if (m_config_cache_update(p->opt_cache))
  ------------------
  |  Branch (1112:9): [True: 0, False: 3.76M]
  ------------------
 1113|      0|        update_queue_config(p);
 1114|       |
 1115|  3.76M|    feed_packet(p);
 1116|  3.76M|    read_frame(p);
 1117|  3.76M|}
f_decoder_wrapper.c:feed_packet:
  881|  3.76M|{
  882|  3.76M|    if (!p->decoder || !mp_pin_in_needs_data(p->decoder->f->pins[0]))
  ------------------
  |  Branch (882:9): [True: 0, False: 3.76M]
  |  Branch (882:24): [True: 917k, False: 2.84M]
  ------------------
  883|   917k|        return;
  884|       |
  885|  2.84M|    if (p->decoded_coverart.type)
  ------------------
  |  Branch (885:9): [True: 0, False: 2.84M]
  ------------------
  886|      0|        return;
  887|       |
  888|  2.84M|    if (!p->packet.type && !p->new_segment) {
  ------------------
  |  Branch (888:9): [True: 2.84M, False: 6.33k]
  |  Branch (888:28): [True: 2.84M, False: 0]
  ------------------
  889|  2.84M|        p->packet = mp_pin_out_read(p->demux);
  890|  2.84M|        if (!p->packet.type)
  ------------------
  |  Branch (890:13): [True: 1.42M, False: 1.42M]
  ------------------
  891|  1.42M|            return;
  892|  1.42M|        if (p->packet.type != MP_FRAME_EOF && p->packet.type != MP_FRAME_PACKET) {
  ------------------
  |  Branch (892:13): [True: 1.41M, False: 3.83k]
  |  Branch (892:47): [True: 0, False: 1.41M]
  ------------------
  893|      0|            MP_ERR(p, "invalid frame type from demuxer\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  894|      0|            mp_frame_unref(&p->packet);
  895|      0|            mp_filter_internal_mark_failed(p->decf);
  896|      0|            return;
  897|      0|        }
  898|  1.42M|    }
  899|       |
  900|  1.42M|    if (!p->packet.type)
  ------------------
  |  Branch (900:9): [True: 0, False: 1.42M]
  ------------------
  901|      0|        return;
  902|       |
  903|       |    // Flush current data if the packet is a new segment.
  904|  1.42M|    if (is_new_segment(p, p->packet)) {
  ------------------
  |  Branch (904:9): [True: 6.33k, False: 1.42M]
  ------------------
  905|  6.33k|        mp_assert(!p->new_segment);
  ------------------
  |  |   41|  6.33k|#define mp_assert assert
  ------------------
  906|  6.33k|        p->new_segment = p->packet.data;
  907|  6.33k|        p->packet = MP_EOF_FRAME;
  ------------------
  |  |   59|  6.33k|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|  6.33k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  908|  6.33k|    }
  909|       |
  910|  1.42M|    mp_assert(p->packet.type == MP_FRAME_PACKET || p->packet.type == MP_FRAME_EOF);
  ------------------
  |  |   41|  1.42M|#define mp_assert assert
  ------------------
  911|  1.42M|    struct demux_packet *packet =
  912|  1.42M|        p->packet.type == MP_FRAME_PACKET ? p->packet.data : NULL;
  ------------------
  |  Branch (912:9): [True: 1.41M, False: 10.1k]
  ------------------
  913|       |
  914|       |    // For video framedropping, including parts of the hr-seek logic.
  915|  1.42M|    if (p->decoder->control) {
  ------------------
  |  Branch (915:9): [True: 285k, False: 1.14M]
  ------------------
  916|   285k|        double start_pts = p->start_pts;
  917|   285k|        if (p->start != MP_NOPTS_VALUE && (start_pts == MP_NOPTS_VALUE ||
  ------------------
  |  |   38|   570k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                      if (p->start != MP_NOPTS_VALUE && (start_pts == MP_NOPTS_VALUE ||
  ------------------
  |  |   38|  25.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (917:13): [True: 12.6k, False: 272k]
  |  Branch (917:44): [True: 12.6k, False: 0]
  ------------------
  918|  12.6k|                                           p->start > start_pts))
  ------------------
  |  Branch (918:44): [True: 0, False: 0]
  ------------------
  919|  12.6k|            start_pts = p->start;
  920|       |
  921|   285k|        int framedrop_type = 0;
  922|       |
  923|   285k|        mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|   285k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  924|   285k|        if (p->attempt_framedrops)
  ------------------
  |  Branch (924:13): [True: 0, False: 285k]
  ------------------
  925|      0|            framedrop_type = 1;
  926|   285k|        mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|   285k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  927|       |
  928|   285k|        if (start_pts != MP_NOPTS_VALUE && packet && p->play_dir > 0 &&
  ------------------
  |  |   38|   570k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (928:13): [True: 12.6k, False: 272k]
  |  Branch (928:44): [True: 6.33k, False: 6.33k]
  |  Branch (928:54): [True: 6.33k, False: 0]
  ------------------
  929|   285k|            packet->pts < start_pts - .005 && !p->has_broken_packet_pts)
  ------------------
  |  Branch (929:13): [True: 4.12k, False: 2.21k]
  |  Branch (929:47): [True: 0, False: 4.12k]
  ------------------
  930|      0|            framedrop_type = 2;
  931|       |
  932|   285k|        p->decoder->control(p->decoder->f, VDCTRL_SET_FRAMEDROP, &framedrop_type);
  933|   285k|    }
  934|       |
  935|  1.42M|    if (!p->dec_dispatch && p->public.recorder_sink)
  ------------------
  |  Branch (935:9): [True: 1.42M, False: 0]
  |  Branch (935:29): [True: 0, False: 1.42M]
  ------------------
  936|      0|        mp_recorder_feed_packet(p->public.recorder_sink, packet);
  937|       |
  938|  1.42M|    double pkt_pts = packet ? packet->pts : MP_NOPTS_VALUE;
  ------------------
  |  |   38|  10.1k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (938:22): [True: 1.41M, False: 10.1k]
  ------------------
  939|  1.42M|    double pkt_dts = packet ? packet->dts : MP_NOPTS_VALUE;
  ------------------
  |  |   38|  10.1k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (939:22): [True: 1.41M, False: 10.1k]
  ------------------
  940|       |
  941|  1.42M|    if (pkt_pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (941:9): [True: 20.3k, False: 1.40M]
  ------------------
  942|  20.3k|        p->has_broken_packet_pts = 1;
  943|       |
  944|  1.42M|    if (packet && packet->dts == MP_NOPTS_VALUE && !p->codec->avi_dts)
  ------------------
  |  |   38|  2.84M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (944:9): [True: 1.41M, False: 10.1k]
  |  Branch (944:19): [True: 10.3k, False: 1.40M]
  |  Branch (944:52): [True: 10.3k, False: 0]
  ------------------
  945|  10.3k|        packet->dts = packet->pts;
  946|       |
  947|  1.42M|    double pkt_pdts = pkt_pts == MP_NOPTS_VALUE ? pkt_dts : pkt_pts;
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (947:23): [True: 20.3k, False: 1.40M]
  ------------------
  948|  1.42M|    if (p->first_packet_pdts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.42M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (948:9): [True: 20.2k, False: 1.40M]
  ------------------
  949|  20.2k|        p->first_packet_pdts = pkt_pdts;
  950|       |
  951|  1.42M|    if (packet && packet->back_preroll) {
  ------------------
  |  Branch (951:9): [True: 1.41M, False: 10.1k]
  |  Branch (951:19): [True: 0, False: 1.41M]
  ------------------
  952|      0|        p->preroll_discard = true;
  953|      0|        packet->pts = packet->dts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  954|      0|    }
  955|       |
  956|  1.42M|    mp_pin_in_write(p->decoder->f->pins[0], p->packet);
  957|  1.42M|    p->packet_fed = true;
  958|  1.42M|    p->packet = MP_NO_FRAME;
  ------------------
  |  |   58|  1.42M|#define MP_NO_FRAME MAKE_FRAME(0, 0)
  |  |  ------------------
  |  |  |  |   57|  1.42M|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  959|       |
  960|  1.42M|    p->packets_without_output += 1;
  961|  1.42M|}
f_decoder_wrapper.c:is_new_segment:
  871|  1.42M|{
  872|  1.42M|    if (frame.type != MP_FRAME_PACKET)
  ------------------
  |  Branch (872:9): [True: 3.83k, False: 1.42M]
  ------------------
  873|  3.83k|        return false;
  874|  1.42M|    struct demux_packet *pkt = frame.data;
  875|  1.42M|    return (pkt->segmented && (pkt->start != p->start || pkt->end != p->end ||
  ------------------
  |  Branch (875:13): [True: 12.6k, False: 1.40M]
  |  Branch (875:32): [True: 6.33k, False: 6.35k]
  |  Branch (875:58): [True: 0, False: 6.35k]
  ------------------
  876|  12.6k|                               pkt->codec != p->codec)) ||
  ------------------
  |  Branch (876:32): [True: 0, False: 6.35k]
  ------------------
  877|  1.42M|           (p->play_dir < 0 && pkt->back_restart && p->packet_fed);
  ------------------
  |  Branch (877:13): [True: 0, False: 1.41M]
  |  Branch (877:32): [True: 0, False: 0]
  |  Branch (877:53): [True: 0, False: 0]
  ------------------
  878|  1.42M|}
f_decoder_wrapper.c:read_frame:
  993|  3.76M|{
  994|  3.76M|    struct mp_pin *pin = p->decf->ppins[0];
  995|  3.76M|    struct mp_frame frame = {0};
  996|       |
  997|  3.76M|    if (!p->decoder || !mp_pin_in_needs_data(pin))
  ------------------
  |  Branch (997:9): [True: 0, False: 3.76M]
  |  Branch (997:24): [True: 3.84k, False: 3.76M]
  ------------------
  998|  3.84k|        return;
  999|       |
 1000|  3.76M|    if (p->decoded_coverart.type) {
  ------------------
  |  Branch (1000:9): [True: 0, False: 3.76M]
  ------------------
 1001|      0|        if (p->coverart_returned == 0) {
  ------------------
  |  Branch (1001:13): [True: 0, False: 0]
  ------------------
 1002|      0|            frame = mp_frame_ref(p->decoded_coverart);
 1003|      0|            p->coverart_returned = 1;
 1004|      0|            goto output_frame;
 1005|      0|        } else if (p->coverart_returned == 1) {
  ------------------
  |  Branch (1005:20): [True: 0, False: 0]
  ------------------
 1006|      0|            frame = MP_EOF_FRAME;
  ------------------
  |  |   59|      0|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|      0|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
 1007|      0|            p->coverart_returned = 2;
 1008|      0|            goto output_frame;
 1009|      0|        }
 1010|      0|        return;
 1011|      0|    }
 1012|       |
 1013|  3.76M|    if (p->reverse_queue_complete && p->num_reverse_queue) {
  ------------------
  |  Branch (1013:9): [True: 0, False: 3.76M]
  |  Branch (1013:38): [True: 0, False: 0]
  ------------------
 1014|      0|        frame = p->reverse_queue[p->num_reverse_queue - 1];
 1015|      0|        p->num_reverse_queue -= 1;
 1016|      0|        goto output_frame;
 1017|      0|    }
 1018|  3.76M|    p->reverse_queue_complete = false;
 1019|       |
 1020|  3.76M|    frame = mp_pin_out_read(p->decoder->f->pins[1]);
 1021|  3.76M|    if (!frame.type)
  ------------------
  |  Branch (1021:9): [True: 3.30M, False: 455k]
  ------------------
 1022|  3.30M|        return;
 1023|       |
 1024|   455k|    mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|   455k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1025|   455k|    if (p->attached_picture && frame.type == MP_FRAME_VIDEO)
  ------------------
  |  Branch (1025:9): [True: 0, False: 455k]
  |  Branch (1025:32): [True: 0, False: 0]
  ------------------
 1026|      0|        p->decoded_coverart = frame;
 1027|   455k|    if (p->attempt_framedrops) {
  ------------------
  |  Branch (1027:9): [True: 0, False: 455k]
  ------------------
 1028|      0|        int dropped = MPMAX(0, p->packets_without_output - 1);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1029|      0|        p->attempt_framedrops = MPMAX(0, p->attempt_framedrops - dropped);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1030|      0|        p->dropped_frames += dropped;
 1031|      0|    }
 1032|   455k|    mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|   455k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1033|       |
 1034|   455k|    if (p->decoded_coverart.type) {
  ------------------
  |  Branch (1034:9): [True: 0, False: 455k]
  ------------------
 1035|      0|        mp_filter_internal_mark_progress(p->decf);
 1036|      0|        return;
 1037|      0|    }
 1038|       |
 1039|   455k|    p->packets_without_output = 0;
 1040|       |
 1041|   455k|    if (p->preroll_discard && frame.type != MP_FRAME_EOF) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 455k]
  |  Branch (1041:31): [True: 0, False: 0]
  ------------------
 1042|      0|        double ts = mp_frame_get_pts(frame);
 1043|      0|        if (ts == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1043:13): [True: 0, False: 0]
  ------------------
 1044|      0|            mp_frame_unref(&frame);
 1045|      0|            mp_filter_internal_mark_progress(p->decf);
 1046|      0|            return;
 1047|      0|        }
 1048|      0|        p->preroll_discard = false;
 1049|      0|    }
 1050|       |
 1051|   455k|    bool segment_ended = process_decoded_frame(p, &frame);
 1052|       |
 1053|   455k|    if (p->play_dir < 0 && frame.type) {
  ------------------
  |  Branch (1053:9): [True: 0, False: 455k]
  |  Branch (1053:28): [True: 0, False: 0]
  ------------------
 1054|      0|        enqueue_backward_frame(p, frame);
 1055|      0|        frame = MP_NO_FRAME;
  ------------------
  |  |   58|      0|#define MP_NO_FRAME MAKE_FRAME(0, 0)
  |  |  ------------------
  |  |  |  |   57|      0|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
 1056|      0|    }
 1057|       |
 1058|       |    // If there's a new segment, start it as soon as we're drained/finished.
 1059|   455k|    if (segment_ended && p->new_segment) {
  ------------------
  |  Branch (1059:9): [True: 10.1k, False: 445k]
  |  Branch (1059:26): [True: 6.33k, False: 3.83k]
  ------------------
 1060|  6.33k|        struct demux_packet *new_segment = p->new_segment;
 1061|  6.33k|        p->new_segment = NULL;
 1062|       |
 1063|  6.33k|        reset_decoder(p);
 1064|       |
 1065|  6.33k|        if (new_segment->segmented) {
  ------------------
  |  Branch (1065:13): [True: 6.33k, False: 0]
  ------------------
 1066|  6.33k|            if (p->codec != new_segment->codec) {
  ------------------
  |  Branch (1066:17): [True: 5.53k, False: 796]
  ------------------
 1067|  5.53k|                p->codec = new_segment->codec;
 1068|  5.53k|                if (!decoder_wrapper_reinit(&p->public))
  ------------------
  |  Branch (1068:21): [True: 0, False: 5.53k]
  ------------------
 1069|      0|                    mp_filter_internal_mark_failed(p->decf);
 1070|  5.53k|            }
 1071|       |
 1072|  6.33k|            p->start = new_segment->start;
 1073|  6.33k|            p->end = new_segment->end;
 1074|  6.33k|        }
 1075|       |
 1076|  6.33k|        p->reverse_queue_byte_size = 0;
 1077|  6.33k|        p->reverse_queue_complete = p->num_reverse_queue > 0;
 1078|       |
 1079|  6.33k|        p->packet = MAKE_FRAME(MP_FRAME_PACKET, new_segment);
  ------------------
  |  |   57|  6.33k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  ------------------
 1080|  6.33k|        mp_filter_internal_mark_progress(p->decf);
 1081|  6.33k|    }
 1082|       |
 1083|   455k|    if (!frame.type) {
  ------------------
  |  Branch (1083:9): [True: 6.33k, False: 449k]
  ------------------
 1084|  6.33k|        mp_filter_internal_mark_progress(p->decf); // make it retry
 1085|  6.33k|        return;
 1086|  6.33k|    }
 1087|       |
 1088|   449k|output_frame:
 1089|   449k|    process_output_frame(p, frame);
 1090|   449k|    mp_pin_in_write(pin, frame);
 1091|   449k|}
f_decoder_wrapper.c:process_decoded_frame:
  710|   455k|{
  711|   455k|    if (frame->type == MP_FRAME_EOF) {
  ------------------
  |  Branch (711:9): [True: 10.1k, False: 445k]
  ------------------
  712|       |        // if we were just draining current segment, don't propagate EOF
  713|  10.1k|        if (p->new_segment)
  ------------------
  |  Branch (713:13): [True: 6.33k, False: 3.83k]
  ------------------
  714|  6.33k|            mp_frame_unref(frame);
  715|  10.1k|        return true;
  716|  10.1k|    }
  717|       |
  718|   445k|    bool segment_ended = false;
  719|       |
  720|   445k|    if (frame->type == MP_FRAME_VIDEO) {
  ------------------
  |  Branch (720:9): [True: 71.9k, False: 373k]
  ------------------
  721|  71.9k|        struct mp_image *mpi = frame->data;
  722|       |
  723|  71.9k|        crazy_video_pts_stuff(p, mpi);
  724|       |
  725|  71.9k|        struct demux_packet *ccpkt = new_demux_packet_from_buf(p->public.f->packet_pool,
  726|  71.9k|                                                               mpi->a53_cc);
  727|  71.9k|        if (ccpkt) {
  ------------------
  |  Branch (727:13): [True: 0, False: 71.9k]
  ------------------
  728|      0|            av_buffer_unref(&mpi->a53_cc);
  729|      0|            ccpkt->pts = mpi->pts;
  730|      0|            ccpkt->dts = mpi->dts;
  731|      0|            demuxer_feed_caption(p->header, ccpkt);
  732|      0|        }
  733|       |
  734|       |        // Stop hr-seek logic.
  735|  71.9k|        if (mpi->pts == MP_NOPTS_VALUE || mpi->pts >= p->start_pts)
  ------------------
  |  |   38|   143k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (735:13): [True: 7, False: 71.9k]
  |  Branch (735:43): [True: 71.9k, False: 0]
  ------------------
  736|  71.9k|            p->start_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  737|       |
  738|  71.9k|        if (mpi->pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (738:13): [True: 71.9k, False: 7]
  ------------------
  739|  71.9k|            segment_ended = p->end != MP_NOPTS_VALUE && mpi->pts >= p->end;
  ------------------
  |  |   38|   143k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (739:29): [True: 0, False: 71.9k]
  |  Branch (739:57): [True: 0, False: 0]
  ------------------
  740|  71.9k|            if ((p->start != MP_NOPTS_VALUE && mpi->pts < p->start) ||
  ------------------
  |  |   38|   143k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (740:18): [True: 0, False: 71.9k]
  |  Branch (740:48): [True: 0, False: 0]
  ------------------
  741|  71.9k|                segment_ended)
  ------------------
  |  Branch (741:17): [True: 0, False: 71.9k]
  ------------------
  742|      0|            {
  743|      0|                mp_frame_unref(frame);
  744|      0|                goto done;
  745|      0|            }
  746|  71.9k|        }
  747|   373k|    } else if (frame->type == MP_FRAME_AUDIO) {
  ------------------
  |  Branch (747:16): [True: 373k, False: 0]
  ------------------
  748|   373k|        struct mp_aframe *aframe = frame->data;
  749|       |
  750|   373k|        mp_aframe_clip_timestamps(aframe, p->start, p->end);
  751|   373k|        double pts = mp_aframe_get_pts(aframe);
  752|   373k|        if (pts != MP_NOPTS_VALUE && p->start != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   747k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                      if (pts != MP_NOPTS_VALUE && p->start != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (752:13): [True: 373k, False: 82]
  |  Branch (752:38): [True: 15, False: 373k]
  ------------------
  753|     15|            segment_ended = pts >= p->end;
  754|       |
  755|   373k|        if (mp_aframe_get_size(aframe) == 0) {
  ------------------
  |  Branch (755:13): [True: 0, False: 373k]
  ------------------
  756|      0|            mp_frame_unref(frame);
  757|      0|            goto done;
  758|      0|        }
  759|   373k|    } else {
  760|      0|        MP_ERR(p, "unknown frame type from decoder\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  761|      0|    }
  762|       |
  763|   445k|done:
  764|   445k|    return segment_ended;
  765|   445k|}
f_decoder_wrapper.c:crazy_video_pts_stuff:
  673|  71.9k|{
  674|       |    // Note: the PTS is reordered, but the DTS is not. Both must be monotonic.
  675|       |
  676|  71.9k|    if (mpi->pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (676:9): [True: 71.9k, False: 7]
  ------------------
  677|  71.9k|        if (mpi->pts < p->codec_pts)
  ------------------
  |  Branch (677:13): [True: 0, False: 71.9k]
  ------------------
  678|      0|            p->num_codec_pts_problems++;
  679|  71.9k|        p->codec_pts = mpi->pts;
  680|  71.9k|    }
  681|       |
  682|  71.9k|    if (mpi->dts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (682:9): [True: 71.9k, False: 7]
  ------------------
  683|  71.9k|        if (mpi->dts <= p->codec_dts)
  ------------------
  |  Branch (683:13): [True: 0, False: 71.9k]
  ------------------
  684|      0|            p->num_codec_dts_problems++;
  685|  71.9k|        p->codec_dts = mpi->dts;
  686|  71.9k|    }
  687|       |
  688|  71.9k|    if (p->has_broken_packet_pts < 0)
  ------------------
  |  Branch (688:9): [True: 4.36k, False: 67.6k]
  ------------------
  689|  4.36k|        p->has_broken_packet_pts++;
  690|  71.9k|    if (p->num_codec_pts_problems)
  ------------------
  |  Branch (690:9): [True: 0, False: 71.9k]
  ------------------
  691|      0|        p->has_broken_packet_pts = 1;
  692|       |
  693|       |    // If PTS is unset, or non-monotonic, fall back to DTS.
  694|  71.9k|    if ((p->num_codec_pts_problems > p->num_codec_dts_problems ||
  ------------------
  |  Branch (694:10): [True: 0, False: 71.9k]
  ------------------
  695|  71.9k|        mpi->pts == MP_NOPTS_VALUE) && mpi->dts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                      mpi->pts == MP_NOPTS_VALUE) && mpi->dts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|      7|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (695:9): [True: 7, False: 71.9k]
  |  Branch (695:40): [True: 0, False: 7]
  ------------------
  696|      0|        mpi->pts = mpi->dts;
  697|       |
  698|       |    // Compensate for incorrectly using mpeg-style DTS for avi timestamps.
  699|  71.9k|    if (p->decoder && p->decoder->control && p->codec->avi_dts &&
  ------------------
  |  Branch (699:9): [True: 71.9k, False: 0]
  |  Branch (699:23): [True: 71.9k, False: 0]
  |  Branch (699:46): [True: 0, False: 71.9k]
  ------------------
  700|  71.9k|        mpi->pts != MP_NOPTS_VALUE && p->fps > 0)
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (700:9): [True: 0, False: 0]
  |  Branch (700:39): [True: 0, False: 0]
  ------------------
  701|      0|    {
  702|      0|        int delay = -1;
  703|      0|        p->decoder->control(p->decoder->f, VDCTRL_GET_BFRAMES, &delay);
  704|      0|        mpi->pts -= MPMAX(delay, 0) / p->fps;
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  705|      0|    }
  706|  71.9k|}
f_decoder_wrapper.c:decoder_wrapper_reinit:
  481|  5.53k|{
  482|  5.53k|    struct priv *p = d->f->priv;
  483|  5.53k|    return reinit_decoder(p);
  484|  5.53k|}
f_decoder_wrapper.c:process_output_frame:
  841|   449k|{
  842|   449k|    if (frame.type == MP_FRAME_VIDEO) {
  ------------------
  |  Branch (842:9): [True: 71.9k, False: 377k]
  ------------------
  843|  71.9k|        struct mp_image *mpi = frame.data;
  844|       |
  845|  71.9k|        correct_video_pts(p, mpi);
  846|       |
  847|  71.9k|        if (!mp_image_params_equal(&p->last_format, &mpi->params)) {
  ------------------
  |  Branch (847:13): [True: 9.26k, False: 62.7k]
  ------------------
  848|  9.26k|            fix_image_params(p, &mpi->params,
  849|  9.26k|                mp_image_params_static_equal(&p->last_format, &mpi->params));
  850|  9.26k|        }
  851|       |
  852|  71.9k|        mpi->params = p->fixed_format;
  853|  71.9k|        mpi->nominal_fps = p->fps;
  854|   377k|    } else if (frame.type == MP_FRAME_AUDIO) {
  ------------------
  |  Branch (854:16): [True: 373k, False: 3.83k]
  ------------------
  855|   373k|        struct mp_aframe *aframe = frame.data;
  856|       |
  857|   373k|        if (p->play_dir < 0 && !mp_aframe_reverse(aframe))
  ------------------
  |  Branch (857:13): [True: 0, False: 373k]
  |  Branch (857:32): [True: 0, False: 0]
  ------------------
  858|   373k|            MP_ERR(p, "Couldn't reverse audio frame.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  859|       |
  860|   373k|        correct_audio_pts(p, aframe);
  861|   373k|    }
  862|   449k|}
f_decoder_wrapper.c:correct_video_pts:
  768|  71.9k|{
  769|  71.9k|    mpi->pts *= p->play_dir;
  770|       |
  771|  71.9k|    if (!p->opts->correct_pts || mpi->pts == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (771:9): [True: 0, False: 71.9k]
  |  Branch (771:34): [True: 7, False: 71.9k]
  ------------------
  772|      7|        double fps = p->fps > 0 ? p->fps : 25;
  ------------------
  |  Branch (772:22): [True: 0, False: 7]
  ------------------
  773|       |
  774|      7|        if (p->opts->correct_pts) {
  ------------------
  |  Branch (774:13): [True: 7, False: 0]
  ------------------
  775|      7|            if (p->has_broken_decoded_pts <= 1) {
  ------------------
  |  Branch (775:17): [True: 7, False: 0]
  ------------------
  776|      7|                MP_WARN(p, "No video PTS! Making something up. Using "
  ------------------
  |  |   86|      7|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      7|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  777|      7|                        "%f FPS.\n", fps);
  778|      7|                if (p->has_broken_decoded_pts == 1)
  ------------------
  |  Branch (778:21): [True: 0, False: 7]
  ------------------
  779|      7|                    MP_WARN(p, "Ignoring further missing PTS warnings.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  780|      7|                p->has_broken_decoded_pts++;
  781|      7|            }
  782|      7|        }
  783|       |
  784|      7|        double frame_time = 1.0f / fps;
  785|      7|        double base = p->first_packet_pdts;
  786|      7|        mpi->pts = p->pts;
  787|      7|        if (mpi->pts == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      7|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (787:13): [True: 7, False: 0]
  ------------------
  788|      7|            mpi->pts = base == MP_NOPTS_VALUE ? 0 : base;
  ------------------
  |  |   38|      7|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (788:24): [True: 7, False: 0]
  ------------------
  789|      7|        } else {
  790|      0|            mpi->pts += frame_time;
  791|      0|        }
  792|      7|    }
  793|       |
  794|  71.9k|    p->pts = mpi->pts;
  795|  71.9k|}
f_decoder_wrapper.c:fix_image_params:
  557|  9.26k|{
  558|  9.26k|    struct mp_image_params m = *params;
  559|  9.26k|    struct mp_codec_params *c = p->codec;
  560|  9.26k|    struct dec_wrapper_opts *opts = p->opts;
  561|       |
  562|  9.26k|    if (!quiet)
  ------------------
  |  Branch (562:9): [True: 9.26k, False: 0]
  ------------------
  563|  9.26k|        MP_VERBOSE(p, "Decoder format: %s\n", mp_image_params_to_str(params));
  ------------------
  |  |   88|  9.26k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.26k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  564|  9.26k|    p->dec_format = *params;
  565|       |
  566|  9.26k|    if (!quiet && opts->movie_aspect == 0)
  ------------------
  |  Branch (566:9): [True: 9.26k, False: 0]
  |  Branch (566:19): [True: 0, False: 9.26k]
  ------------------
  567|  9.26k|        MP_WARN(p, "Setting video-aspect-override to 0 is deprecated.\n"
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  568|  9.26k|                   "Use --video-aspect-override=no --video-aspect-mode=ignore instead.\n");
  569|  9.26k|    if (!quiet && opts->movie_aspect == -1)
  ------------------
  |  Branch (569:9): [True: 9.26k, False: 0]
  |  Branch (569:19): [True: 0, False: 9.26k]
  ------------------
  570|  9.26k|        MP_WARN(p, "Setting video-aspect-override to -1 is deprecated.\n"
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  571|  9.26k|                   "Use --video-aspect-override=no --video-aspect-mode=container instead.\n");
  572|       |
  573|       |    // While mp_image_params normally always have to have d_w/d_h set, the
  574|       |    // decoder signals unknown bitstream aspect ratio with both set to 0.
  575|  9.26k|    bool use_container = true;
  576|  9.26k|    if (opts->aspect_method == 1 && m.p_w > 0 && m.p_h > 0 &&
  ------------------
  |  Branch (576:9): [True: 0, False: 9.26k]
  |  Branch (576:37): [True: 0, False: 0]
  |  Branch (576:50): [True: 0, False: 0]
  ------------------
  577|  9.26k|        opts->movie_aspect != -1) {
  ------------------
  |  Branch (577:9): [True: 0, False: 0]
  ------------------
  578|      0|        if (!quiet)
  ------------------
  |  Branch (578:13): [True: 0, False: 0]
  ------------------
  579|      0|            MP_VERBOSE(p, "Using bitstream aspect ratio.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  580|      0|        use_container = false;
  581|      0|    }
  582|       |
  583|  9.26k|    if (opts->aspect_method == 3 && opts->movie_aspect != -1) {
  ------------------
  |  Branch (583:9): [True: 0, False: 9.26k]
  |  Branch (583:37): [True: 0, False: 0]
  ------------------
  584|      0|        if (!quiet)
  ------------------
  |  Branch (584:13): [True: 0, False: 0]
  ------------------
  585|      0|            MP_VERBOSE(p, "Ignoring aspect ratio.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  586|      0|        use_container = false;
  587|      0|        m.p_w = m.p_h = 1;
  588|      0|    }
  589|       |
  590|  9.26k|    if (use_container && c->par_w > 0 && c->par_h) {
  ------------------
  |  Branch (590:9): [True: 9.26k, False: 0]
  |  Branch (590:26): [True: 0, False: 9.26k]
  |  Branch (590:42): [True: 0, False: 0]
  ------------------
  591|      0|        if (!quiet)
  ------------------
  |  Branch (591:13): [True: 0, False: 0]
  ------------------
  592|      0|            MP_VERBOSE(p, "Using container aspect ratio.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  593|      0|        m.p_w = c->par_w;
  594|      0|        m.p_h = c->par_h;
  595|      0|    }
  596|       |
  597|  9.26k|    if (opts->movie_aspect >= 0) {
  ------------------
  |  Branch (597:9): [True: 0, False: 9.26k]
  ------------------
  598|      0|        if (!quiet)
  ------------------
  |  Branch (598:13): [True: 0, False: 0]
  ------------------
  599|      0|            MP_VERBOSE(p, "Forcing user-set aspect ratio.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  600|      0|        if (opts->movie_aspect == 0) {
  ------------------
  |  Branch (600:13): [True: 0, False: 0]
  ------------------
  601|      0|            m.p_w = m.p_h = 1;
  602|      0|        } else {
  603|      0|            AVRational a = av_d2q(opts->movie_aspect, INT_MAX);
  604|      0|            mp_image_params_set_dsize(&m, a.num, a.den);
  605|      0|        }
  606|      0|    }
  607|       |
  608|       |    // Assume square pixels if no aspect ratio is set at all.
  609|  9.26k|    if (m.p_w <= 0 || m.p_h <= 0)
  ------------------
  |  Branch (609:9): [True: 9.26k, False: 0]
  |  Branch (609:23): [True: 0, False: 0]
  ------------------
  610|  9.26k|        m.p_w = m.p_h = 1;
  611|       |
  612|  9.26k|    m.stereo3d = p->codec->stereo_mode;
  613|       |
  614|  9.26k|    if (!mp_rect_equals(&p->codec->crop, &(struct mp_rect){0})) {
  ------------------
  |  Branch (614:9): [True: 0, False: 9.26k]
  ------------------
  615|      0|        struct mp_rect crop = p->codec->crop;
  616|       |        // Offset to respect existing decoder crop.
  617|      0|        crop.x0 += m.crop.x0;
  618|      0|        crop.x1 += m.crop.x0;
  619|      0|        crop.y0 += m.crop.y0;
  620|      0|        crop.y1 += m.crop.y0;
  621|       |        // Crop has to be inside existing image bounds.
  622|      0|        if (mp_image_crop_valid(&(struct mp_image_params) {
  ------------------
  |  Branch (622:13): [True: 0, False: 0]
  ------------------
  623|      0|            .w = mp_rect_w(m.crop), .h = mp_rect_h(m.crop), .crop = crop }))
  ------------------
  |  |  128|      0|#define mp_rect_w(r) ((r).x1 - (r).x0)
  ------------------
                          .w = mp_rect_w(m.crop), .h = mp_rect_h(m.crop), .crop = crop }))
  ------------------
  |  |  129|      0|#define mp_rect_h(r) ((r).y1 - (r).y0)
  ------------------
  624|      0|        {
  625|      0|            m.crop = crop;
  626|      0|        } else {
  627|      0|            MP_WARN(p, "Invalid container crop %dx%d+%d+%d for %dx%d image\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  628|      0|            mp_rect_w(crop), mp_rect_h(crop), crop.x0, crop.y0,
  629|      0|            mp_rect_w(m.crop), mp_rect_h(m.crop));
  630|      0|        }
  631|      0|    }
  632|       |
  633|  9.26k|    if (opts->video_rotate < 0) {
  ------------------
  |  Branch (633:9): [True: 0, False: 9.26k]
  ------------------
  634|      0|        m.rotate = 0;
  635|  9.26k|    } else {
  636|       |        // ffmpeg commit 535a835e51 says that frame rotate takes priority
  637|  9.26k|        if (!m.rotate)
  ------------------
  |  Branch (637:13): [True: 9.26k, False: 0]
  ------------------
  638|  9.26k|            m.rotate = p->codec->rotate;
  639|  9.26k|        m.rotate = (m.rotate + opts->video_rotate) % 360;
  640|  9.26k|    }
  641|       |
  642|  9.26k|    pl_color_space_merge(&m.color, &c->color);
  643|  9.26k|    pl_color_repr_merge(&m.repr, &c->repr);
  644|       |
  645|  9.26k|    if (m.chroma_location == PL_CHROMA_UNKNOWN)
  ------------------
  |  Branch (645:9): [True: 9.26k, False: 0]
  ------------------
  646|  9.26k|        m.chroma_location = c->chroma_location;
  647|       |
  648|       |    // Guess missing colorspace fields from metadata. This guarantees all
  649|       |    // fields are at least set to legal values afterwards.
  650|  9.26k|    mp_image_params_guess_csp(&m);
  651|       |
  652|  9.26k|    p->last_format = *params;
  653|  9.26k|    p->fixed_format = m;
  654|  9.26k|}
f_decoder_wrapper.c:correct_audio_pts:
  798|   373k|{
  799|   373k|    double dir = p->play_dir;
  800|       |
  801|   373k|    double frame_pts = mp_aframe_get_pts(aframe);
  802|   373k|    double frame_len = mp_aframe_duration(aframe);
  803|       |
  804|   373k|    if (frame_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (804:9): [True: 373k, False: 82]
  ------------------
  805|   373k|        if (dir < 0)
  ------------------
  |  Branch (805:13): [True: 0, False: 373k]
  ------------------
  806|      0|            frame_pts = -(frame_pts + frame_len);
  807|       |
  808|   373k|        if (p->pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (808:13): [True: 372k, False: 678]
  ------------------
  809|   373k|            MP_STATS(p, "value %f audio-pts-err", p->pts - frame_pts);
  ------------------
  |  |   95|   372k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   372k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  810|       |
  811|   373k|        double diff = fabs(p->pts - frame_pts);
  812|       |
  813|       |        // Attempt to detect jumps in PTS. Even for the lowest sample rates and
  814|       |        // with worst container rounded timestamp, this should be a margin more
  815|       |        // than enough.
  816|   373k|        if (p->pts != MP_NOPTS_VALUE && diff > 0.1) {
  ------------------
  |  |   38|   746k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (816:13): [True: 372k, False: 678]
  |  Branch (816:41): [True: 9.08k, False: 363k]
  ------------------
  817|  9.08k|            MP_WARN(p, "Invalid audio PTS: %f -> %f\n", p->pts, frame_pts);
  ------------------
  |  |   86|  9.08k|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.08k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  818|  9.08k|            if (diff >= 5) {
  ------------------
  |  Branch (818:17): [True: 295, False: 8.78k]
  ------------------
  819|    295|                mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|    295|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  820|    295|                p->pts_reset = true;
  821|    295|                mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|    295|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  822|    295|            }
  823|  9.08k|        }
  824|       |
  825|       |        // Keep the interpolated timestamp if it doesn't deviate more
  826|       |        // than 1 ms from the real one. (MKV rounded timestamps.)
  827|   373k|        if (p->pts == MP_NOPTS_VALUE || diff > 0.001)
  ------------------
  |  |   38|   746k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (827:13): [True: 678, False: 372k]
  |  Branch (827:41): [True: 19.7k, False: 353k]
  ------------------
  828|  20.4k|            p->pts = frame_pts;
  829|   373k|    }
  830|       |
  831|   373k|    if (p->pts == MP_NOPTS_VALUE && p->header->missing_timestamps)
  ------------------
  |  |   38|   747k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (831:9): [True: 82, False: 373k]
  |  Branch (831:37): [True: 0, False: 82]
  ------------------
  832|      0|        p->pts = 0;
  833|       |
  834|   373k|    mp_aframe_set_pts(aframe, p->pts);
  835|       |
  836|   373k|    if (p->pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (836:9): [True: 373k, False: 82]
  ------------------
  837|   373k|        p->pts += frame_len;
  838|   373k|}
f_decoder_wrapper.c:decf_reset:
  322|  9.76k|{
  323|  9.76k|    struct priv *p = f->priv;
  324|  9.76k|    mp_assert(p->decf == f);
  ------------------
  |  |   41|  9.76k|#define mp_assert assert
  ------------------
  325|       |
  326|  9.76k|    p->pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  9.76k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  327|  9.76k|    p->last_format = p->fixed_format = (struct mp_image_params){0};
  328|       |
  329|  9.76k|    mp_mutex_lock(&p->cache_lock);
  ------------------
  |  |  131|  9.76k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  330|  9.76k|    p->pts_reset = false;
  331|  9.76k|    p->attempt_framedrops = 0;
  332|  9.76k|    p->dropped_frames = 0;
  333|  9.76k|    mp_mutex_unlock(&p->cache_lock);
  ------------------
  |  |  133|  9.76k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  334|       |
  335|  9.76k|    p->coverart_returned = 0;
  336|       |
  337|  9.76k|    for (int n = 0; n < p->num_reverse_queue; n++)
  ------------------
  |  Branch (337:21): [True: 0, False: 9.76k]
  ------------------
  338|      0|        mp_frame_unref(&p->reverse_queue[n]);
  339|  9.76k|    p->num_reverse_queue = 0;
  340|  9.76k|    p->reverse_queue_byte_size = 0;
  341|  9.76k|    p->reverse_queue_complete = false;
  342|       |
  343|  9.76k|    reset_decoder(p);
  344|  9.76k|}
f_decoder_wrapper.c:public_f_reset:
 1140|  4.88k|{
 1141|  4.88k|    struct priv *p = f->priv;
 1142|  4.88k|    mp_assert(p->public.f == f);
  ------------------
  |  |   41|  4.88k|#define mp_assert assert
  ------------------
 1143|       |
 1144|  4.88k|    if (p->queue) {
  ------------------
  |  Branch (1144:9): [True: 0, False: 4.88k]
  ------------------
 1145|      0|        mp_async_queue_reset(p->queue);
 1146|      0|        thread_lock(p);
 1147|      0|        mp_filter_reset(p->dec_root_filter);
 1148|      0|        mp_dispatch_interrupt(p->dec_dispatch);
 1149|      0|        thread_unlock(p);
 1150|      0|        mp_async_queue_resume(p->queue);
 1151|      0|    }
 1152|  4.88k|}

mp_demux_in_create:
   72|  4.88k|{
   73|  4.88k|    struct mp_filter *f = mp_filter_create(parent, &demux_filter);
   74|  4.88k|    if (!f)
  ------------------
  |  Branch (74:9): [True: 0, False: 4.88k]
  ------------------
   75|      0|        return NULL;
   76|       |
   77|  4.88k|    struct priv *p = f->priv;
   78|  4.88k|    p->src = src;
   79|       |
   80|  4.88k|    mp_filter_add_pin(f, MP_PIN_OUT, "out");
   81|       |
   82|  4.88k|    demux_set_stream_wakeup_cb(p->src, wakeup, f);
   83|       |
   84|  4.88k|    return f;
   85|  4.88k|}
f_demux_in.c:demux_destroy:
   56|  4.88k|{
   57|  4.88k|    struct priv *p = f->priv;
   58|       |
   59|  4.88k|    demux_set_stream_wakeup_cb(p->src, NULL, NULL);
   60|  4.88k|}
f_demux_in.c:demux_process:
   21|  1.43M|{
   22|  1.43M|    struct priv *p = f->priv;
   23|       |
   24|  1.43M|    if (!mp_pin_in_needs_data(f->ppins[0]))
  ------------------
  |  Branch (24:9): [True: 3.84k, False: 1.43M]
  ------------------
   25|  3.84k|        return;
   26|       |
   27|  1.43M|    struct demux_packet *pkt = NULL;
   28|  1.43M|    if (demux_read_packet_async(p->src, &pkt) == 0)
  ------------------
  |  Branch (28:9): [True: 9.91k, False: 1.42M]
  ------------------
   29|  9.91k|        return; // wait
   30|       |
   31|  1.42M|    struct mp_frame frame = {MP_FRAME_PACKET, pkt};
   32|  1.42M|    if (pkt) {
  ------------------
  |  Branch (32:9): [True: 1.41M, False: 5.94k]
  ------------------
   33|  1.41M|        if (p->eof_returned)
  ------------------
  |  Branch (33:13): [True: 0, False: 1.41M]
  ------------------
   34|  1.41M|            MP_VERBOSE(f, "unset EOF on stream %d\n", p->src->index);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   35|  1.41M|        p->eof_returned = false;
   36|  1.41M|    } else {
   37|  5.94k|        frame.type = MP_FRAME_EOF;
   38|       |
   39|       |        // While the demuxer will repeat EOFs, filters never do that.
   40|  5.94k|        if (p->eof_returned)
  ------------------
  |  Branch (40:13): [True: 2.10k, False: 3.83k]
  ------------------
   41|  2.10k|            return;
   42|  3.83k|        p->eof_returned = true;
   43|  3.83k|    }
   44|       |
   45|  1.42M|    mp_pin_in_write(f->ppins[0], frame);
   46|  1.42M|}
f_demux_in.c:wakeup:
   14|  9.92k|{
   15|  9.92k|    struct mp_filter *f = ctx;
   16|       |
   17|  9.92k|    mp_filter_wakeup(f);
   18|  9.92k|}

mp_output_chain_set_vo:
  374|  2.93k|{
  375|  2.93k|    struct chain *p = c->f->priv;
  376|       |
  377|  2.93k|    p->stream_info.hwdec_devs = vo ? vo->hwdec_devs : NULL;
  ------------------
  |  Branch (377:33): [True: 2.93k, False: 0]
  ------------------
  378|  2.93k|    p->stream_info.osd = vo ? vo->osd : NULL;
  ------------------
  |  Branch (378:26): [True: 2.93k, False: 0]
  ------------------
  379|  2.93k|    p->stream_info.vflip = vo ? vo->driver->caps & VO_CAP_VFLIP : false;
  ------------------
  |  Branch (379:28): [True: 2.93k, False: 0]
  ------------------
  380|  2.93k|    p->stream_info.rotate90 = vo ? vo->driver->caps & VO_CAP_ROTATE90 : false;
  ------------------
  |  Branch (380:31): [True: 2.93k, False: 0]
  ------------------
  381|  2.93k|    p->stream_info.dr_vo = vo;
  382|  2.93k|    p->vo = vo;
  383|  2.93k|    update_output_caps(p);
  384|  2.93k|}
mp_output_chain_set_ao:
  387|  1.36k|{
  388|  1.36k|    struct chain *p = c->f->priv;
  389|       |
  390|  1.36k|    mp_assert(p->public.ao_needs_update); // can't just call it any time
  ------------------
  |  |   41|  1.36k|#define mp_assert assert
  ------------------
  391|  1.36k|    mp_assert(!p->ao);
  ------------------
  |  |   41|  1.36k|#define mp_assert assert
  ------------------
  392|       |
  393|  1.36k|    p->public.ao_needs_update = false;
  394|       |
  395|  1.36k|    p->ao = ao;
  396|       |
  397|  1.36k|    int out_format = 0;
  398|  1.36k|    int out_rate = 0;
  399|  1.36k|    struct mp_chmap out_channels = {0};
  400|  1.36k|    ao_get_format(p->ao, &out_rate, &out_format, &out_channels);
  401|       |
  402|  1.36k|    mp_autoconvert_clear(p->convert);
  403|  1.36k|    mp_autoconvert_add_afmt(p->convert, out_format);
  404|  1.36k|    mp_autoconvert_add_srate(p->convert, out_rate);
  405|  1.36k|    mp_autoconvert_add_chmap(p->convert, &out_channels);
  406|       |
  407|  1.36k|    mp_autoconvert_format_change_continue(p->convert);
  408|       |
  409|       |    // Just to get the format change logged again.
  410|  1.36k|    mp_aframe_reset(p->public.output_aformat);
  411|  1.36k|}
mp_output_chain_set_audio_speed:
  486|  1.82k|{
  487|  1.82k|    struct chain *p = c->f->priv;
  488|       |
  489|       |    // We always resample with the final libavresample instance.
  490|  1.82k|    set_speed_any(p->post_filters, p->num_post_filters,
  491|  1.82k|                  MP_FILTER_COMMAND_SET_SPEED_RESAMPLE, &resample);
  492|       |
  493|       |    // If users have filters like "scaletempo" insert anywhere, use that,
  494|       |    // otherwise use the builtin ones.
  495|  1.82k|    set_speed_any(p->user_filters, p->num_user_filters,
  496|  1.82k|                  MP_FILTER_COMMAND_SET_SPEED, &speed);
  497|  1.82k|    set_speed_any(p->post_filters, p->num_post_filters,
  498|  1.82k|                  MP_FILTER_COMMAND_SET_SPEED, &speed);
  499|  1.82k|    set_speed_any(p->user_filters, p->num_user_filters,
  500|  1.82k|                  MP_FILTER_COMMAND_SET_SPEED_DROP, &drop);
  501|  1.82k|    set_speed_any(p->post_filters, p->num_post_filters,
  502|  1.82k|                  MP_FILTER_COMMAND_SET_SPEED_DROP, &drop);
  503|  1.82k|}
mp_output_chain_update_filters:
  537|  3.84k|{
  538|  3.84k|    struct chain *p = c->f->priv;
  539|       |
  540|  3.84k|    struct mp_user_filter **add = NULL;      // new filters
  541|  3.84k|    int num_add = 0;
  542|  3.84k|    struct mp_user_filter **res = NULL;      // new final list
  543|  3.84k|    int num_res = 0;
  544|  3.84k|    bool *used = talloc_zero_array(NULL, bool, p->num_user_filters);
  ------------------
  |  |   30|  3.84k|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|  3.84k|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  3.84k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  545|       |
  546|  3.84k|    for (int n = 0; list && list[n].name; n++) {
  ------------------
  |  Branch (546:21): [True: 0, False: 3.84k]
  |  Branch (546:29): [True: 0, False: 0]
  ------------------
  547|      0|        struct m_obj_settings *entry = &list[n];
  548|       |
  549|      0|        if (!entry->enabled)
  ------------------
  |  Branch (549:13): [True: 0, False: 0]
  ------------------
  550|      0|            continue;
  551|       |
  552|      0|        struct mp_user_filter *u = NULL;
  553|       |
  554|      0|        for (int i = 0; i < p->num_user_filters; i++) {
  ------------------
  |  Branch (554:25): [True: 0, False: 0]
  ------------------
  555|      0|            if (!used[i] && m_obj_settings_equal(entry, p->user_filters[i]->args))
  ------------------
  |  Branch (555:17): [True: 0, False: 0]
  |  Branch (555:29): [True: 0, False: 0]
  ------------------
  556|      0|            {
  557|      0|                u = p->user_filters[i];
  558|      0|                used[i] = true;
  559|      0|                break;
  560|      0|            }
  561|      0|        }
  562|       |
  563|      0|        if (!u) {
  ------------------
  |  Branch (563:13): [True: 0, False: 0]
  ------------------
  564|      0|            u = create_wrapper_filter(p);
  565|      0|            u->name = talloc_strdup(u, entry->name);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  566|      0|            u->label = talloc_strdup(u, entry->label);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  567|      0|            u->f = mp_create_user_filter(u->wrapper, p->type, entry->name,
  568|      0|                                         entry->attribs);
  569|      0|            if (!u->f) {
  ------------------
  |  Branch (569:17): [True: 0, False: 0]
  ------------------
  570|      0|                talloc_free(u->wrapper);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  571|      0|                goto error;
  572|      0|            }
  573|       |
  574|      0|            struct m_obj_settings *args = (struct m_obj_settings[2]){*entry, {0}};
  575|       |
  576|      0|            struct m_option dummy = {.type = &m_option_type_obj_settings_list};
  577|      0|            m_option_copy(&dummy, &u->args, &args);
  578|       |
  579|      0|            MP_TARRAY_APPEND(NULL, add, num_add, u);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  580|      0|        }
  581|       |
  582|      0|        MP_TARRAY_APPEND(p, res, num_res, u);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  583|      0|    }
  584|       |
  585|       |    // At this point we definitely know we'll use the new list, so clean up.
  586|       |
  587|  3.84k|    for (int n = 0; n < p->num_user_filters; n++) {
  ------------------
  |  Branch (587:21): [True: 0, False: 3.84k]
  ------------------
  588|      0|        if (!used[n])
  ------------------
  |  Branch (588:13): [True: 0, False: 0]
  ------------------
  589|      0|            talloc_free(p->user_filters[n]->wrapper);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  590|      0|    }
  591|       |
  592|  3.84k|    talloc_free(p->user_filters);
  ------------------
  |  |   47|  3.84k|#define talloc_free                     ta_free
  ------------------
  593|  3.84k|    p->user_filters = res;
  594|  3.84k|    p->num_user_filters = num_res;
  595|       |
  596|  3.84k|    relink_filter_list(p);
  597|       |
  598|  3.84k|    for (int n = 0; n < p->num_user_filters; n++) {
  ------------------
  |  Branch (598:21): [True: 0, False: 3.84k]
  ------------------
  599|      0|        struct mp_user_filter *u = p->user_filters[n];
  600|      0|        if (u->generated_label)
  ------------------
  |  Branch (600:13): [True: 0, False: 0]
  ------------------
  601|      0|            TA_FREEP(&u->label);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  602|      0|        if (!u->label) {
  ------------------
  |  Branch (602:13): [True: 0, False: 0]
  ------------------
  603|      0|            for (int i = 0; i < 100; i++) {
  ------------------
  |  Branch (603:29): [True: 0, False: 0]
  ------------------
  604|      0|                char *label = mp_tprintf(80, "%s.%02d", u->name, i);
  ------------------
  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  ------------------
  605|      0|                if (!find_by_label(p, label)) {
  ------------------
  |  Branch (605:21): [True: 0, False: 0]
  ------------------
  606|      0|                    u->label = talloc_strdup(u, label);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  607|      0|                    u->generated_label = true;
  608|      0|                    break;
  609|      0|                }
  610|      0|            }
  611|      0|        }
  612|      0|    }
  613|       |
  614|  3.84k|    MP_VERBOSE(p, "User filter list:\n");
  ------------------
  |  |   88|  3.84k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.84k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  615|  3.84k|    for (int n = 0; n < p->num_user_filters; n++) {
  ------------------
  |  Branch (615:21): [True: 0, False: 3.84k]
  ------------------
  616|      0|        struct mp_user_filter *u = p->user_filters[n];
  617|      0|        MP_VERBOSE(p, "  %s (%s)\n", u->name, u->label ? u->label : "-");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  618|      0|    }
  619|  3.84k|    if (!p->num_user_filters)
  ------------------
  |  Branch (619:9): [True: 3.84k, False: 0]
  ------------------
  620|  3.84k|        MP_VERBOSE(p, "  (empty)\n");
  ------------------
  |  |   88|  3.84k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.84k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  621|       |
  622|       |    // Filters can load hwdec interops, which might add new formats.
  623|  3.84k|    update_output_caps(p);
  624|       |
  625|  3.84k|    mp_filter_wakeup(p->f);
  626|       |
  627|  3.84k|    talloc_free(add);
  ------------------
  |  |   47|  3.84k|#define talloc_free                     ta_free
  ------------------
  628|  3.84k|    talloc_free(used);
  ------------------
  |  |   47|  3.84k|#define talloc_free                     ta_free
  ------------------
  629|  3.84k|    return true;
  630|       |
  631|      0|error:
  632|      0|    for (int n = 0; n < num_add; n++)
  ------------------
  |  Branch (632:21): [True: 0, False: 0]
  ------------------
  633|      0|        talloc_free(add[n]->wrapper);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  634|      0|    talloc_free(add);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  635|      0|    talloc_free(used);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  636|      0|    return false;
  637|  3.84k|}
mp_output_chain_create:
  685|  4.88k|{
  686|  4.88k|    struct mp_filter *f = mp_filter_create(parent, &output_chain_filter);
  687|  4.88k|    if (!f)
  ------------------
  |  Branch (687:9): [True: 0, False: 4.88k]
  ------------------
  688|      0|        return NULL;
  689|       |
  690|  4.88k|    mp_filter_add_pin(f, MP_PIN_IN, "in");
  691|  4.88k|    mp_filter_add_pin(f, MP_PIN_OUT, "out");
  692|       |
  693|  4.88k|    const char *log_name = NULL;
  694|  4.88k|    switch (type) {
  ------------------
  |  Branch (694:13): [True: 0, False: 4.88k]
  ------------------
  695|  2.93k|    case MP_OUTPUT_CHAIN_VIDEO: log_name = "!vf"; break;
  ------------------
  |  Branch (695:5): [True: 2.93k, False: 1.95k]
  ------------------
  696|  1.95k|    case MP_OUTPUT_CHAIN_AUDIO: log_name = "!af"; break;
  ------------------
  |  Branch (696:5): [True: 1.95k, False: 2.93k]
  ------------------
  697|  4.88k|    }
  698|  4.88k|    if (log_name)
  ------------------
  |  Branch (698:9): [True: 4.88k, False: 0]
  ------------------
  699|  4.88k|        f->log = mp_log_new(f, parent->global->log, log_name);
  700|       |
  701|  4.88k|    struct chain *p = f->priv;
  702|  4.88k|    p->f = f;
  703|  4.88k|    p->log = f->log;
  704|  4.88k|    p->type = type;
  705|       |
  706|  4.88k|    struct mp_output_chain *c = &p->public;
  707|  4.88k|    c->f = f;
  708|  4.88k|    c->input_aformat = talloc_steal(p, mp_aframe_create());
  ------------------
  |  |   38|  4.88k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  4.88k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  709|  4.88k|    c->output_aformat = talloc_steal(p, mp_aframe_create());
  ------------------
  |  |   38|  4.88k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  4.88k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  710|       |
  711|       |    // Dummy filter for reporting and logging the input format.
  712|  4.88k|    p->input = create_wrapper_filter(p);
  713|  4.88k|    p->input->f = mp_bidir_nop_filter_create(p->input->wrapper);
  714|  4.88k|    if (!p->input->f)
  ------------------
  |  Branch (714:9): [True: 0, False: 4.88k]
  ------------------
  715|      0|        abort();
  716|  4.88k|    p->input->name = "in";
  717|  4.88k|    MP_TARRAY_APPEND(p, p->pre_filters, p->num_pre_filters, p->input);
  ------------------
  |  |  105|  4.88k|    do {                                            \
  |  |  106|  4.88k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.88k|    do {                                            \
  |  |  |  |   97|  4.88k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.88k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.88k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.88k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.88k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.88k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.88k|    do {                                                        \
  |  |  |  |  |  |   89|  4.88k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.88k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.88k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.88k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.88k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.88k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.88k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.88k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.88k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.88k|        (idxvar)++;                                 \
  |  |  109|  4.88k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  718|       |
  719|  4.88k|    switch (type) {
  ------------------
  |  Branch (719:13): [True: 0, False: 4.88k]
  ------------------
  720|  2.93k|    case MP_OUTPUT_CHAIN_VIDEO: create_video_things(p); break;
  ------------------
  |  Branch (720:5): [True: 2.93k, False: 1.95k]
  ------------------
  721|  1.95k|    case MP_OUTPUT_CHAIN_AUDIO: create_audio_things(p); break;
  ------------------
  |  Branch (721:5): [True: 1.95k, False: 2.93k]
  ------------------
  722|  4.88k|    }
  723|       |
  724|  4.88k|    p->convert_wrapper = create_wrapper_filter(p);
  725|  4.88k|    p->convert = mp_autoconvert_create(p->convert_wrapper->wrapper);
  726|  4.88k|    if (!p->convert)
  ------------------
  |  Branch (726:9): [True: 0, False: 4.88k]
  ------------------
  727|      0|        abort();
  728|  4.88k|    p->convert_wrapper->name = "convert";
  729|  4.88k|    p->convert_wrapper->f = p->convert->f;
  730|  4.88k|    MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, p->convert_wrapper);
  ------------------
  |  |  105|  4.88k|    do {                                            \
  |  |  106|  4.88k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.88k|    do {                                            \
  |  |  |  |   97|  4.88k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.88k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.88k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.88k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.93k, False: 1.95k]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.88k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.93k|    do {                                                        \
  |  |  |  |  |  |   89|  2.93k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.93k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.93k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.93k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.93k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.93k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.93k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.88k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.88k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.88k|        (idxvar)++;                                 \
  |  |  109|  4.88k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  731|       |
  732|  4.88k|    if (type == MP_OUTPUT_CHAIN_AUDIO) {
  ------------------
  |  Branch (732:9): [True: 1.95k, False: 2.93k]
  ------------------
  733|  1.95k|        p->convert->on_audio_format_change = on_audio_format_change;
  734|  1.95k|        p->convert->on_audio_format_change_opaque = p;
  735|  1.95k|    }
  736|       |
  737|       |    // Dummy filter for reporting and logging the output format.
  738|  4.88k|    p->output = create_wrapper_filter(p);
  739|  4.88k|    p->output->f = mp_bidir_nop_filter_create(p->output->wrapper);
  740|  4.88k|    if (!p->output->f)
  ------------------
  |  Branch (740:9): [True: 0, False: 4.88k]
  ------------------
  741|      0|        abort();
  742|  4.88k|    p->output->name = "out";
  743|  4.88k|    MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, p->output);
  ------------------
  |  |  105|  4.88k|    do {                                            \
  |  |  106|  4.88k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.88k|    do {                                            \
  |  |  |  |   97|  4.88k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.88k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.88k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.88k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 1.95k, False: 2.93k]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.88k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  1.95k|    do {                                                        \
  |  |  |  |  |  |   89|  1.95k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  1.95k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  1.95k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  1.95k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  1.95k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  1.95k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  1.95k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.88k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.88k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.88k|        (idxvar)++;                                 \
  |  |  109|  4.88k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  744|       |
  745|  4.88k|    relink_filter_list(p);
  746|       |
  747|  4.88k|    output_chain_reset(f);
  748|       |
  749|  4.88k|    return c;
  750|  4.88k|}
f_output_chain.c:update_output_caps:
   77|  16.0k|{
   78|  16.0k|    if (p->type != MP_OUTPUT_CHAIN_VIDEO)
  ------------------
  |  Branch (78:9): [True: 1.81k, False: 14.2k]
  ------------------
   79|  1.81k|        return;
   80|       |
   81|  14.2k|    mp_autoconvert_clear(p->convert);
   82|       |
   83|  14.2k|    if (p->vo) {
  ------------------
  |  Branch (83:9): [True: 14.2k, False: 0]
  ------------------
   84|  14.2k|        uint8_t allowed_output_formats[IMGFMT_END - IMGFMT_START] = {0};
   85|  14.2k|        vo_query_formats(p->vo, allowed_output_formats);
   86|       |
   87|  7.93M|        for (int n = 0; n < MP_ARRAY_SIZE(allowed_output_formats); n++) {
  ------------------
  |  |   48|  7.93M|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (87:25): [True: 7.92M, False: 14.2k]
  ------------------
   88|  7.92M|            if (allowed_output_formats[n])
  ------------------
  |  Branch (88:17): [True: 7.92M, False: 0]
  ------------------
   89|  7.92M|                mp_autoconvert_add_imgfmt(p->convert, IMGFMT_START + n, 0);
   90|  7.92M|        }
   91|  14.2k|    }
   92|  14.2k|}
f_output_chain.c:set_speed_any:
  472|  9.10k|{
  473|  25.4k|    for (int n = num_filters - 1; n >= 0; n--) {
  ------------------
  |  Branch (473:35): [True: 16.3k, False: 9.10k]
  ------------------
  474|  16.3k|        mp_assert(*speed);
  ------------------
  |  |   41|  16.3k|#define mp_assert assert
  ------------------
  475|  16.3k|        struct mp_filter_command cmd = {
  476|  16.3k|            .type = command,
  477|  16.3k|            .speed = *speed,
  478|  16.3k|        };
  479|  16.3k|        if (mp_filter_command(filters[n]->f, &cmd))
  ------------------
  |  Branch (479:13): [True: 5.46k, False: 10.9k]
  ------------------
  480|  5.46k|            *speed = 1.0;
  481|  16.3k|    }
  482|  9.10k|}
f_output_chain.c:create_wrapper_filter:
  242|  25.3k|{
  243|  25.3k|    struct mp_filter *f = mp_filter_create(p->f, &user_wrapper_filter);
  244|  25.3k|    if (!f)
  ------------------
  |  Branch (244:9): [True: 0, False: 25.3k]
  ------------------
  245|      0|        abort();
  246|  25.3k|    struct mp_user_filter *wrapper = f->priv;
  247|  25.3k|    wrapper->wrapper = f;
  248|  25.3k|    wrapper->p = p;
  249|  25.3k|    wrapper->last_in_aformat = talloc_steal(wrapper, mp_aframe_create());
  ------------------
  |  |   38|  25.3k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  25.3k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  250|  25.3k|    wrapper->last_is_active = true;
  251|  25.3k|    mp_filter_add_pin(f, MP_PIN_IN, "in");
  252|  25.3k|    mp_filter_add_pin(f, MP_PIN_OUT, "out");
  253|  25.3k|    return wrapper;
  254|  25.3k|}
f_output_chain.c:user_wrapper_destroy:
  224|  25.3k|{
  225|  25.3k|    struct mp_user_filter *u = f->priv;
  226|       |
  227|  25.3k|    struct m_option dummy = {.type = &m_option_type_obj_settings_list};
  228|  25.3k|    m_option_free(&dummy, &u->args);
  229|       |
  230|  25.3k|    mp_filter_free_children(f);
  231|  25.3k|}
f_output_chain.c:user_wrapper_process:
  149|  7.07M|{
  150|  7.07M|    struct mp_user_filter *u = f->priv;
  151|  7.07M|    struct chain *p = u->p;
  152|       |
  153|  7.07M|    mp_filter_set_error_handler(u->f, f);
  154|  7.07M|    const char *name = u->label ? u->label : u->name;
  ------------------
  |  Branch (154:24): [True: 0, False: 7.07M]
  ------------------
  155|  7.07M|    mp_assert(u->name);
  ------------------
  |  |   41|  7.07M|#define mp_assert assert
  ------------------
  156|       |
  157|  7.07M|    if (!u->failed && mp_filter_has_failed(u->f)) {
  ------------------
  |  Branch (157:9): [True: 7.07M, False: 0]
  |  Branch (157:23): [True: 0, False: 7.07M]
  ------------------
  158|      0|        if (u == p->convert_wrapper) {
  ------------------
  |  Branch (158:13): [True: 0, False: 0]
  ------------------
  159|       |            // This is a fuckup we can't ignore.
  160|      0|            MP_FATAL(p, "Cannot convert decoder/filter output to any format "
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  161|      0|                     "supported by the output.\n");
  162|      0|            p->public.failed_output_conversion = true;
  163|      0|            mp_filter_wakeup(p->f);
  164|      0|        } else {
  165|      0|            MP_ERR(p, "Disabling filter %s because it has failed.\n", name);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  166|      0|            mp_filter_reset(u->f); // clear out staled buffered data
  167|      0|        }
  168|      0|        u->failed = true;
  169|      0|    }
  170|       |
  171|  7.07M|    if (u->failed) {
  ------------------
  |  Branch (171:9): [True: 0, False: 7.07M]
  ------------------
  172|      0|        if (u == p->convert_wrapper) {
  ------------------
  |  Branch (172:13): [True: 0, False: 0]
  ------------------
  173|      0|            if (mp_pin_in_needs_data(f->ppins[1])) {
  ------------------
  |  Branch (173:17): [True: 0, False: 0]
  ------------------
  174|      0|                if (!u->error_eof_sent)
  ------------------
  |  Branch (174:21): [True: 0, False: 0]
  ------------------
  175|      0|                    mp_pin_in_write(f->ppins[1], MP_EOF_FRAME);
  ------------------
  |  |   59|      0|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|      0|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  176|      0|                u->error_eof_sent = true;
  177|      0|            }
  178|      0|            return;
  179|      0|        }
  180|       |
  181|      0|        mp_pin_transfer_data(f->ppins[1], f->ppins[0]);
  182|      0|        return;
  183|      0|    }
  184|       |
  185|  7.07M|    if (mp_pin_can_transfer_data(u->f->pins[0], f->ppins[0])) {
  ------------------
  |  Branch (185:9): [True: 1.94M, False: 5.13M]
  ------------------
  186|  1.94M|        struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  187|       |
  188|  1.94M|        check_in_format_change(u, frame);
  189|       |
  190|  1.94M|        double pts = mp_frame_get_pts(frame);
  191|  1.94M|        if (pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.94M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (191:13): [True: 1.92M, False: 19.7k]
  ------------------
  192|  1.92M|            u->last_in_pts = pts;
  193|       |
  194|  1.94M|        mp_pin_in_write(u->f->pins[0], frame);
  195|  1.94M|    }
  196|       |
  197|  7.07M|    if (mp_pin_can_transfer_data(f->ppins[1], u->f->pins[1])) {
  ------------------
  |  Branch (197:9): [True: 1.94M, False: 5.13M]
  ------------------
  198|  1.94M|        struct mp_frame frame = mp_pin_out_read(u->f->pins[1]);
  199|       |
  200|  1.94M|        double pts = mp_frame_get_pts(frame);
  201|  1.94M|        if (pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  1.94M|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (201:13): [True: 1.92M, False: 19.7k]
  ------------------
  202|  1.92M|            u->last_out_pts = pts;
  203|       |
  204|  1.94M|        mp_pin_in_write(f->ppins[1], frame);
  205|       |
  206|  1.94M|        struct mp_filter_command cmd = {.type = MP_FILTER_COMMAND_IS_ACTIVE};
  207|  1.94M|        if (mp_filter_command(u->f, &cmd) && u->last_is_active != cmd.is_active) {
  ------------------
  |  Branch (207:13): [True: 1.04M, False: 898k]
  |  Branch (207:46): [True: 11.7k, False: 1.03M]
  ------------------
  208|  11.7k|            u->last_is_active = cmd.is_active;
  209|  11.7k|            MP_VERBOSE(p, "[%s] (%sabled)\n", u->name,
  ------------------
  |  |   88|  11.7k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  23.4k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 11.7k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  210|  11.7k|                       u->last_is_active ? "en" : "dis");
  211|  11.7k|        }
  212|  1.94M|    }
  213|  7.07M|}
f_output_chain.c:check_in_format_change:
   96|  1.94M|{
   97|  1.94M|    struct chain *p = u->p;
   98|       |
   99|  1.94M|    if (frame.type == MP_FRAME_VIDEO) {
  ------------------
  |  Branch (99:9): [True: 431k, False: 1.51M]
  ------------------
  100|   431k|        struct mp_image *img = frame.data;
  101|       |
  102|   431k|        if (!mp_image_params_equal(&img->params, &u->last_in_vformat)) {
  ------------------
  |  Branch (102:13): [True: 55.5k, False: 376k]
  ------------------
  103|  55.5k|            if (u == p->input) {
  ------------------
  |  Branch (103:17): [True: 9.26k, False: 46.3k]
  ------------------
  104|  9.26k|                p->public.input_params = img->params;
  105|  46.3k|            } else if (u == p->output) {
  ------------------
  |  Branch (105:24): [True: 9.26k, False: 37.0k]
  ------------------
  106|  9.26k|                p->public.output_params = img->params;
  107|  9.26k|            }
  108|       |
  109|  55.5k|            if (!mp_image_params_static_equal(&img->params, &u->last_in_vformat)) {
  ------------------
  |  Branch (109:17): [True: 55.5k, False: 0]
  ------------------
  110|  55.5k|                MP_VERBOSE(p, "[%s] %s\n", u->name,
  ------------------
  |  |   88|  55.5k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  55.5k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  111|  55.5k|                           mp_image_params_to_str(&img->params));
  112|       |
  113|       |                // Unfortunately there's no good place to update these.
  114|       |                // But a common case is enabling HW decoding, which
  115|       |                // might init some support of them in the VO, and update
  116|       |                // the VO's format list.
  117|       |                //
  118|       |                // But as this is only relevant to the "convert" filter, don't
  119|       |                // do this for the other filters as it is wasted work.
  120|  55.5k|                if (strcmp(u->name, "convert") == 0)
  ------------------
  |  Branch (120:21): [True: 9.26k, False: 46.3k]
  ------------------
  121|  9.26k|                    update_output_caps(p);
  122|       |
  123|  55.5k|                p->public.reconfig_happened = true;
  124|  55.5k|            }
  125|  55.5k|            u->last_in_vformat = img->params;
  126|  55.5k|        }
  127|   431k|    }
  128|       |
  129|  1.94M|    if (frame.type == MP_FRAME_AUDIO) {
  ------------------
  |  Branch (129:9): [True: 1.49M, False: 451k]
  ------------------
  130|  1.49M|        struct mp_aframe *aframe = frame.data;
  131|       |
  132|  1.49M|        if (!mp_aframe_config_equals(aframe, u->last_in_aformat)) {
  ------------------
  |  Branch (132:13): [True: 5.45k, False: 1.48M]
  ------------------
  133|  5.45k|            MP_VERBOSE(p, "[%s] %s\n", u->name,
  ------------------
  |  |   88|  5.45k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.45k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  134|  5.45k|                       mp_aframe_format_str(aframe));
  135|  5.45k|            mp_aframe_config_copy(u->last_in_aformat, aframe);
  136|       |
  137|  5.45k|            if (u == p->input) {
  ------------------
  |  Branch (137:17): [True: 1.36k, False: 4.08k]
  ------------------
  138|  1.36k|                mp_aframe_config_copy(p->public.input_aformat, aframe);
  139|  4.08k|            } else if (u == p->output) {
  ------------------
  |  Branch (139:24): [True: 1.36k, False: 2.72k]
  ------------------
  140|  1.36k|                mp_aframe_config_copy(p->public.output_aformat, aframe);
  141|  1.36k|            }
  142|       |
  143|  5.45k|            p->public.reconfig_happened = true;
  144|  5.45k|        }
  145|  1.49M|    }
  146|  1.94M|}
f_output_chain.c:relink_filter_list:
  258|  8.72k|{
  259|  8.72k|    struct mp_user_filter **all_filters[3] =
  260|  8.72k|        {p->pre_filters, p->user_filters, p->post_filters};
  261|  8.72k|    int all_filters_num[3] =
  262|  8.72k|        {p->num_pre_filters, p->num_user_filters, p->num_post_filters};
  263|  8.72k|    p->num_all_filters = 0;
  264|  34.9k|    for (int n = 0; n < 3; n++) {
  ------------------
  |  Branch (264:21): [True: 26.1k, False: 8.72k]
  ------------------
  265|  26.1k|        struct mp_user_filter **filters = all_filters[n];
  266|  26.1k|        int filters_num = all_filters_num[n];
  267|  70.9k|        for (int i = 0; i < filters_num; i++)
  ------------------
  |  Branch (267:25): [True: 44.8k, False: 26.1k]
  ------------------
  268|  44.8k|            MP_TARRAY_APPEND(p, p->all_filters, p->num_all_filters, filters[i]);
  ------------------
  |  |  105|  44.8k|    do {                                            \
  |  |  106|  44.8k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  44.8k|    do {                                            \
  |  |  |  |   97|  44.8k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  44.8k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  44.8k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  44.8k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 9.76k, False: 35.0k]
  |  |  |  |  ------------------
  |  |  |  |   99|  44.8k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  9.76k|    do {                                                        \
  |  |  |  |  |  |   89|  9.76k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  9.76k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  9.76k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  9.76k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  9.76k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  9.76k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  9.76k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  44.8k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  44.8k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  44.8k|        (idxvar)++;                                 \
  |  |  109|  44.8k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  269|  26.1k|    }
  270|       |
  271|  8.72k|    mp_assert(p->num_all_filters > 0);
  ------------------
  |  |   41|  8.72k|#define mp_assert assert
  ------------------
  272|       |
  273|  8.72k|    p->filters_in = NULL;
  274|  8.72k|    p->filters_out = NULL;
  275|  53.5k|    for (int n = 0; n < p->num_all_filters; n++) {
  ------------------
  |  Branch (275:21): [True: 44.8k, False: 8.72k]
  ------------------
  276|  44.8k|        struct mp_filter *f = p->all_filters[n]->wrapper;
  277|  44.8k|        if (n == 0)
  ------------------
  |  Branch (277:13): [True: 8.72k, False: 36.0k]
  ------------------
  278|  8.72k|            p->filters_in = f->pins[0];
  279|  44.8k|        if (p->filters_out)
  ------------------
  |  Branch (279:13): [True: 36.0k, False: 8.72k]
  ------------------
  280|  36.0k|            mp_pin_connect(f->pins[0], p->filters_out);
  281|  44.8k|        p->filters_out = f->pins[1];
  282|  44.8k|    }
  283|  8.72k|}
f_output_chain.c:output_chain_destroy:
  345|  4.88k|{
  346|  4.88k|    output_chain_reset(f);
  347|  4.88k|}
f_output_chain.c:output_chain_process:
  286|  1.80M|{
  287|  1.80M|    struct chain *p = f->priv;
  288|       |
  289|  1.80M|    if (mp_pin_can_transfer_data(p->filters_in, f->ppins[0])) {
  ------------------
  |  Branch (289:9): [True: 449k, False: 1.35M]
  ------------------
  290|   449k|        struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  291|       |
  292|   449k|        if (frame.type == MP_FRAME_EOF)
  ------------------
  |  Branch (292:13): [True: 3.83k, False: 445k]
  ------------------
  293|   449k|            MP_VERBOSE(p, "filter input EOF\n");
  ------------------
  |  |   88|  3.83k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.83k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  294|       |
  295|   449k|        if (frame.type == MP_FRAME_VIDEO && p->public.update_subtitles) {
  ------------------
  |  Branch (295:13): [True: 71.9k, False: 377k]
  |  Branch (295:45): [True: 71.9k, False: 0]
  ------------------
  296|  71.9k|            p->public.update_subtitles(p->public.update_subtitles_ctx,
  297|  71.9k|                                       mp_frame_get_pts(frame));
  298|  71.9k|        }
  299|       |
  300|   449k|        mp_pin_in_write(p->filters_in, frame);
  301|   449k|    }
  302|       |
  303|  1.80M|    if (mp_pin_can_transfer_data(f->ppins[1], p->filters_out)) {
  ------------------
  |  Branch (303:9): [True: 449k, False: 1.35M]
  ------------------
  304|   449k|        struct mp_frame frame = mp_pin_out_read(p->filters_out);
  305|       |
  306|   449k|        p->public.got_output_eof = frame.type == MP_FRAME_EOF;
  307|   449k|        if (p->public.got_output_eof)
  ------------------
  |  Branch (307:13): [True: 3.83k, False: 445k]
  ------------------
  308|   449k|            MP_VERBOSE(p, "filter output EOF\n");
  ------------------
  |  |   88|  3.83k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.83k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  309|       |
  310|   449k|        mp_pin_in_write(f->ppins[1], frame);
  311|   449k|    }
  312|  1.80M|}
f_output_chain.c:create_video_things:
  640|  2.93k|{
  641|  2.93k|    p->frame_type = MP_FRAME_VIDEO;
  642|       |
  643|  2.93k|    p->stream_info.priv = p;
  644|  2.93k|    p->stream_info.get_display_fps = get_display_fps;
  645|  2.93k|    p->stream_info.get_display_res = get_display_res;
  646|       |
  647|  2.93k|    p->f->stream_info = &p->stream_info;
  648|       |
  649|  2.93k|    struct mp_user_filter *f = create_wrapper_filter(p);
  650|  2.93k|    f->name = "userdeint";
  651|  2.93k|    f->f = mp_deint_create(f->wrapper);
  652|  2.93k|    if (!f->f)
  ------------------
  |  Branch (652:9): [True: 0, False: 2.93k]
  ------------------
  653|      0|        abort();
  654|  2.93k|    MP_TARRAY_APPEND(p, p->pre_filters, p->num_pre_filters, f);
  ------------------
  |  |  105|  2.93k|    do {                                            \
  |  |  106|  2.93k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  2.93k|    do {                                            \
  |  |  |  |   97|  2.93k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  2.93k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  2.93k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  2.93k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 2.93k]
  |  |  |  |  ------------------
  |  |  |  |   99|  2.93k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  2.93k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  2.93k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  2.93k|        (idxvar)++;                                 \
  |  |  109|  2.93k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  655|       |
  656|  2.93k|    f = create_wrapper_filter(p);
  657|  2.93k|    f->name = "autovflip";
  658|  2.93k|    f->f = mp_autovflip_create(f->wrapper);
  659|  2.93k|    if (!f->f)
  ------------------
  |  Branch (659:9): [True: 0, False: 2.93k]
  ------------------
  660|      0|        abort();
  661|  2.93k|    MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, f);
  ------------------
  |  |  105|  2.93k|    do {                                            \
  |  |  106|  2.93k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  2.93k|    do {                                            \
  |  |  |  |   97|  2.93k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  2.93k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  2.93k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  2.93k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.93k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  2.93k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.93k|    do {                                                        \
  |  |  |  |  |  |   89|  2.93k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.93k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.93k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.93k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.93k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.93k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.93k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  2.93k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  2.93k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  2.93k|        (idxvar)++;                                 \
  |  |  109|  2.93k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  662|       |
  663|  2.93k|    f = create_wrapper_filter(p);
  664|  2.93k|    f->name = "autorotate";
  665|  2.93k|    f->f = mp_autorotate_create(f->wrapper);
  666|  2.93k|    if (!f->f)
  ------------------
  |  Branch (666:9): [True: 0, False: 2.93k]
  ------------------
  667|      0|        abort();
  668|  2.93k|    MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, f);
  ------------------
  |  |  105|  2.93k|    do {                                            \
  |  |  106|  2.93k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  2.93k|    do {                                            \
  |  |  |  |   97|  2.93k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  2.93k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  2.93k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  2.93k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 2.93k]
  |  |  |  |  ------------------
  |  |  |  |   99|  2.93k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  2.93k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  2.93k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  2.93k|        (idxvar)++;                                 \
  |  |  109|  2.93k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  669|  2.93k|}
f_output_chain.c:create_audio_things:
  672|  1.95k|{
  673|  1.95k|    p->frame_type = MP_FRAME_AUDIO;
  674|       |
  675|  1.95k|    struct mp_user_filter *f = create_wrapper_filter(p);
  676|  1.95k|    f->name = "userspeed";
  677|  1.95k|    f->f = mp_autoaspeed_create(f->wrapper);
  678|  1.95k|    if (!f->f)
  ------------------
  |  Branch (678:9): [True: 0, False: 1.95k]
  ------------------
  679|      0|        abort();
  680|  1.95k|    MP_TARRAY_APPEND(p, p->post_filters, p->num_post_filters, f);
  ------------------
  |  |  105|  1.95k|    do {                                            \
  |  |  106|  1.95k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.95k|    do {                                            \
  |  |  |  |   97|  1.95k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.95k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.95k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.95k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 1.95k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.95k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  1.95k|    do {                                                        \
  |  |  |  |  |  |   89|  1.95k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  1.95k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  1.95k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  1.95k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  1.95k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  1.95k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  1.95k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.95k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.95k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.95k|        (idxvar)++;                                 \
  |  |  109|  1.95k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  681|  1.95k|}
f_output_chain.c:on_audio_format_change:
  414|  1.36k|{
  415|  1.36k|    struct chain *p = opaque;
  416|       |
  417|       |    // Let the f_output_chain user know what format to use. (Not quite proper,
  418|       |    // since we overwrite what some other code normally automatically sets.
  419|       |    // The main issue is that this callback is called before output_aformat can
  420|       |    // be set, because we "block" the converter until the AO is reconfigured,
  421|       |    // and mp_autoconvert_format_change_continue() is called.)
  422|  1.36k|    mp_aframe_config_copy(p->public.output_aformat,
  423|  1.36k|                          p->convert_wrapper->last_in_aformat);
  424|       |
  425|       |    // Ask for calling mp_output_chain_set_ao().
  426|  1.36k|    p->public.ao_needs_update = true;
  427|  1.36k|    p->ao = NULL;
  428|       |
  429|       |    // Do something silly to notify the f_output_chain user. (Not quite proper,
  430|       |    // it's merely that this will cause the core to run again, and check the
  431|       |    // flag set above.)
  432|  1.36k|    mp_filter_wakeup(p->f);
  433|  1.36k|}
f_output_chain.c:output_chain_reset:
  315|  9.76k|{
  316|  9.76k|    struct chain *p = f->priv;
  317|       |
  318|  9.76k|    p->public.ao_needs_update = false;
  319|       |
  320|  9.76k|    p->public.got_output_eof = false;
  321|  9.76k|}

mp_subfilter_read:
   94|  2.11M|{
   95|  2.11M|    if (sub->filter) {
  ------------------
  |  Branch (95:9): [True: 0, False: 2.11M]
  ------------------
   96|      0|        if (mp_pin_can_transfer_data(sub->out, sub->filter->pins[1])) {
  ------------------
  |  Branch (96:13): [True: 0, False: 0]
  ------------------
   97|      0|            struct mp_frame frame = mp_pin_out_read(sub->filter->pins[1]);
   98|      0|            if (sub->draining && frame.type == MP_FRAME_EOF) {
  ------------------
  |  Branch (98:17): [True: 0, False: 0]
  |  Branch (98:34): [True: 0, False: 0]
  ------------------
   99|      0|                sub->draining = false;
  100|      0|                TA_FREEP(&sub->filter);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  101|      0|                mark_progress(sub);
  102|      0|                return false;
  103|      0|            }
  104|      0|            mp_pin_in_write(sub->out, frame);
  105|      0|            return false;
  106|      0|        }
  107|      0|        if (sub->draining)
  ------------------
  |  Branch (107:13): [True: 0, False: 0]
  ------------------
  108|      0|            return false;
  109|      0|    }
  110|       |
  111|  2.11M|    struct mp_pin *out = sub->filter ? sub->filter->pins[0] : sub->out;
  ------------------
  |  Branch (111:26): [True: 0, False: 2.11M]
  ------------------
  112|       |
  113|  2.11M|    if (sub->frame.type)
  ------------------
  |  Branch (113:9): [True: 1.36k, False: 2.11M]
  ------------------
  114|  1.36k|        return mp_pin_in_needs_data(out);
  115|       |
  116|  2.11M|    if (!mp_pin_can_transfer_data(out, sub->in))
  ------------------
  |  Branch (116:9): [True: 1.06M, False: 1.04M]
  ------------------
  117|  1.06M|        return false;
  118|       |
  119|  1.04M|    sub->frame = mp_pin_out_read(sub->in);
  120|  1.04M|    return true;
  121|  2.11M|}
mp_subfilter_reset:
  124|  15.6k|{
  125|  15.6k|    if (sub->filter && sub->draining)
  ------------------
  |  Branch (125:9): [True: 0, False: 15.6k]
  |  Branch (125:24): [True: 0, False: 0]
  ------------------
  126|      0|        TA_FREEP(&sub->filter);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  127|  15.6k|    sub->draining = false;
  128|  15.6k|    mp_frame_unref(&sub->frame);
  129|  15.6k|}
mp_subfilter_continue:
  132|  1.04M|{
  133|  1.04M|    struct mp_pin *out = sub->filter ? sub->filter->pins[0] : sub->out;
  ------------------
  |  Branch (133:26): [True: 0, False: 1.04M]
  ------------------
  134|       |    // It was made sure earlier that the pin is writable, unless the filter
  135|       |    // was newly created, or a previously existing filter (which was going to
  136|       |    // accept input) was destroyed. In those cases, essentially restart
  137|       |    // data flow.
  138|  1.04M|    if (!mp_pin_in_needs_data(out)) {
  ------------------
  |  Branch (138:9): [True: 0, False: 1.04M]
  ------------------
  139|      0|        mark_progress(sub);
  140|      0|        return;
  141|      0|    }
  142|  1.04M|    mp_pin_in_write(out, sub->frame);
  143|  1.04M|    sub->frame = MP_NO_FRAME;
  ------------------
  |  |   58|  1.04M|#define MP_NO_FRAME MAKE_FRAME(0, 0)
  |  |  ------------------
  |  |  |  |   57|  1.04M|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  144|  1.04M|}
mp_subfilter_destroy:
  147|  71.9k|{
  148|  71.9k|    TA_FREEP(&sub->filter);
  ------------------
  |  |   81|  71.9k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  71.9k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  149|  71.9k|    sub->draining = false;
  150|  71.9k|}
mp_subfilter_drain_destroy:
  153|  31.6k|{
  154|  31.6k|    if (!sub->draining && sub->filter) {
  ------------------
  |  Branch (154:9): [True: 31.6k, False: 0]
  |  Branch (154:27): [True: 0, False: 31.6k]
  ------------------
  155|       |        // We know the filter is writable (unless the user created a new filter
  156|       |        // and immediately called this function, which is invalid).
  157|      0|        mp_pin_in_write(sub->filter->pins[0], MP_EOF_FRAME);
  ------------------
  |  |   59|      0|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|      0|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  158|      0|        sub->draining = true;
  159|      0|    }
  160|  31.6k|    return !sub->filter;
  161|  31.6k|}
mp_bidir_nop_filter_create:
  168|  9.76k|{
  169|  9.76k|    struct mp_filter *f = mp_filter_create(parent, &bidir_nop_filter);
  170|  9.76k|    if (!f)
  ------------------
  |  Branch (170:9): [True: 0, False: 9.76k]
  ------------------
  171|      0|        return NULL;
  172|       |
  173|  9.76k|    mp_filter_add_pin(f, MP_PIN_IN, "in");
  174|  9.76k|    mp_filter_add_pin(f, MP_PIN_OUT, "out");
  175|       |
  176|  9.76k|    mp_pin_connect(f->ppins[1], f->ppins[0]);
  177|       |
  178|  9.76k|    return f;
  179|  9.76k|}

mp_filter_internal_mark_progress:
  190|  1.44M|{
  191|  1.44M|    struct filter_runner *r = f->in->runner;
  192|  1.44M|    mp_assert(r->filtering); // only call from f's process()
  ------------------
  |  |   41|  1.44M|#define mp_assert assert
  ------------------
  193|  1.44M|    add_pending(f);
  194|  1.44M|}
mp_filter_graph_run:
  212|  1.20M|{
  213|  1.20M|    struct filter_runner *r = filter->in->runner;
  214|  1.20M|    mp_assert(filter == r->root_filter); // user is supposed to call this on root only
  ------------------
  |  |   41|  1.20M|#define mp_assert assert
  ------------------
  215|       |
  216|  1.20M|    int64_t end_time = 0;
  217|  1.20M|    if (isfinite(r->max_run_time))
  218|   170k|        end_time = mp_time_ns_add(mp_time_ns(), MPMAX(r->max_run_time, 0));
  ------------------
  |  |   43|   170k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 170k, False: 0]
  |  |  ------------------
  ------------------
  219|       |
  220|       |    // (could happen with separate filter graphs calling each other, for now
  221|       |    // ignore this issue as we don't use such a setup anywhere)
  222|  1.20M|    mp_assert(!r->filtering);
  ------------------
  |  |   41|  1.20M|#define mp_assert assert
  ------------------
  223|       |
  224|  1.20M|    r->filtering = true;
  225|       |
  226|  1.20M|    flush_async_notifications(r);
  227|       |
  228|  1.20M|    bool exit_req = false;
  229|       |
  230|  23.0M|    while (1) {
  ------------------
  |  Branch (230:12): [Folded - Ignored]
  ------------------
  231|  23.0M|        if (atomic_exchange_explicit(&r->interrupt_flag, false,
  ------------------
  |  Branch (231:13): [True: 129, False: 23.0M]
  ------------------
  232|  23.0M|                                     memory_order_acq_rel))
  233|    129|        {
  234|    129|            mp_mutex_lock(&r->async_lock);
  ------------------
  |  |  131|    129|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  235|    129|            if (!r->async_wakeup_sent && r->wakeup_cb)
  ------------------
  |  Branch (235:17): [True: 77, False: 52]
  |  Branch (235:42): [True: 77, False: 0]
  ------------------
  236|     77|                r->wakeup_cb(r->wakeup_ctx);
  237|    129|            r->async_wakeup_sent = true;
  238|    129|            mp_mutex_unlock(&r->async_lock);
  ------------------
  |  |  133|    129|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  239|    129|            exit_req = true;
  240|    129|        }
  241|       |
  242|  23.0M|        if (!r->num_pending) {
  ------------------
  |  Branch (242:13): [True: 1.21M, False: 21.8M]
  ------------------
  243|  1.21M|            flush_async_notifications(r);
  244|  1.21M|            if (!r->num_pending)
  ------------------
  |  Branch (244:17): [True: 1.20M, False: 6.40k]
  ------------------
  245|  1.20M|                break;
  246|  1.21M|        }
  247|       |
  248|  21.8M|        struct mp_filter *next = NULL;
  249|       |
  250|  21.8M|        if (r->pending[0]->in->high_priority) {
  ------------------
  |  Branch (250:13): [True: 376k, False: 21.4M]
  ------------------
  251|   376k|            next = r->pending[0];
  252|   376k|            MP_TARRAY_REMOVE_AT(r->pending, r->num_pending, 0);
  ------------------
  |  |  143|   376k|    do {                                            \
  |  |  144|   376k|        size_t at_ = (at);                          \
  |  |  145|   376k|        assert(at_ <= (idxvar));                    \
  |  |  146|   376k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|   376k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|   376k|        (idxvar)--;                                 \
  |  |  149|   376k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  253|  21.4M|        } else if (!exit_req) {
  ------------------
  |  Branch (253:20): [True: 21.4M, False: 18.4E]
  ------------------
  254|  21.4M|            next = r->pending[r->num_pending - 1];
  255|  21.4M|            r->num_pending -= 1;
  256|  21.4M|        }
  257|       |
  258|  21.8M|        if (!next)
  ------------------
  |  Branch (258:13): [True: 128, False: 21.8M]
  ------------------
  259|    128|            break;
  260|       |
  261|  21.8M|        next->in->pending = false;
  262|  21.8M|        if (next->in->info->process)
  ------------------
  |  Branch (262:13): [True: 21.3M, False: 454k]
  ------------------
  263|  21.3M|            next->in->info->process(next);
  264|       |
  265|  21.8M|        if (end_time && mp_time_ns() >= end_time)
  ------------------
  |  Branch (265:13): [True: 20.7M, False: 1.08M]
  |  Branch (265:25): [True: 129, False: 20.7M]
  ------------------
  266|    129|            mp_filter_graph_interrupt(r->root_filter);
  267|  21.8M|    }
  268|       |
  269|  1.20M|    r->filtering = false;
  270|       |
  271|  1.20M|    bool externals = r->external_pending;
  272|  1.20M|    r->external_pending = false;
  273|  1.20M|    return externals;
  274|  1.20M|}
mp_pin_can_transfer_data:
  277|  20.6M|{
  278|  20.6M|    return mp_pin_in_needs_data(dst) && mp_pin_out_request_data(src);
  ------------------
  |  Branch (278:12): [True: 16.3M, False: 4.26M]
  |  Branch (278:41): [True: 6.21M, False: 10.1M]
  ------------------
  279|  20.6M|}
mp_pin_in_needs_data:
  290|  45.0M|{
  291|  45.0M|    mp_assert(p->dir == MP_PIN_IN);
  ------------------
  |  |   41|  45.0M|#define mp_assert assert
  ------------------
  292|  45.0M|    mp_assert(!p->within_conn);
  ------------------
  |  |   41|  45.0M|#define mp_assert assert
  ------------------
  293|  45.0M|    return p->conn && p->conn->manual_connection && p->conn->data_requested;
  ------------------
  |  Branch (293:12): [True: 45.0M, False: 18.4E]
  |  Branch (293:23): [True: 45.0M, False: 18.4E]
  |  Branch (293:53): [True: 39.8M, False: 5.20M]
  ------------------
  294|  45.0M|}
mp_pin_in_write:
  297|  10.3M|{
  298|  10.3M|    if (!mp_pin_in_needs_data(p) || frame.type == MP_FRAME_NONE) {
  ------------------
  |  Branch (298:9): [True: 18.4E, False: 10.3M]
  |  Branch (298:37): [True: 18.4E, False: 10.3M]
  ------------------
  299|      0|        if (frame.type)
  ------------------
  |  Branch (299:13): [True: 0, False: 0]
  ------------------
  300|      0|            MP_ERR(p->owner, "losing frame on %s\n", p->name);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  301|      0|        mp_frame_unref(&frame);
  302|      0|        return false;
  303|      0|    }
  304|  10.3M|    mp_assert(p->conn->data.type == MP_FRAME_NONE);
  ------------------
  |  |   41|  10.3M|#define mp_assert assert
  ------------------
  305|  10.3M|    p->conn->data = frame;
  306|  10.3M|    p->conn->data_requested = false;
  307|  10.3M|    add_pending_pin(p->conn);
  308|  10.3M|    filter_recursive(p);
  309|  10.3M|    return true;
  310|  10.3M|}
mp_pin_out_has_data:
  313|  52.0M|{
  314|  52.0M|    mp_assert(p->dir == MP_PIN_OUT);
  ------------------
  |  |   41|  52.0M|#define mp_assert assert
  ------------------
  315|  52.0M|    mp_assert(!p->within_conn);
  ------------------
  |  |   41|  52.0M|#define mp_assert assert
  ------------------
  316|  52.0M|    return p->conn && p->conn->manual_connection && p->data.type != MP_FRAME_NONE;
  ------------------
  |  Branch (316:12): [True: 52.0M, False: 18.4E]
  |  Branch (316:23): [True: 52.0M, False: 18.4E]
  |  Branch (316:53): [True: 16.9M, False: 35.1M]
  ------------------
  317|  52.0M|}
mp_pin_out_request_data:
  320|  34.2M|{
  321|  34.2M|    if (mp_pin_out_has_data(p))
  ------------------
  |  Branch (321:9): [True: 16.4M, False: 17.7M]
  ------------------
  322|  16.4M|        return true;
  323|  17.8M|    if (p->conn && p->conn->manual_connection) {
  ------------------
  |  Branch (323:9): [True: 17.8M, False: 18.4E]
  |  Branch (323:20): [True: 17.8M, False: 18.4E]
  ------------------
  324|  17.8M|        if (!p->data_requested) {
  ------------------
  |  Branch (324:13): [True: 10.3M, False: 7.42M]
  ------------------
  325|  10.3M|            p->data_requested = true;
  326|  10.3M|            add_pending_pin(p->conn);
  327|  10.3M|        }
  328|  17.8M|        filter_recursive(p);
  329|  17.8M|    }
  330|  17.7M|    return mp_pin_out_has_data(p);
  331|  34.2M|}
mp_pin_out_request_data_next:
  334|   373k|{
  335|   373k|    if (mp_pin_out_request_data(p))
  ------------------
  |  Branch (335:9): [True: 0, False: 373k]
  ------------------
  336|      0|        add_pending_pin(p->conn);
  337|   373k|}
mp_pin_out_read:
  340|  17.1M|{
  341|  17.1M|    if (!mp_pin_out_request_data(p))
  ------------------
  |  Branch (341:9): [True: 6.82M, False: 10.3M]
  ------------------
  342|  6.82M|        return MP_NO_FRAME;
  ------------------
  |  |   58|  6.82M|#define MP_NO_FRAME MAKE_FRAME(0, 0)
  |  |  ------------------
  |  |  |  |   57|  6.82M|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  343|  10.3M|    struct mp_frame res = p->data;
  344|  10.3M|    p->data = MP_NO_FRAME;
  ------------------
  |  |   58|  10.3M|#define MP_NO_FRAME MAKE_FRAME(0, 0)
  |  |  ------------------
  |  |  |  |   57|  10.3M|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  345|  10.3M|    return res;
  346|  17.1M|}
mp_pin_connect:
  438|  56.5k|{
  439|  56.5k|    mp_assert(src->dir == MP_PIN_OUT);
  ------------------
  |  |   41|  56.5k|#define mp_assert assert
  ------------------
  440|  56.5k|    mp_assert(dst->dir == MP_PIN_IN);
  ------------------
  |  |   41|  56.5k|#define mp_assert assert
  ------------------
  441|       |
  442|  56.5k|    if (dst->user_conn == src) {
  ------------------
  |  Branch (442:9): [True: 15.5k, False: 40.9k]
  ------------------
  443|  15.5k|        mp_assert(src->user_conn == dst);
  ------------------
  |  |   41|  15.5k|#define mp_assert assert
  ------------------
  444|  15.5k|        return;
  445|  15.5k|    }
  446|       |
  447|  40.9k|    mp_pin_disconnect(src);
  448|  40.9k|    mp_pin_disconnect(dst);
  449|       |
  450|  40.9k|    src->user_conn = dst;
  451|  40.9k|    dst->user_conn = src;
  452|       |
  453|  40.9k|    init_connection(src);
  454|  40.9k|}
mp_pin_disconnect:
  499|   381k|{
  500|   381k|    if (!mp_pin_is_connected(p))
  ------------------
  |  Branch (500:9): [True: 40.9k, False: 340k]
  ------------------
  501|  40.9k|        return;
  502|       |
  503|   340k|    p->manual_connection = NULL;
  504|       |
  505|   340k|    struct mp_pin *conn = p->user_conn;
  506|   340k|    if (conn) {
  ------------------
  |  Branch (506:9): [True: 40.9k, False: 299k]
  ------------------
  507|  40.9k|        p->user_conn = NULL;
  508|  40.9k|        conn->user_conn = NULL;
  509|  40.9k|        deinit_connection(conn);
  510|  40.9k|    }
  511|       |
  512|   340k|    deinit_connection(p);
  513|   340k|}
mp_pin_is_connected:
  516|   381k|{
  517|   381k|    return p->user_conn || p->manual_connection;
  ------------------
  |  Branch (517:12): [True: 40.9k, False: 340k]
  |  Branch (517:28): [True: 299k, False: 40.9k]
  ------------------
  518|   381k|}
mp_filter_get_info:
  536|  1.36k|{
  537|  1.36k|    return f->in->info;
  538|  1.36k|}
mp_filter_set_high_priority:
  541|  1.36k|{
  542|  1.36k|    f->in->high_priority = pri;
  543|  1.36k|}
mp_filter_get_named_pin:
  552|   149k|{
  553|   214k|    for (int n = 0; n < f->num_pins; n++) {
  ------------------
  |  Branch (553:21): [True: 65.2k, False: 149k]
  ------------------
  554|  65.2k|        if (name && strcmp(f->pins[n]->name, name) == 0)
  ------------------
  |  Branch (554:13): [True: 65.2k, False: 0]
  |  Branch (554:21): [True: 0, False: 65.2k]
  ------------------
  555|      0|            return f->pins[n];
  556|  65.2k|    }
  557|   149k|    return NULL;
  558|   149k|}
mp_filter_set_error_handler:
  561|  7.07M|{
  562|  7.07M|    f->in->error_handler = handler;
  563|  7.07M|}
mp_filter_has_failed:
  578|  7.07M|{
  579|  7.07M|    bool failed = filter->in->failed;
  580|  7.07M|    filter->in->failed = false;
  581|  7.07M|    return failed;
  582|  7.07M|}
mp_filter_reset:
  595|   103k|{
  596|   103k|    if (!filter)
  ------------------
  |  Branch (596:9): [True: 0, False: 103k]
  ------------------
  597|      0|        return;
  598|       |
  599|   104k|    for (int n = 0; n < filter->in->num_children; n++)
  ------------------
  |  Branch (599:21): [True: 1.13k, False: 103k]
  ------------------
  600|  1.13k|        mp_filter_reset(filter->in->children[n]);
  601|       |
  602|   117k|    for (int n = 0; n < filter->num_pins; n++) {
  ------------------
  |  Branch (602:21): [True: 13.8k, False: 103k]
  ------------------
  603|  13.8k|        struct mp_pin *p = filter->ppins[n];
  604|  13.8k|        reset_pin(p);
  605|  13.8k|        reset_pin(p->other);
  606|  13.8k|    }
  607|       |
  608|   103k|    if (filter->in->info->reset)
  ------------------
  |  Branch (608:9): [True: 6.33k, False: 97.0k]
  ------------------
  609|  6.33k|        filter->in->info->reset(filter);
  610|   103k|}
mp_filter_add_pin:
  614|   149k|{
  615|   149k|    mp_assert(dir == MP_PIN_IN || dir == MP_PIN_OUT);
  ------------------
  |  |   41|   149k|#define mp_assert assert
  ------------------
  616|   149k|    mp_assert(name && name[0]);
  ------------------
  |  |   41|   149k|#define mp_assert assert
  ------------------
  617|   149k|    mp_assert(!mp_filter_get_named_pin(f, name));
  ------------------
  |  |   41|   149k|#define mp_assert assert
  ------------------
  618|       |
  619|       |    // "Public" pin
  620|   149k|    struct mp_pin *p = talloc_ptrtype(NULL, p);
  ------------------
  |  |   34|   149k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   149k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   149k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  621|   149k|    *p = (struct mp_pin){
  622|   149k|        .name = talloc_strdup(p, name),
  ------------------
  |  |   50|   149k|#define talloc_strdup                   ta_xstrdup
  ------------------
  623|   149k|        .dir = dir,
  624|   149k|        .owner = f,
  625|   149k|        .manual_connection = f->in->parent,
  626|   149k|    };
  627|       |
  628|       |    // "Private" paired pin
  629|   149k|    p->other = talloc_ptrtype(NULL, p);
  ------------------
  |  |   34|   149k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   149k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   149k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  630|   149k|    *p->other = (struct mp_pin){
  631|   149k|        .name = p->name,
  632|   149k|        .dir = p->dir == MP_PIN_IN ? MP_PIN_OUT : MP_PIN_IN,
  ------------------
  |  Branch (632:16): [True: 68.5k, False: 81.1k]
  ------------------
  633|   149k|        .owner = f,
  634|   149k|        .other = p,
  635|   149k|        .manual_connection = f,
  636|   149k|    };
  637|       |
  638|   149k|    MP_TARRAY_GROW(f, f->pins, f->num_pins);
  ------------------
  |  |   96|   149k|    do {                                            \
  |  |   97|   149k|        size_t nextidx_ = (nextidx);                \
  |  |   98|   149k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|   149k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|   149k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 84.5k, False: 65.2k]
  |  |  ------------------
  |  |   99|   149k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  84.5k|    do {                                                        \
  |  |  |  |   89|  84.5k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  84.5k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  84.5k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  84.5k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  84.5k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  84.5k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  84.5k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|   149k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  639|   149k|    MP_TARRAY_GROW(f, f->ppins, f->num_pins);
  ------------------
  |  |   96|   149k|    do {                                            \
  |  |   97|   149k|        size_t nextidx_ = (nextidx);                \
  |  |   98|   149k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|   149k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|   149k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 84.5k, False: 65.2k]
  |  |  ------------------
  |  |   99|   149k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  84.5k|    do {                                                        \
  |  |  |  |   89|  84.5k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  84.5k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  84.5k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  84.5k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  84.5k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  84.5k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  84.5k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|   149k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  640|   149k|    f->pins[f->num_pins] = p;
  641|   149k|    f->ppins[f->num_pins] = p->other;
  642|   149k|    f->num_pins += 1;
  643|       |
  644|   149k|    init_connection(p);
  645|       |
  646|   149k|    return p->other;
  647|   149k|}
mp_filter_remove_pin:
  650|   149k|{
  651|   149k|    if (!p)
  ------------------
  |  Branch (651:9): [True: 0, False: 149k]
  ------------------
  652|      0|        return;
  653|       |
  654|   149k|    mp_assert(p->owner == f);
  ------------------
  |  |   41|   149k|#define mp_assert assert
  ------------------
  655|   149k|    mp_pin_disconnect(p);
  656|   149k|    mp_pin_disconnect(p->other);
  657|       |
  658|   149k|    int index = -1;
  659|   149k|    for (int n = 0; n < f->num_pins; n++) {
  ------------------
  |  Branch (659:21): [True: 149k, False: 0]
  ------------------
  660|   149k|        if (f->ppins[n] == p) {
  ------------------
  |  Branch (660:13): [True: 149k, False: 0]
  ------------------
  661|   149k|            index = n;
  662|   149k|            break;
  663|   149k|        }
  664|   149k|    }
  665|   149k|    mp_assert(index >= 0);
  ------------------
  |  |   41|   149k|#define mp_assert assert
  ------------------
  666|       |
  667|   149k|    talloc_free(f->pins[index]);
  ------------------
  |  |   47|   149k|#define talloc_free                     ta_free
  ------------------
  668|   149k|    talloc_free(f->ppins[index]);
  ------------------
  |  |   47|   149k|#define talloc_free                     ta_free
  ------------------
  669|       |
  670|   149k|    int count = f->num_pins;
  671|   149k|    MP_TARRAY_REMOVE_AT(f->pins, count, index);
  ------------------
  |  |  143|   149k|    do {                                            \
  |  |  144|   149k|        size_t at_ = (at);                          \
  |  |  145|   149k|        assert(at_ <= (idxvar));                    \
  |  |  146|   149k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|   149k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|   149k|        (idxvar)--;                                 \
  |  |  149|   149k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  672|   149k|    count = f->num_pins;
  673|   149k|    MP_TARRAY_REMOVE_AT(f->ppins, count, index);
  ------------------
  |  |  143|   149k|    do {                                            \
  |  |  144|   149k|        size_t at_ = (at);                          \
  |  |  145|   149k|        assert(at_ <= (idxvar));                    \
  |  |  146|   149k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|   149k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|   149k|        (idxvar)--;                                 \
  |  |  149|   149k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  674|   149k|    f->num_pins -= 1;
  675|   149k|}
mp_filter_command:
  678|  1.96M|{
  679|  1.96M|    return f->in->info->command ? f->in->info->command(f, cmd) : false;
  ------------------
  |  Branch (679:12): [True: 1.05M, False: 904k]
  ------------------
  680|  1.96M|}
mp_filter_find_stream_info:
  683|  20.6k|{
  684|  69.6k|    while (f) {
  ------------------
  |  Branch (684:12): [True: 69.6k, False: 0]
  ------------------
  685|  69.6k|        if (f->stream_info)
  ------------------
  |  Branch (685:13): [True: 20.6k, False: 48.9k]
  ------------------
  686|  20.6k|            return f->stream_info;
  687|  48.9k|        f = f->in->parent;
  688|  48.9k|    }
  689|      0|    return NULL;
  690|  20.6k|}
mp_filter_wakeup:
  726|   771k|{
  727|   771k|    filter_wakeup(f, false);
  728|   771k|}
mp_filter_graph_set_max_run_time:
  736|  94.7k|{
  737|  94.7k|    struct filter_runner *r = f->in->runner;
  738|  94.7k|    mp_assert(f == r->root_filter); // user is supposed to call this on root only
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
  739|  94.7k|    r->max_run_time = seconds;
  740|  94.7k|}
mp_filter_graph_interrupt:
  743|    129|{
  744|    129|    struct filter_runner *r = f->in->runner;
  745|    129|    mp_assert(f == r->root_filter); // user is supposed to call this on root only
  ------------------
  |  |   41|    129|#define mp_assert assert
  ------------------
  746|    129|    atomic_store(&r->interrupt_flag, true);
  747|    129|}
mp_filter_free_children:
  750|   210k|{
  751|   273k|    while(f->in->num_children)
  ------------------
  |  Branch (751:11): [True: 62.6k, False: 210k]
  ------------------
  752|  62.6k|        talloc_free(f->in->children[0]);
  ------------------
  |  |   47|  62.6k|#define talloc_free                     ta_free
  ------------------
  753|   210k|}
mp_filter_create_with_params:
  800|   180k|{
  801|   180k|    struct mp_filter *f = talloc(NULL, struct mp_filter);
  ------------------
  |  |   26|   180k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|   180k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   180k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  802|   180k|    talloc_set_destructor(f, filter_destructor);
  ------------------
  |  |   41|   180k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  803|   180k|    *f = (struct mp_filter){
  804|   180k|        .priv = params->info->priv_size ?
  ------------------
  |  Branch (804:17): [True: 67.9k, False: 112k]
  ------------------
  805|  67.9k|                    talloc_zero_size(f, params->info->priv_size) : NULL,
  ------------------
  |  |   44|  67.9k|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|  67.9k|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|  67.9k|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  67.9k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  67.9k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  67.9k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  806|   180k|        .global = params->global,
  807|   180k|        .packet_pool = demux_packet_pool_get(params->parent ? params->parent->global : params->global),
  ------------------
  |  Branch (807:46): [True: 84.5k, False: 96.1k]
  ------------------
  808|   180k|        .in = talloc(f, struct mp_filter_internal),
  ------------------
  |  |   26|   180k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|   180k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   180k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  809|   180k|    };
  810|   180k|    *f->in = (struct mp_filter_internal){
  811|   180k|        .info = params->info,
  812|   180k|        .parent = params->parent,
  813|   180k|        .runner = params->parent ? params->parent->in->runner : NULL,
  ------------------
  |  Branch (813:19): [True: 84.5k, False: 96.1k]
  ------------------
  814|   180k|    };
  815|       |
  816|   180k|    if (!f->in->runner) {
  ------------------
  |  Branch (816:9): [True: 96.1k, False: 84.5k]
  ------------------
  817|  96.1k|        mp_assert(params->global);
  ------------------
  |  |   41|  96.1k|#define mp_assert assert
  ------------------
  818|       |
  819|  96.1k|        f->in->runner = talloc(NULL, struct filter_runner);
  ------------------
  |  |   26|  96.1k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  96.1k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  96.1k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  820|  96.1k|        *f->in->runner = (struct filter_runner){
  821|  96.1k|            .global = params->global,
  822|  96.1k|            .root_filter = f,
  823|  96.1k|            .max_run_time = INFINITY,
  824|  96.1k|        };
  825|  96.1k|        mp_mutex_init(&f->in->runner->async_lock);
  826|  96.1k|    }
  827|       |
  828|   180k|    if (!f->global)
  ------------------
  |  Branch (828:9): [True: 84.5k, False: 96.1k]
  ------------------
  829|  84.5k|        f->global = f->in->runner->global;
  830|       |
  831|   180k|    if (f->in->parent) {
  ------------------
  |  Branch (831:9): [True: 84.5k, False: 96.1k]
  ------------------
  832|  84.5k|        struct mp_filter_internal *parent = f->in->parent->in;
  833|  84.5k|        MP_TARRAY_APPEND(parent, parent->children, parent->num_children, f);
  ------------------
  |  |  105|  84.5k|    do {                                            \
  |  |  106|  84.5k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  84.5k|    do {                                            \
  |  |  |  |   97|  84.5k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  84.5k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  84.5k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  84.5k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 55.8k, False: 28.6k]
  |  |  |  |  ------------------
  |  |  |  |   99|  84.5k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  55.8k|    do {                                                        \
  |  |  |  |  |  |   89|  55.8k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  55.8k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  55.8k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  55.8k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  55.8k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  55.8k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  55.8k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  84.5k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  84.5k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  84.5k|        (idxvar)++;                                 \
  |  |  109|  84.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  834|  84.5k|        f->log = mp_log_new(f, f->global->log, params->info->name);
  835|  96.1k|    } else {
  836|  96.1k|        f->log = mp_log_new(f, f->global->log, "!root");
  837|  96.1k|    }
  838|       |
  839|   180k|    if (f->in->info->init) {
  ------------------
  |  Branch (839:9): [True: 0, False: 180k]
  ------------------
  840|      0|        if (!f->in->info->init(f, params)) {
  ------------------
  |  Branch (840:13): [True: 0, False: 0]
  ------------------
  841|      0|            talloc_free(f);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  842|      0|            return NULL;
  843|      0|        }
  844|      0|    }
  845|       |
  846|   180k|    return f;
  847|   180k|}
mp_filter_create:
  851|  84.5k|{
  852|  84.5k|    mp_assert(parent);
  ------------------
  |  |   41|  84.5k|#define mp_assert assert
  ------------------
  853|  84.5k|    mp_assert(info);
  ------------------
  |  |   41|  84.5k|#define mp_assert assert
  ------------------
  854|  84.5k|    struct mp_filter_params params = {
  855|  84.5k|        .info = info,
  856|  84.5k|        .parent = parent,
  857|  84.5k|    };
  858|  84.5k|    return mp_filter_create_with_params(&params);
  859|  84.5k|}
mp_filter_create_root:
  868|  96.1k|{
  869|  96.1k|    struct mp_filter_params params = {
  870|  96.1k|        .info = &filter_root,
  871|  96.1k|        .global = global,
  872|  96.1k|    };
  873|  96.1k|    return mp_filter_create_with_params(&params);
  874|  96.1k|}
mp_filter_graph_set_wakeup_cb:
  878|  96.1k|{
  879|  96.1k|    struct filter_runner *r = root->in->runner;
  880|  96.1k|    mp_assert(root == r->root_filter); // user is supposed to call this on root only
  ------------------
  |  |   41|  96.1k|#define mp_assert assert
  ------------------
  881|  96.1k|    mp_mutex_lock(&r->async_lock);
  ------------------
  |  |  131|  96.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  882|  96.1k|    r->wakeup_cb = wakeup_cb;
  883|  96.1k|    r->wakeup_ctx = ctx;
  884|  96.1k|    mp_mutex_unlock(&r->async_lock);
  ------------------
  |  |  133|  96.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  885|  96.1k|}
filter.c:add_pending:
  131|  22.1M|{
  132|  22.1M|    struct filter_runner *r = f->in->runner;
  133|       |
  134|  22.1M|    if (f->in->pending)
  ------------------
  |  Branch (134:9): [True: 314k, False: 21.8M]
  ------------------
  135|   314k|        return;
  136|       |
  137|       |    // This should probably really be some sort of priority queue, but for now
  138|       |    // something naive and dumb does the job too.
  139|  21.8M|    f->in->pending = true;
  140|  21.8M|    if (f->in->high_priority) {
  ------------------
  |  Branch (140:9): [True: 377k, False: 21.4M]
  ------------------
  141|   377k|        MP_TARRAY_INSERT_AT(r, r->pending, r->num_pending, 0, f);
  ------------------
  |  |  115|   377k|    do {                                            \
  |  |  116|   377k|        size_t at_ = (at);                          \
  |  |  117|   377k|        assert(at_ <= (idxvar));                    \
  |  |  118|   377k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|   377k|    do {                                            \
  |  |  |  |   97|   377k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|   377k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|   377k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|   377k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 377k]
  |  |  |  |  ------------------
  |  |  |  |   99|   377k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|   377k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|   377k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|   377k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|   377k|        (idxvar)++;                                 \
  |  |  122|   377k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|   377k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  142|  21.4M|    } else {
  143|  21.4M|        MP_TARRAY_APPEND(r, r->pending, r->num_pending, f);
  ------------------
  |  |  105|  21.4M|    do {                                            \
  |  |  106|  21.4M|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  21.4M|    do {                                            \
  |  |  |  |   97|  21.4M|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  21.4M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  21.4M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  21.4M|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 18.1k, False: 21.4M]
  |  |  |  |  ------------------
  |  |  |  |   99|  21.4M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  18.1k|    do {                                                        \
  |  |  |  |  |  |   89|  18.1k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  18.1k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  18.1k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  18.1k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  18.1k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  18.1k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  18.1k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  21.4M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  21.4M|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  21.4M|        (idxvar)++;                                 \
  |  |  109|  21.4M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  144|  21.4M|    }
  145|  21.8M|}
filter.c:flush_async_notifications:
  199|  2.59M|{
  200|  2.59M|    mp_mutex_lock(&r->async_lock);
  ------------------
  |  |  131|  2.59M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  201|  2.97M|    for (int n = 0; n < r->num_async_pending; n++) {
  ------------------
  |  Branch (201:21): [True: 383k, False: 2.59M]
  ------------------
  202|   383k|        struct mp_filter *f = r->async_pending[n];
  203|   383k|        add_pending(f);
  204|   383k|        f->in->async_pending = false;
  205|   383k|    }
  206|  2.59M|    r->num_async_pending = 0;
  207|  2.59M|    r->async_wakeup_sent = false;
  208|  2.59M|    mp_mutex_unlock(&r->async_lock);
  ------------------
  |  |  133|  2.59M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  209|  2.59M|}
filter.c:add_pending_pin:
  148|  20.7M|{
  149|  20.7M|    struct mp_filter *f = p->manual_connection;
  150|  20.7M|    mp_assert(f);
  ------------------
  |  |   41|  20.7M|#define mp_assert assert
  ------------------
  151|       |
  152|  20.7M|    if (f->in->pending)
  ------------------
  |  Branch (152:9): [True: 753k, False: 19.9M]
  ------------------
  153|   753k|        return;
  154|       |
  155|  19.9M|    add_pending(f);
  156|       |
  157|       |    // Need to tell user that something changed.
  158|  19.9M|    if (f == f->in->runner->root_filter && p != f->in->runner->recursive)
  ------------------
  |  Branch (158:9): [True: 445k, False: 19.5M]
  |  Branch (158:44): [True: 77, False: 445k]
  ------------------
  159|     77|        f->in->runner->external_pending = true;
  160|  19.9M|}
filter.c:filter_recursive:
  169|  28.1M|{
  170|  28.1M|    struct mp_filter *f = p->conn->manual_connection;
  171|  28.1M|    mp_assert(f);
  ------------------
  |  |   41|  28.1M|#define mp_assert assert
  ------------------
  172|  28.1M|    struct filter_runner *r = f->in->runner;
  173|       |
  174|       |    // Never do internal filtering recursively.
  175|  28.1M|    if (r->filtering)
  ------------------
  |  Branch (175:9): [True: 27.0M, False: 1.10M]
  ------------------
  176|  27.0M|        return;
  177|       |
  178|  1.10M|    mp_assert(!r->recursive);
  ------------------
  |  |   41|  1.10M|#define mp_assert assert
  ------------------
  179|  1.11M|    r->recursive = p;
  180|       |
  181|       |    // Also don't lose the pending state, which the user may or may not
  182|       |    // care about.
  183|  1.11M|    r->external_pending |= mp_filter_graph_run(r->root_filter);
  184|       |
  185|  1.11M|    mp_assert(r->recursive == p);
  ------------------
  |  |   41|  1.11M|#define mp_assert assert
  ------------------
  186|  1.11M|    r->recursive = NULL;
  187|  1.11M|}
filter.c:init_connection:
  385|   190k|{
  386|   190k|    struct filter_runner *runner = p->owner->in->runner;
  387|       |
  388|   190k|    if (p->dir == MP_PIN_IN)
  ------------------
  |  Branch (388:9): [True: 68.5k, False: 122k]
  ------------------
  389|  68.5k|        p = p->other;
  390|       |
  391|   190k|    struct mp_pin *in = find_connected_end(p);
  392|   190k|    struct mp_pin *out = find_connected_end(p->other);
  393|       |
  394|       |    // These are the "outer" pins by definition, they have no user connections.
  395|   190k|    mp_assert(!in->user_conn);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  396|   190k|    mp_assert(!out->user_conn);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  397|       |
  398|       |    // This and similar checks enforce the same root filter requirement.
  399|   190k|    if (in->manual_connection)
  ------------------
  |  Branch (399:9): [True: 190k, False: 0]
  ------------------
  400|   190k|        mp_assert(in->manual_connection->in->runner == runner);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  401|   190k|    if (out->manual_connection)
  ------------------
  |  Branch (401:9): [True: 190k, False: 0]
  ------------------
  402|   190k|        mp_assert(out->manual_connection->in->runner == runner);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  403|       |
  404|       |    // Logically, the ends are always manual connections. A pin chain without
  405|       |    // manual connections at the ends is still disconnected (or if this
  406|       |    // attempted to extend an existing connection, becomes dangling and gets
  407|       |    // disconnected).
  408|   190k|    if (!in->manual_connection || !out->manual_connection)
  ------------------
  |  Branch (408:9): [True: 0, False: 190k]
  |  Branch (408:35): [True: 0, False: 190k]
  ------------------
  409|      0|        return;
  410|       |
  411|   190k|    mp_assert(in->dir == MP_PIN_IN);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  412|   190k|    mp_assert(out->dir == MP_PIN_OUT);
  ------------------
  |  |   41|   190k|#define mp_assert assert
  ------------------
  413|       |
  414|   190k|    struct mp_pin *cur = in;
  415|   426k|    while (cur) {
  ------------------
  |  Branch (415:12): [True: 235k, False: 190k]
  ------------------
  416|   235k|        mp_assert(!cur->within_conn && !cur->other->within_conn);
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  417|   235k|        mp_assert(!cur->conn && !cur->other->conn);
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  418|   235k|        mp_assert(!cur->data_requested); // unused for in pins
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  419|   235k|        mp_assert(!cur->data.type); // unused for in pins
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  420|   235k|        mp_assert(!cur->other->data_requested); // unset for unconnected out pins
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  421|   235k|        mp_assert(!cur->other->data.type); // unset for unconnected out pins
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  422|   235k|        mp_assert(cur->owner->in->runner == runner);
  ------------------
  |  |   41|   235k|#define mp_assert assert
  ------------------
  423|   235k|        cur->within_conn = cur->other->within_conn = true;
  424|   235k|        cur = cur->other->user_conn;
  425|   235k|    }
  426|       |
  427|   190k|    in->conn = out;
  428|   190k|    in->within_conn = false;
  429|   190k|    out->conn = in;
  430|   190k|    out->within_conn = false;
  431|       |
  432|       |    // Scheduling so far will be messed up.
  433|   190k|    add_pending(in->manual_connection);
  434|   190k|    add_pending(out->manual_connection);
  435|   190k|}
filter.c:find_connected_end:
  372|   762k|{
  373|   842k|    while (1) {
  ------------------
  |  Branch (373:12): [Folded - Ignored]
  ------------------
  374|   842k|        struct mp_pin *other = p->other;
  375|   842k|        if (!other->user_conn)
  ------------------
  |  Branch (375:13): [True: 762k, False: 79.8k]
  ------------------
  376|   762k|            return other;
  377|  79.8k|        p = other->user_conn;
  378|  79.8k|    }
  379|      0|    MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
  380|      0|}
filter.c:deinit_connection:
  477|   381k|{
  478|   381k|    if (p->dir == MP_PIN_OUT)
  ------------------
  |  Branch (478:9): [True: 190k, False: 190k]
  ------------------
  479|   190k|        p = p->other;
  480|       |
  481|   381k|    p = find_connected_end(p);
  482|       |
  483|   801k|    while (p) {
  ------------------
  |  Branch (483:12): [True: 420k, False: 381k]
  ------------------
  484|   420k|        p->conn = p->other->conn = NULL;
  485|   420k|        p->within_conn = p->other->within_conn = false;
  486|   420k|        mp_assert(!p->other->data_requested); // unused for in pins
  ------------------
  |  |   41|   420k|#define mp_assert assert
  ------------------
  487|   420k|        mp_assert(!p->other->data.type); // unused for in pins
  ------------------
  |  |   41|   420k|#define mp_assert assert
  ------------------
  488|   420k|        p->data_requested = false;
  489|   420k|        if (p->data.type)
  ------------------
  |  Branch (489:13): [True: 0, False: 420k]
  ------------------
  490|   420k|            MP_VERBOSE(p->owner, "dropping frame due to pin disconnect\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  491|   420k|        if (p->data_requested)
  ------------------
  |  Branch (491:13): [True: 0, False: 420k]
  ------------------
  492|   420k|            MP_VERBOSE(p->owner, "dropping request due to pin disconnect\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  493|   420k|        mp_frame_unref(&p->data);
  494|   420k|        p = p->other->user_conn;
  495|   420k|    }
  496|   381k|}
filter.c:reset_pin:
  585|  27.6k|{
  586|  27.6k|    if (!p->conn || p->dir != MP_PIN_OUT) {
  ------------------
  |  Branch (586:9): [True: 0, False: 27.6k]
  |  Branch (586:21): [True: 13.8k, False: 13.8k]
  ------------------
  587|  13.8k|        mp_assert(!p->data.type);
  ------------------
  |  |   41|  13.8k|#define mp_assert assert
  ------------------
  588|  13.8k|        mp_assert(!p->data_requested);
  ------------------
  |  |   41|  13.8k|#define mp_assert assert
  ------------------
  589|  13.8k|    }
  590|  27.6k|    mp_frame_unref(&p->data);
  591|  27.6k|    p->data_requested = false;
  592|  27.6k|}
filter.c:filter_wakeup:
  709|   771k|{
  710|   771k|    struct filter_runner *r = f->in->runner;
  711|   771k|    mp_mutex_lock(&r->async_lock);
  ------------------
  |  |  131|   771k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  712|   771k|    if (!f->in->async_pending) {
  ------------------
  |  Branch (712:9): [True: 383k, False: 388k]
  ------------------
  713|   383k|        f->in->async_pending = true;
  714|       |        // (not using a talloc parent for thread safety reasons)
  715|   383k|        MP_TARRAY_APPEND(NULL, r->async_pending, r->num_async_pending, f);
  ------------------
  |  |  105|   383k|    do {                                            \
  |  |  106|   383k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|   383k|    do {                                            \
  |  |  |  |   97|   383k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|   383k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|   383k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|   383k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.38k, False: 378k]
  |  |  |  |  ------------------
  |  |  |  |   99|   383k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.38k|    do {                                                        \
  |  |  |  |  |  |   89|  4.38k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.38k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.38k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.38k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.38k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.38k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.38k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|   383k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|   383k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|   383k|        (idxvar)++;                                 \
  |  |  109|   383k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  716|   383k|    }
  717|   771k|    if (!mark_only && !r->async_wakeup_sent) {
  ------------------
  |  Branch (717:9): [True: 771k, False: 0]
  |  Branch (717:23): [True: 377k, False: 393k]
  ------------------
  718|   377k|        if (r->wakeup_cb)
  ------------------
  |  Branch (718:13): [True: 376k, False: 1.34k]
  ------------------
  719|   376k|            r->wakeup_cb(r->wakeup_ctx);
  720|   377k|        r->async_wakeup_sent = true;
  721|   377k|    }
  722|   771k|    mp_mutex_unlock(&r->async_lock);
  ------------------
  |  |  133|   771k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  723|   771k|}
filter.c:filter_destructor:
  756|   180k|{
  757|   180k|    struct mp_filter *f = p;
  758|   180k|    struct filter_runner *r = f->in->runner;
  759|       |
  760|   180k|    if (f->in->info->destroy)
  ------------------
  |  Branch (760:9): [True: 72.7k, False: 107k]
  ------------------
  761|  72.7k|        f->in->info->destroy(f);
  762|       |
  763|       |    // For convenience, free child filters.
  764|   180k|    mp_filter_free_children(f);
  765|       |
  766|   330k|    while (f->num_pins)
  ------------------
  |  Branch (766:12): [True: 149k, False: 180k]
  ------------------
  767|   149k|        mp_filter_remove_pin(f, f->ppins[0]);
  768|       |
  769|       |    // Just make sure the filter is not still in the async notifications set.
  770|       |    // There will be no more new notifications at this point (due to destroy()).
  771|   180k|    flush_async_notifications(r);
  772|       |
  773|   269k|    for (int n = 0; n < r->num_pending; n++) {
  ------------------
  |  Branch (773:21): [True: 107k, False: 161k]
  ------------------
  774|   107k|        if (r->pending[n] == f) {
  ------------------
  |  Branch (774:13): [True: 19.1k, False: 88.5k]
  ------------------
  775|  19.1k|            MP_TARRAY_REMOVE_AT(r->pending, r->num_pending, n);
  ------------------
  |  |  143|  19.1k|    do {                                            \
  |  |  144|  19.1k|        size_t at_ = (at);                          \
  |  |  145|  19.1k|        assert(at_ <= (idxvar));                    \
  |  |  146|  19.1k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  19.1k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  19.1k|        (idxvar)--;                                 \
  |  |  149|  19.1k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  776|  19.1k|            break;
  777|  19.1k|        }
  778|   107k|    }
  779|       |
  780|   180k|    if (f->in->parent) {
  ------------------
  |  Branch (780:9): [True: 84.5k, False: 96.1k]
  ------------------
  781|  84.5k|        struct mp_filter_internal *p_in = f->in->parent->in;
  782|   118k|        for (int n = 0; n < p_in->num_children; n++) {
  ------------------
  |  Branch (782:25): [True: 118k, False: 0]
  ------------------
  783|   118k|            if (p_in->children[n] == f) {
  ------------------
  |  Branch (783:17): [True: 84.5k, False: 33.6k]
  ------------------
  784|  84.5k|                MP_TARRAY_REMOVE_AT(p_in->children, p_in->num_children, n);
  ------------------
  |  |  143|  84.5k|    do {                                            \
  |  |  144|  84.5k|        size_t at_ = (at);                          \
  |  |  145|  84.5k|        assert(at_ <= (idxvar));                    \
  |  |  146|  84.5k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  84.5k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  84.5k|        (idxvar)--;                                 \
  |  |  149|  84.5k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  785|  84.5k|                break;
  786|  84.5k|            }
  787|   118k|        }
  788|  84.5k|    }
  789|       |
  790|   180k|    if (r->root_filter == f) {
  ------------------
  |  Branch (790:9): [True: 96.1k, False: 84.5k]
  ------------------
  791|  96.1k|        mp_assert(!f->in->parent);
  ------------------
  |  |   41|  96.1k|#define mp_assert assert
  ------------------
  792|  96.1k|        mp_mutex_destroy(&r->async_lock);
  ------------------
  |  |  130|  96.1k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  793|  96.1k|        talloc_free(r->async_pending);
  ------------------
  |  |   47|  96.1k|#define talloc_free                     ta_free
  ------------------
  794|  96.1k|        talloc_free(r);
  ------------------
  |  |   47|  96.1k|#define talloc_free                     ta_free
  ------------------
  795|  96.1k|    }
  796|   180k|}

mp_frame_is_signaling:
  137|   968k|{
  138|   968k|    return frame_handlers[frame.type].is_signaling;
  139|   968k|}
mp_frame_unref:
  142|   504k|{
  143|   504k|    if (!frame)
  ------------------
  |  Branch (143:9): [True: 0, False: 504k]
  ------------------
  144|      0|        return;
  145|       |
  146|   504k|    if (frame_handlers[frame->type].free)
  ------------------
  |  Branch (146:9): [True: 2.28k, False: 501k]
  ------------------
  147|  2.28k|        frame_handlers[frame->type].free(frame->data);
  148|       |
  149|   504k|    *frame = (struct mp_frame){0};
  150|   504k|}
mp_frame_get_pts:
  164|  3.96M|{
  165|  3.96M|    if (frame_handlers[frame.type].get_pts)
  ------------------
  |  Branch (165:9): [True: 3.92M, False: 38.8k]
  ------------------
  166|  3.92M|        return frame_handlers[frame.type].get_pts(frame.data);
  167|  38.8k|    return MP_NOPTS_VALUE;
  ------------------
  |  |   38|  38.8k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  168|  3.96M|}
mp_frame_approx_size:
  177|   746k|{
  178|   746k|    if (frame_handlers[frame.type].approx_size)
  ------------------
  |  Branch (178:9): [True: 744k, False: 1.34k]
  ------------------
  179|   744k|        return frame_handlers[frame.type].approx_size(frame.data);
  180|  1.34k|    return 0;
  181|   746k|}
frame.c:video_get_pts:
   29|   935k|{
   30|   935k|    return ((struct mp_image *)data)->pts;
   31|   935k|}
frame.c:audio_get_pts:
   59|  2.98M|{
   60|  2.98M|    return mp_aframe_get_pts(data);
   61|  2.98M|}
frame.c:audio_approx_size:
   69|   744k|{
   70|   744k|    return mp_aframe_approx_byte_size(data);
   71|   744k|}

user_filters.c:get_af_desc:
   47|  46.4k|{
   48|  46.4k|    return get_desc_from(af_list, MP_ARRAY_SIZE(af_list), dst, index);
  ------------------
  |  |   48|  46.4k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
   49|  46.4k|}
user_filters.c:get_desc_from:
   14|  75.5k|{
   15|  75.5k|    if (index >= num)
  ------------------
  |  Branch (15:9): [True: 11.6k, False: 63.9k]
  ------------------
   16|  11.6k|        return false;
   17|  63.9k|    const struct mp_user_filter_entry *entry = list[index];
   18|  63.9k|    *dst = entry->desc;
   19|  63.9k|    dst->p = entry;
   20|  63.9k|    return true;
   21|  75.5k|}
user_filters.c:get_vf_desc:
  109|  29.0k|{
  110|  29.0k|    return get_desc_from(vf_list, MP_ARRAY_SIZE(vf_list), dst, index);
  ------------------
  |  |   48|  29.0k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  111|  29.0k|}

fuzzer_loadfile_direct.c:str_startswith:
   43|  5.81k|{
   44|  5.81k|    if (str_len < prefix_len)
  ------------------
  |  Branch (44:9): [True: 0, False: 5.81k]
  ------------------
   45|      0|        return false;
   46|  5.81k|    return !memcmp(str, prefix, prefix_len);
   47|  5.81k|}
fuzzer_loadfile_direct.c:check_error:
   34|  52.2k|{
   35|  52.2k|    if (status < 0) {
  ------------------
  |  Branch (35:9): [True: 0, False: 52.2k]
  ------------------
   36|      0|        fprintf(stderr, "mpv API error: %s\n", mpv_error_string(status));
   37|      0|        exit(1);
   38|      0|    }
   39|  52.2k|}
fuzzer_loadfile_direct.c:player_loop:
   54|  5.81k|{
   55|  5.81k|    bool playing = false;
   56|  5.81k|    bool loaded = false;
   57|  5.81k|    int timeout = -1;
   58|   234k|    while (1) {
  ------------------
  |  Branch (58:12): [Folded - Ignored]
  ------------------
   59|   234k|        mpv_event *event = mpv_wait_event(ctx, timeout);
   60|   234k|        if (timeout == PLAYBACK_TIME_LIMIT && event->event_id == MPV_EVENT_NONE)
  ------------------
  |  |   50|   469k|#define PLAYBACK_TIME_LIMIT 5
  ------------------
  |  Branch (60:13): [True: 26.0k, False: 208k]
  |  Branch (60:47): [True: 0, False: 26.0k]
  ------------------
   61|      0|            break;
   62|   234k|        if (event->event_id == MPV_EVENT_START_FILE)
  ------------------
  |  Branch (62:13): [True: 94.7k, False: 139k]
  ------------------
   63|  94.7k|            loaded = playing = true;
   64|   234k|        if (event->event_id == MPV_EVENT_END_FILE) {
  ------------------
  |  Branch (64:13): [True: 94.7k, False: 139k]
  ------------------
   65|  94.7k|            playing = false;
   66|  94.7k|            timeout = -1;
   67|  94.7k|        }
   68|   234k|        if (playing && event->event_id == MPV_EVENT_PLAYBACK_RESTART)
  ------------------
  |  Branch (68:13): [True: 130k, False: 103k]
  |  Branch (68:24): [True: 2.96k, False: 127k]
  ------------------
   69|  2.96k|            timeout = PLAYBACK_TIME_LIMIT;
  ------------------
  |  |   50|  2.96k|#define PLAYBACK_TIME_LIMIT 5
  ------------------
   70|   234k|        if (loaded && event->event_id == MPV_EVENT_IDLE)
  ------------------
  |  Branch (70:13): [True: 233k, False: 679]
  |  Branch (70:23): [True: 5.81k, False: 228k]
  ------------------
   71|  5.81k|            break;
   72|   234k|    }
   73|  5.81k|}

LLVMFuzzerTestOneInput:
   26|  5.81k|{
   27|  5.81k|    if (size <= 1 || data[size - 1] != '\0')
  ------------------
  |  Branch (27:9): [True: 0, False: 5.81k]
  |  Branch (27:22): [True: 0, False: 5.81k]
  ------------------
   28|      0|        return 0;
   29|       |
   30|       |    // Exclude data with null bytes inside
   31|  5.81k|    if (strlen(data) != size - 1)
  ------------------
  |  Branch (31:9): [True: 0, False: 5.81k]
  ------------------
   32|      0|        return 0;
   33|       |
   34|  5.81k|#ifdef MPV_PROTO
   35|  5.81k|    if (!str_startswith(data, size - 1, MPV_STRINGIFY(MPV_PROTO) "://", sizeof(MPV_STRINGIFY(MPV_PROTO) "://") - 1))
  ------------------
  |  |   31|  5.81k|#define MPV_STRINGIFY(X) MPV_STRINGIFY_(X)
  |  |  ------------------
  |  |  |  |   30|  5.81k|#define MPV_STRINGIFY_(X) #X
  |  |  ------------------
  ------------------
                  if (!str_startswith(data, size - 1, MPV_STRINGIFY(MPV_PROTO) "://", sizeof(MPV_STRINGIFY(MPV_PROTO) "://") - 1))
  ------------------
  |  |   31|  5.81k|#define MPV_STRINGIFY(X) MPV_STRINGIFY_(X)
  |  |  ------------------
  |  |  |  |   30|  5.81k|#define MPV_STRINGIFY_(X) #X
  |  |  ------------------
  ------------------
  |  Branch (35:9): [True: 0, False: 5.81k]
  ------------------
   36|      0|        return 0;
   37|  5.81k|#endif
   38|       |
   39|  5.81k|    mpv_handle *ctx = mpv_create();
   40|  5.81k|    if (!ctx)
  ------------------
  |  Branch (40:9): [True: 0, False: 5.81k]
  ------------------
   41|      0|        exit(1);
   42|       |
   43|  5.81k|    check_error(mpv_set_option_string(ctx, "vo", "null"));
   44|  5.81k|    check_error(mpv_set_option_string(ctx, "ao", "null"));
   45|  5.81k|    check_error(mpv_set_option_string(ctx, "ao-null-untimed", "yes"));
   46|  5.81k|    check_error(mpv_set_option_string(ctx, "untimed", "yes"));
   47|  5.81k|    check_error(mpv_set_option_string(ctx, "video-osd", "no"));
   48|  5.81k|    check_error(mpv_set_option_string(ctx, "msg-level", "all=trace"));
   49|  5.81k|    check_error(mpv_set_option_string(ctx, "network-timeout", "1"));
   50|       |
   51|  5.81k|    check_error(mpv_initialize(ctx));
   52|       |
   53|  5.81k|    const char *cmd[] = {"loadfile", data, NULL};
   54|  5.81k|    check_error(mpv_command(ctx, cmd));
   55|       |
   56|  5.81k|    player_loop(ctx);
   57|       |
   58|  5.81k|    mpv_terminate_destroy(ctx);
   59|       |
   60|  5.81k|    return 0;
   61|  5.81k|}

mp_input_parse_cmd_node:
  293|  11.6k|{
  294|  11.6k|    struct mp_cmd *cmd = talloc_ptrtype(NULL, cmd);
  ------------------
  |  |   34|  11.6k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  11.6k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  295|  11.6k|    talloc_set_destructor(cmd, destroy_cmd);
  ------------------
  |  |   41|  11.6k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  296|  11.6k|    *cmd = (struct mp_cmd) { .scale = 1, .scale_units = 1 };
  297|       |
  298|  11.6k|    bool res = false;
  299|  11.6k|    if (node->format == MPV_FORMAT_NODE_ARRAY) {
  ------------------
  |  Branch (299:9): [True: 11.6k, False: 0]
  ------------------
  300|  11.6k|        res = cmd_node_array(log, cmd, node);
  301|  11.6k|    } else if (node->format == MPV_FORMAT_NODE_MAP) {
  ------------------
  |  Branch (301:16): [True: 0, False: 0]
  ------------------
  302|      0|        res = cmd_node_map(log, cmd, node);
  303|      0|    }
  304|       |
  305|  11.6k|    res = res && finish_cmd(log, cmd);
  ------------------
  |  Branch (305:11): [True: 11.6k, False: 0]
  |  Branch (305:18): [True: 11.6k, False: 0]
  ------------------
  306|       |
  307|  11.6k|    if (!res)
  ------------------
  |  Branch (307:9): [True: 0, False: 11.6k]
  ------------------
  308|      0|        TA_FREEP(&cmd);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  309|       |
  310|  11.6k|    return cmd;
  311|  11.6k|}
mp_input_parse_cmd_str:
  455|  1.11M|{
  456|  1.11M|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  1.11M|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  1.11M|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  457|  1.11M|    bstr original = str;
  458|  1.11M|    struct mp_cmd *cmd = parse_cmd_str(log, tmp, &str, loc);
  459|  1.11M|    if (!cmd)
  ------------------
  |  Branch (459:9): [True: 0, False: 1.11M]
  ------------------
  460|      0|        goto done;
  461|       |
  462|       |    // Handle "multi" commands
  463|  1.11M|    struct mp_cmd **p_prev = NULL;
  464|  1.22M|    while (1) {
  ------------------
  |  Branch (464:12): [Folded - Ignored]
  ------------------
  465|  1.22M|        str = bstr_lstrip(str);
  466|       |        // read_token just to check whether it's trailing whitespace only
  467|  1.22M|        bstr u1, u2;
  468|  1.22M|        if (!bstr_eatstart0(&str, ";") || !read_token(str, &u1, &u2))
  ------------------
  |  Branch (468:13): [True: 1.11M, False: 104k]
  |  Branch (468:43): [True: 0, False: 104k]
  ------------------
  469|  1.11M|            break;
  470|       |        // Multi-command. Since other input.c code uses queue_next for its
  471|       |        // own purposes, a pseudo-command is used to wrap the command list.
  472|   104k|        if (!p_prev) {
  ------------------
  |  Branch (472:13): [True: 75.5k, False: 29.0k]
  ------------------
  473|  75.5k|            struct mp_cmd *list = talloc_ptrtype(NULL, list);
  ------------------
  |  |   34|  75.5k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  75.5k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  75.5k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  474|  75.5k|            talloc_set_destructor(list, destroy_cmd);
  ------------------
  |  |   41|  75.5k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  475|  75.5k|            *list = (struct mp_cmd) {
  476|  75.5k|                .name = (char *)mp_cmd_list.name,
  477|  75.5k|                .def = &mp_cmd_list,
  478|  75.5k|            };
  479|  75.5k|            talloc_steal(list, cmd);
  ------------------
  |  |   38|  75.5k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  75.5k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  480|  75.5k|            struct mp_cmd_arg arg = {0};
  481|  75.5k|            arg.v.p = cmd;
  482|  75.5k|            list->args = talloc_dup(list, &arg);
  ------------------
  |  |   48|  75.5k|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|  75.5k|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  75.5k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  483|  75.5k|            p_prev = &cmd->queue_next;
  484|  75.5k|            cmd = list;
  485|  75.5k|        }
  486|   104k|        struct mp_cmd *sub = parse_cmd_str(log, tmp, &str, loc);
  487|   104k|        if (!sub) {
  ------------------
  |  Branch (487:13): [True: 0, False: 104k]
  ------------------
  488|      0|            talloc_free(cmd);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  489|      0|            cmd = NULL;
  490|      0|            goto done;
  491|      0|        }
  492|   104k|        talloc_steal(cmd, sub);
  ------------------
  |  |   38|   104k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|   104k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  493|   104k|        *p_prev = sub;
  494|   104k|        p_prev = &sub->queue_next;
  495|   104k|    }
  496|       |
  497|  1.11M|    cmd->original = bstrto0(cmd, bstr_strip(
  498|  1.11M|                        bstr_splice(original, 0, str.start - original.start)));
  499|       |
  500|  1.11M|    str = bstr_strip(str);
  501|  1.11M|    if (bstr_eatstart0(&str, "#") && !bstr_startswith0(str, "#")) {
  ------------------
  |  Branch (501:9): [True: 854k, False: 261k]
  |  Branch (501:38): [True: 854k, False: 0]
  ------------------
  502|   854k|        str = bstr_strip(str);
  503|   854k|        if (str.len)
  ------------------
  |  Branch (503:13): [True: 854k, False: 0]
  ------------------
  504|   854k|            cmd->desc = bstrto0(cmd, str);
  505|   854k|    }
  506|       |
  507|  1.11M|done:
  508|  1.11M|    talloc_free(tmp);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
  509|  1.11M|    return cmd;
  510|  1.11M|}
mp_input_parse_cmd_strv:
  513|  11.6k|{
  514|  11.6k|    int count = 0;
  515|  29.0k|    while (argv[count])
  ------------------
  |  Branch (515:12): [True: 17.4k, False: 11.6k]
  ------------------
  516|  17.4k|        count++;
  517|  11.6k|    mpv_node *items = talloc_zero_array(NULL, mpv_node, count);
  ------------------
  |  |   30|  11.6k|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|  11.6k|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  518|  11.6k|    mpv_node_list list = {.values = items, .num = count};
  519|  11.6k|    mpv_node node = {.format = MPV_FORMAT_NODE_ARRAY, .u = {.list = &list}};
  520|  29.0k|    for (int n = 0; n < count; n++) {
  ------------------
  |  Branch (520:21): [True: 17.4k, False: 11.6k]
  ------------------
  521|  17.4k|        items[n] = (mpv_node){.format = MPV_FORMAT_STRING,
  522|  17.4k|                              .u = {.string = (char *)argv[n]}};
  523|  17.4k|    }
  524|  11.6k|    struct mp_cmd *res = mp_input_parse_cmd_node(log, &node);
  525|  11.6k|    talloc_free(items);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
  526|  11.6k|    return res;
  527|  11.6k|}
mp_cmd_dump:
  582|  11.6k|{
  583|  11.6k|    if (!mp_msg_test(log, msgl))
  ------------------
  |  Branch (583:9): [True: 0, False: 11.6k]
  ------------------
  584|      0|        return;
  585|  11.6k|    if (header)
  ------------------
  |  Branch (585:9): [True: 11.6k, False: 0]
  ------------------
  586|  11.6k|        mp_msg(log, msgl, "%s ", header);
  587|  11.6k|    if (!cmd) {
  ------------------
  |  Branch (587:9): [True: 0, False: 11.6k]
  ------------------
  588|      0|        mp_msg(log, msgl, "(NULL)\n");
  589|      0|        return;
  590|      0|    }
  591|  11.6k|    mp_msg(log, msgl, "%s, flags=%d, args=[", cmd->name, cmd->flags);
  592|  11.6k|    int argc = get_arg_count(cmd->def);
  593|  40.6k|    for (int n = 0; n < cmd->nargs; n++) {
  ------------------
  |  Branch (593:21): [True: 29.0k, False: 11.6k]
  ------------------
  594|  29.0k|        const char *argname = cmd->def->args[MPMIN(n, argc - 1)].name;
  ------------------
  |  |   44|  29.0k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 29.0k]
  |  |  ------------------
  ------------------
  595|  29.0k|        char *s = m_option_print(cmd->args[n].type, &cmd->args[n].v);
  596|  29.0k|        if (n)
  ------------------
  |  Branch (596:13): [True: 17.4k, False: 11.6k]
  ------------------
  597|  17.4k|            mp_msg(log, msgl, ", ");
  598|  29.0k|        struct mpv_node node = {
  599|  29.0k|            .format = MPV_FORMAT_STRING,
  600|  29.0k|            .u.string = s ? s : "(NULL)",
  ------------------
  |  Branch (600:25): [True: 29.0k, False: 0]
  ------------------
  601|  29.0k|        };
  602|  29.0k|        char *esc = NULL;
  603|  29.0k|        json_write(&esc, &node);
  604|  29.0k|        mp_msg(log, msgl, "%s=%s", argname, esc ? esc : "<error>");
  ------------------
  |  Branch (604:45): [True: 29.0k, False: 0]
  ------------------
  605|  29.0k|        talloc_free(esc);
  ------------------
  |  |   47|  29.0k|#define talloc_free                     ta_free
  ------------------
  606|  29.0k|        talloc_free(s);
  ------------------
  |  |   47|  29.0k|#define talloc_free                     ta_free
  ------------------
  607|  29.0k|    }
  608|  11.6k|    mp_msg(log, msgl, "]\n");
  609|  11.6k|}
cmd.c:destroy_cmd:
   33|  1.30M|{
   34|  1.30M|    struct mp_cmd *cmd = ptr;
   35|  3.75M|    for (int n = 0; n < cmd->nargs; n++) {
  ------------------
  |  Branch (35:21): [True: 2.44M, False: 1.30M]
  ------------------
   36|  2.44M|        if (cmd->args[n].type)
  ------------------
  |  Branch (36:13): [True: 2.44M, False: 0]
  ------------------
   37|  2.44M|            m_option_free(cmd->args[n].type, &cmd->args[n].v);
   38|  2.44M|    }
   39|  1.30M|}
cmd.c:cmd_node_array:
  205|  11.6k|{
  206|  11.6k|    mp_assert(node->format == MPV_FORMAT_NODE_ARRAY);
  ------------------
  |  |   41|  11.6k|#define mp_assert assert
  ------------------
  207|  11.6k|    mpv_node_list *args = node->u.list;
  208|  11.6k|    int cur = 0;
  209|       |
  210|  11.6k|    while (cur < args->num) {
  ------------------
  |  Branch (210:12): [True: 11.6k, False: 0]
  ------------------
  211|  11.6k|        if (args->values[cur].format != MPV_FORMAT_STRING)
  ------------------
  |  Branch (211:13): [True: 0, False: 11.6k]
  ------------------
  212|      0|            break;
  213|  11.6k|        if (!apply_flag(cmd, bstr0(args->values[cur].u.string)))
  ------------------
  |  Branch (213:13): [True: 11.6k, False: 0]
  ------------------
  214|  11.6k|            break;
  215|      0|        cur++;
  216|      0|    }
  217|       |
  218|  11.6k|    bstr cmd_name = {0};
  219|  11.6k|    if (cur < args->num && args->values[cur].format == MPV_FORMAT_STRING)
  ------------------
  |  Branch (219:9): [True: 11.6k, False: 0]
  |  Branch (219:28): [True: 11.6k, False: 0]
  ------------------
  220|  11.6k|        cmd_name = bstr0(args->values[cur++].u.string);
  221|  11.6k|    if (!find_cmd(log, cmd, cmd_name))
  ------------------
  |  Branch (221:9): [True: 0, False: 11.6k]
  ------------------
  222|      0|        return false;
  223|       |
  224|  11.6k|    int first = cur;
  225|  17.4k|    for (int i = 0; i < args->num - first; i++) {
  ------------------
  |  Branch (225:21): [True: 5.81k, False: 11.6k]
  ------------------
  226|  5.81k|        if (!set_node_arg(log, cmd, cmd->nargs, &args->values[cur++]))
  ------------------
  |  Branch (226:13): [True: 0, False: 5.81k]
  ------------------
  227|      0|            return false;
  228|  5.81k|    }
  229|       |
  230|  11.6k|    return true;
  231|  11.6k|}
cmd.c:apply_flag:
   63|  1.31M|{
   64|  16.0M|    for (int n = 0; cmd_flags[n].name; n++) {
  ------------------
  |  Branch (64:21): [True: 14.8M, False: 1.23M]
  ------------------
   65|  14.8M|        if (bstr_equals0(str, cmd_flags[n].name)) {
  ------------------
  |  Branch (65:13): [True: 81.3k, False: 14.7M]
  ------------------
   66|  81.3k|            cmd->flags = (cmd->flags & ~cmd_flags[n].remove) | cmd_flags[n].add;
   67|  81.3k|            return true;
   68|  81.3k|        }
   69|  14.8M|    }
   70|  1.23M|    return false;
   71|  1.31M|}
cmd.c:find_cmd:
   74|  1.23M|{
   75|  1.23M|    if (name.len == 0) {
  ------------------
  |  Branch (75:9): [True: 0, False: 1.23M]
  ------------------
   76|      0|        mp_err(log, "Command name missing.\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
   77|      0|        return false;
   78|      0|    }
   79|       |
   80|  1.23M|    char nname[80];
   81|  1.23M|    snprintf(nname, sizeof(nname), "%.*s", BSTR_P(name));
  ------------------
  |  |  283|  1.23M|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 1.23M, False: 0]
  |  |  ------------------
  ------------------
   82|  8.59M|    for (int n = 0; nname[n]; n++) {
  ------------------
  |  Branch (82:21): [True: 7.36M, False: 1.23M]
  ------------------
   83|  7.36M|        if (nname[n] == '_')
  ------------------
  |  Branch (83:13): [True: 0, False: 7.36M]
  ------------------
   84|      0|            nname[n] = '-';
   85|  7.36M|    }
   86|       |
   87|  49.2M|    for (int n = 0; mp_cmds[n].name; n++) {
  ------------------
  |  Branch (87:21): [True: 49.2M, False: 0]
  ------------------
   88|  49.2M|        if (strcmp(nname, mp_cmds[n].name) == 0) {
  ------------------
  |  Branch (88:13): [True: 1.23M, False: 47.9M]
  ------------------
   89|  1.23M|            cmd->def = &mp_cmds[n];
   90|  1.23M|            cmd->name = (char *)cmd->def->name;
   91|  1.23M|            return true;
   92|  1.23M|        }
   93|  49.2M|    }
   94|      0|    mp_err(log, "Command '%.*s' not found.\n", BSTR_P(name));
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   95|      0|    return false;
   96|  1.23M|}
cmd.c:set_node_arg:
  161|  5.81k|{
  162|  5.81k|    const char *name = get_arg_name(cmd->def, i);
  ------------------
  |  |  123|  5.81k|    ((i) < MP_CMD_DEF_MAX_ARGS && (cmd)->args[(i)].name &&      \
  |  |  ------------------
  |  |  |  |   26|  11.6k|#define MP_CMD_DEF_MAX_ARGS 11
  |  |  ------------------
  |  |  |  Branch (123:6): [True: 5.81k, False: 0]
  |  |  |  Branch (123:35): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |  124|  5.81k|     (cmd)->args[(i)].name[0]                                   \
  |  |  ------------------
  |  |  |  Branch (124:6): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |  125|  5.81k|     ? (cmd)->args[(i)].name : mp_tprintf(10, "%d", (i) + 1))
  |  |  ------------------
  |  |  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  |  |  ------------------
  ------------------
  163|       |
  164|  5.81k|    const struct m_option *opt = get_arg_type(cmd->def, i);
  165|  5.81k|    if (!opt) {
  ------------------
  |  Branch (165:9): [True: 0, False: 5.81k]
  ------------------
  166|      0|        mp_err(log, "Command %s: has only %d arguments.\n", cmd->name, i);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  167|      0|        return false;
  168|      0|    }
  169|       |
  170|  5.81k|    if (i < cmd->nargs && cmd->args[i].type) {
  ------------------
  |  Branch (170:9): [True: 0, False: 5.81k]
  |  Branch (170:27): [True: 0, False: 0]
  ------------------
  171|      0|        mp_err(log, "Command %s: argument %s was already set.\n", cmd->name, name);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  172|      0|        return false;
  173|      0|    }
  174|       |
  175|  5.81k|    struct mp_cmd_arg arg = {.type = opt};
  176|  5.81k|    void *dst = &arg.v;
  177|  5.81k|    if (val->format == MPV_FORMAT_STRING) {
  ------------------
  |  Branch (177:9): [True: 5.81k, False: 0]
  ------------------
  178|  5.81k|        int r = m_option_parse(log, opt, bstr0(cmd->name),
  179|  5.81k|                                bstr0(val->u.string), dst);
  180|  5.81k|        if (r < 0) {
  ------------------
  |  Branch (180:13): [True: 0, False: 5.81k]
  ------------------
  181|      0|            mp_err(log, "Command %s: argument %s can't be parsed: %s.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  182|      0|                   cmd->name, name, m_option_strerror(r));
  183|      0|            return false;
  184|      0|        }
  185|  5.81k|    } else {
  186|      0|        int r = m_option_set_node(opt, dst, val);
  187|      0|        if (r < 0) {
  ------------------
  |  Branch (187:13): [True: 0, False: 0]
  ------------------
  188|      0|            mp_err(log, "Command %s: argument %s has incompatible type.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  189|      0|                   cmd->name, name);
  190|      0|            return false;
  191|      0|        }
  192|      0|    }
  193|       |
  194|       |    // (leave unset arguments blank, to be set later or checked by finish_cmd())
  195|  11.6k|    while (i >= cmd->nargs) {
  ------------------
  |  Branch (195:12): [True: 5.81k, False: 5.81k]
  ------------------
  196|  5.81k|        struct mp_cmd_arg t = {0};
  197|  5.81k|        MP_TARRAY_APPEND(cmd, cmd->args, cmd->nargs, t);
  ------------------
  |  |  105|  5.81k|    do {                                            \
  |  |  106|  5.81k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.81k|    do {                                            \
  |  |  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  5.81k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  5.81k|        (idxvar)++;                                 \
  |  |  109|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  198|  5.81k|    }
  199|       |
  200|  5.81k|    cmd->args[i] = arg;
  201|  5.81k|    return true;
  202|  5.81k|}
cmd.c:get_arg_type:
  104|  4.89M|{
  105|  4.89M|    const struct m_option *opt = NULL;
  106|  4.89M|    if (is_vararg(cmd, i)) {
  ------------------
  |  Branch (106:9): [True: 98.7k, False: 4.79M]
  ------------------
  107|       |        // The last arg in a vararg command sets all vararg types.
  108|   197k|        for (int n = MPMIN(i, MP_CMD_DEF_MAX_ARGS - 1); n >= 0; n--) {
  ------------------
  |  |   44|  98.7k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 98.7k]
  |  |  ------------------
  ------------------
  |  Branch (108:57): [True: 197k, False: 0]
  ------------------
  109|   197k|            if (cmd->args[n].type) {
  ------------------
  |  Branch (109:17): [True: 98.7k, False: 98.7k]
  ------------------
  110|  98.7k|                opt = &cmd->args[n];
  111|  98.7k|                break;
  112|  98.7k|            }
  113|   197k|        }
  114|  4.79M|    } else if (i < MP_CMD_DEF_MAX_ARGS) {
  ------------------
  |  |   26|  4.79M|#define MP_CMD_DEF_MAX_ARGS 11
  ------------------
  |  Branch (114:16): [True: 4.79M, False: 0]
  ------------------
  115|  4.79M|        opt = &cmd->args[i];
  116|  4.79M|    }
  117|  4.89M|    return opt && opt->type ? opt : NULL;
  ------------------
  |  Branch (117:12): [True: 4.89M, False: 0]
  |  Branch (117:19): [True: 2.99M, False: 1.90M]
  ------------------
  118|  4.89M|}
cmd.c:is_vararg:
   99|  5.53M|{
  100|  5.53M|    return m->vararg && (i + 1 >= MP_CMD_DEF_MAX_ARGS || !m->args[i + 1].type);
  ------------------
  |  |   26|   371k|#define MP_CMD_DEF_MAX_ARGS 11
  ------------------
  |  Branch (100:12): [True: 185k, False: 5.35M]
  |  Branch (100:26): [True: 0, False: 185k]
  |  Branch (100:58): [True: 127k, False: 58.1k]
  ------------------
  101|  5.53M|}
cmd.c:finish_cmd:
  129|  1.23M|{
  130|  3.67M|    for (int i = 0; i < MP_CMD_DEF_MAX_ARGS; i++) {
  ------------------
  |  |   26|  3.67M|#define MP_CMD_DEF_MAX_ARGS 11
  ------------------
  |  Branch (130:21): [True: 3.67M, False: 0]
  ------------------
  131|       |        // (type==NULL is used for yet unset arguments)
  132|  3.67M|        if (i < cmd->nargs && cmd->args[i].type)
  ------------------
  |  Branch (132:13): [True: 1.83M, False: 1.84M]
  |  Branch (132:31): [True: 1.83M, False: 0]
  ------------------
  133|  1.83M|            continue;
  134|  1.84M|        const struct m_option *opt = get_arg_type(cmd->def, i);
  135|  1.84M|        if (i >= cmd->nargs && (!opt || is_vararg(cmd->def, i)))
  ------------------
  |  Branch (135:13): [True: 1.84M, False: 0]
  |  Branch (135:33): [True: 1.20M, False: 639k]
  |  Branch (135:41): [True: 29.0k, False: 610k]
  ------------------
  136|  1.23M|            break;
  137|   610k|        if (!opt->defval && !(opt->flags & MP_CMD_OPT_ARG)) {
  ------------------
  |  |   27|   238k|#define MP_CMD_OPT_ARG M_OPT_OPTIONAL_PARAM
  |  |  ------------------
  |  |  |  |  485|   238k|#define M_OPT_OPTIONAL_PARAM    (UINT64_C(1) << 54)
  |  |  ------------------
  ------------------
  |  Branch (137:13): [True: 238k, False: 371k]
  |  Branch (137:29): [True: 0, False: 238k]
  ------------------
  138|      0|            mp_err(log, "Command %s: required argument %s not set.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  139|      0|                   cmd->name, get_arg_name(cmd->def, i));
  140|      0|            return false;
  141|      0|        }
  142|   610k|        struct mp_cmd_arg arg = {.type = opt};
  143|   610k|        if (opt->defval)
  ------------------
  |  Branch (143:13): [True: 371k, False: 238k]
  ------------------
  144|   371k|            m_option_copy(opt, &arg.v, opt->defval);
  145|   610k|        mp_assert(i <= cmd->nargs);
  ------------------
  |  |   41|   610k|#define mp_assert assert
  ------------------
  146|   610k|        if (i == cmd->nargs) {
  ------------------
  |  Branch (146:13): [True: 610k, False: 0]
  ------------------
  147|   610k|            MP_TARRAY_APPEND(cmd, cmd->args, cmd->nargs, arg);
  ------------------
  |  |  105|   610k|    do {                                            \
  |  |  106|   610k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|   610k|    do {                                            \
  |  |  |  |   97|   610k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|   610k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|   610k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|   610k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 215k, False: 395k]
  |  |  |  |  ------------------
  |  |  |  |   99|   610k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|   215k|    do {                                                        \
  |  |  |  |  |  |   89|   215k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|   215k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|   215k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|   215k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|   215k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|   215k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|   215k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|   610k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|   610k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|   610k|        (idxvar)++;                                 \
  |  |  109|   610k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  148|   610k|        } else {
  149|      0|            cmd->args[i] = arg;
  150|      0|        }
  151|   610k|    }
  152|       |
  153|  1.23M|    if (!(cmd->flags & (MP_ASYNC_CMD | MP_SYNC_CMD)))
  ------------------
  |  Branch (153:9): [True: 1.23M, False: 0]
  ------------------
  154|  1.23M|        cmd->flags |= cmd->def->default_async ? MP_ASYNC_CMD : MP_SYNC_CMD;
  ------------------
  |  Branch (154:23): [True: 0, False: 1.23M]
  ------------------
  155|       |
  156|  1.23M|    return true;
  157|  1.23M|}
cmd.c:parse_cmd_str:
  374|  1.22M|{
  375|  1.22M|    struct parse_ctx *ctx = &(struct parse_ctx){
  376|  1.22M|        .log = log,
  377|  1.22M|        .tmp = tmp,
  378|  1.22M|        .str = *str,
  379|  1.22M|        .start = *str,
  380|  1.22M|    };
  381|       |
  382|  1.22M|    struct mp_cmd *cmd = talloc_ptrtype(NULL, cmd);
  ------------------
  |  |   34|  1.22M|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  1.22M|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.22M|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  383|  1.22M|    talloc_set_destructor(cmd, destroy_cmd);
  ------------------
  |  |   41|  1.22M|#define talloc_set_destructor           ta_set_destructor
  ------------------
  384|  1.22M|    *cmd = (struct mp_cmd) {
  385|  1.22M|        .flags = MP_ON_OSD_AUTO | MP_EXPAND_PROPERTIES,
  386|  1.22M|        .scale = 1,
  387|  1.22M|        .scale_units = 1,
  388|  1.22M|    };
  389|       |
  390|  1.22M|    ctx->str = bstr_lstrip(ctx->str);
  391|       |
  392|  1.22M|    bstr cur_token;
  393|  1.22M|    if (pctx_read_token(ctx, &cur_token) < 0)
  ------------------
  |  Branch (393:9): [True: 0, False: 1.22M]
  ------------------
  394|      0|        goto error;
  395|       |
  396|  1.30M|    while (1) {
  ------------------
  |  Branch (396:12): [Folded - Ignored]
  ------------------
  397|  1.30M|        if (!apply_flag(cmd, cur_token))
  ------------------
  |  Branch (397:13): [True: 1.22M, False: 81.3k]
  ------------------
  398|  1.22M|            break;
  399|  81.3k|        if (pctx_read_token(ctx, &cur_token) < 0)
  ------------------
  |  Branch (399:13): [True: 0, False: 81.3k]
  ------------------
  400|      0|            goto error;
  401|  81.3k|    }
  402|       |
  403|  1.22M|    if (!find_cmd(ctx->log, cmd, cur_token))
  ------------------
  |  Branch (403:9): [True: 0, False: 1.22M]
  ------------------
  404|      0|        goto error;
  405|       |
  406|  3.05M|    for (int i = 0; i < MP_CMD_MAX_ARGS; i++) {
  ------------------
  |  |   86|  3.05M|#define MP_CMD_MAX_ARGS 100
  ------------------
  |  Branch (406:21): [True: 3.05M, False: 0]
  ------------------
  407|  3.05M|        const struct m_option *opt = get_arg_type(cmd->def, i);
  408|  3.05M|        if (!opt)
  ------------------
  |  Branch (408:13): [True: 697k, False: 2.35M]
  ------------------
  409|   697k|            break;
  410|       |
  411|  2.35M|        int r = pctx_read_token(ctx, &cur_token);
  412|  2.35M|        if (r < 0) {
  ------------------
  |  Branch (412:13): [True: 0, False: 2.35M]
  ------------------
  413|      0|            MP_ERR(ctx, "Command %s: error in argument %d.\n", cmd->name, i + 1);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  414|      0|            goto error;
  415|      0|        }
  416|  2.35M|        if (r < 1)
  ------------------
  |  Branch (416:13): [True: 522k, False: 1.83M]
  ------------------
  417|   522k|            break;
  418|       |
  419|  1.83M|        struct mp_cmd_arg arg = {.type = opt};
  420|  1.83M|        r = m_option_parse(ctx->log, opt, bstr0(cmd->name), cur_token, &arg.v);
  421|  1.83M|        if (r < 0) {
  ------------------
  |  Branch (421:13): [True: 0, False: 1.83M]
  ------------------
  422|      0|            MP_ERR(ctx, "Command %s: argument %d can't be parsed: %s.\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  423|      0|                   cmd->name, i + 1, m_option_strerror(r));
  424|      0|            goto error;
  425|      0|        }
  426|       |
  427|  1.83M|        MP_TARRAY_APPEND(cmd, cmd->args, cmd->nargs, arg);
  ------------------
  |  |  105|  1.83M|    do {                                            \
  |  |  106|  1.83M|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.83M|    do {                                            \
  |  |  |  |   97|  1.83M|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.83M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.83M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.83M|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 1.12M, False: 708k]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.83M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  1.12M|    do {                                                        \
  |  |  |  |  |  |   89|  1.12M|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  1.12M|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  1.12M|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  1.12M|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  1.12M|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  1.12M|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  1.12M|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.83M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.83M|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.83M|        (idxvar)++;                                 \
  |  |  109|  1.83M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  428|  1.83M|    }
  429|       |
  430|  1.22M|    if (!finish_cmd(ctx->log, cmd))
  ------------------
  |  Branch (430:9): [True: 0, False: 1.22M]
  ------------------
  431|      0|        goto error;
  432|       |
  433|  1.22M|    bstr dummy;
  434|  1.22M|    if (read_token(ctx->str, &dummy, &dummy) && ctx->str.len) {
  ------------------
  |  Branch (434:9): [True: 0, False: 1.22M]
  |  Branch (434:49): [True: 0, False: 0]
  ------------------
  435|      0|        MP_ERR(ctx, "Command %s has trailing unused arguments: '%.*s'.\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  436|      0|               cmd->name, BSTR_P(ctx->str));
  437|       |        // Better make it fatal to make it clear something is wrong.
  438|      0|        goto error;
  439|      0|    }
  440|       |
  441|  1.22M|    bstr orig = {ctx->start.start, ctx->str.start - ctx->start.start};
  442|  1.22M|    cmd->original = bstrto0(cmd, bstr_strip(orig));
  443|       |
  444|  1.22M|    *str = ctx->str;
  445|  1.22M|    return cmd;
  446|       |
  447|      0|error:
  448|      0|    MP_ERR(ctx, "Command was defined at %s.\n", loc);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  449|      0|    talloc_free(cmd);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  450|      0|    *str = ctx->str;
  451|      0|    return NULL;
  452|  1.22M|}
cmd.c:pctx_read_token:
  331|  3.65M|{
  332|  3.65M|    *out = (bstr){0};
  333|  3.65M|    ctx->str = bstr_lstrip(ctx->str);
  334|  3.65M|    bstr start = ctx->str;
  335|  3.65M|    if (bstr_eatstart0(&ctx->str, "\"")) {
  ------------------
  |  Branch (335:9): [True: 58.1k, False: 3.59M]
  ------------------
  336|  58.1k|        if (!mp_append_escaped_string_noalloc(ctx->tmp, out, &ctx->str)) {
  ------------------
  |  Branch (336:13): [True: 0, False: 58.1k]
  ------------------
  337|      0|            MP_ERR(ctx, "Broken string escapes: ...>%.*s<.\n", BSTR_P(start));
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  338|      0|            return -1;
  339|      0|        }
  340|  58.1k|        if (!bstr_eatstart0(&ctx->str, "\"")) {
  ------------------
  |  Branch (340:13): [True: 0, False: 58.1k]
  ------------------
  341|      0|            MP_ERR(ctx, "Unterminated double quote: ...>%.*s<.\n", BSTR_P(start));
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  342|      0|            return -1;
  343|      0|        }
  344|  58.1k|        return 1;
  345|  58.1k|    }
  346|  3.59M|    if (bstr_eatstart0(&ctx->str, "'")) {
  ------------------
  |  Branch (346:9): [True: 5.81k, False: 3.59M]
  ------------------
  347|  5.81k|        int next = bstrchr(ctx->str, '\'');
  348|  5.81k|        if (next < 0) {
  ------------------
  |  Branch (348:13): [True: 0, False: 5.81k]
  ------------------
  349|      0|            MP_ERR(ctx, "Unterminated single quote: ...>%.*s<.\n", BSTR_P(start));
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  350|      0|            return -1;
  351|      0|        }
  352|  5.81k|        *out = bstr_splice(ctx->str, 0, next);
  353|  5.81k|        ctx->str = bstr_cut(ctx->str, next+1);
  354|  5.81k|        return 1;
  355|  5.81k|    }
  356|  3.59M|    if (ctx->start.len > 1 && bstr_eatstart0(&ctx->str, "`")) {
  ------------------
  |  Branch (356:9): [True: 3.59M, False: 0]
  |  Branch (356:31): [True: 0, False: 3.59M]
  ------------------
  357|      0|        char endquote[2] = {ctx->str.start[0], '`'};
  358|      0|        ctx->str = bstr_cut(ctx->str, 1);
  359|      0|        int next = bstr_find(ctx->str, (bstr){endquote, 2});
  360|      0|        if (next < 0) {
  ------------------
  |  Branch (360:13): [True: 0, False: 0]
  ------------------
  361|      0|            MP_ERR(ctx, "Unterminated custom quote: ...>%.*s<.\n", BSTR_P(start));
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  362|      0|            return -1;
  363|      0|        }
  364|      0|        *out = bstr_splice(ctx->str, 0, next);
  365|      0|        ctx->str = bstr_cut(ctx->str, next+2);
  366|      0|        return 1;
  367|      0|    }
  368|       |
  369|  3.59M|    return read_token(ctx->str, &ctx->str, out) ? 1 : 0;
  ------------------
  |  Branch (369:12): [True: 3.06M, False: 522k]
  ------------------
  370|  3.59M|}
cmd.c:read_token:
  314|  4.91M|{
  315|  4.91M|    bstr t = bstr_lstrip(str);
  316|  4.91M|    int next = bstrcspn(t, WHITESPACE "#;");
  ------------------
  |  |  285|  4.91M|#define WHITESPACE " \f\n\r\t\v"
  ------------------
  317|  4.91M|    if (!next)
  ------------------
  |  Branch (317:9): [True: 1.74M, False: 3.17M]
  ------------------
  318|  1.74M|        return false;
  319|  3.17M|    *out_token = bstr_splice(t, 0, next);
  320|  3.17M|    *out_rest = bstr_cut(t, next);
  321|  3.17M|    return true;
  322|  4.91M|}
cmd.c:get_arg_count:
  573|  11.6k|{
  574|   110k|    for (int i = MP_CMD_DEF_MAX_ARGS - 1; i >= 0; i--) {
  ------------------
  |  |   26|  11.6k|#define MP_CMD_DEF_MAX_ARGS 11
  ------------------
  |  Branch (574:43): [True: 110k, False: 0]
  ------------------
  575|   110k|        if (cmd->args[i].type)
  ------------------
  |  Branch (575:13): [True: 11.6k, False: 98.7k]
  ------------------
  576|  11.6k|            return i + 1;
  577|   110k|    }
  578|      0|    return 0;
  579|  11.6k|}

mp_input_set_mouse_transform:
  864|  2.78k|{
  865|  2.78k|    input_lock(ictx);
  ------------------
  |  |   56|  2.78k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  2.78k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
  866|  2.78k|    ictx->mouse_mangle = dst || src;
  ------------------
  |  Branch (866:26): [True: 0, False: 2.78k]
  |  Branch (866:33): [True: 0, False: 2.78k]
  ------------------
  867|  2.78k|    if (ictx->mouse_mangle) {
  ------------------
  |  Branch (867:9): [True: 0, False: 2.78k]
  ------------------
  868|      0|        ictx->mouse_dst = *dst;
  869|      0|        ictx->mouse_src_mangle = !!src;
  870|      0|        if (ictx->mouse_src_mangle)
  ------------------
  |  Branch (870:13): [True: 0, False: 0]
  ------------------
  871|      0|            ictx->mouse_src = *src;
  872|      0|    }
  873|  2.78k|    input_unlock(ictx);
  ------------------
  |  |   57|  2.78k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  2.78k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
  874|  2.78k|}
mp_input_get_mouse_event_counter:
 1108|  85.4k|{
 1109|       |    // Make the frontend always display the mouse cursor (as long as it's not
 1110|       |    // forced invisible) if mouse input is desired.
 1111|  85.4k|    input_lock(ictx);
  ------------------
  |  |   56|  85.4k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  85.4k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1112|  85.4k|    if (test_mouse_active(ictx, ictx->mouse_x, ictx->mouse_y))
  ------------------
  |  Branch (1112:9): [True: 0, False: 85.4k]
  ------------------
 1113|      0|        ictx->mouse_event_counter++;
 1114|  85.4k|    int ret = ictx->mouse_event_counter;
 1115|  85.4k|    input_unlock(ictx);
  ------------------
  |  |   57|  85.4k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  85.4k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1116|  85.4k|    return ret;
 1117|  85.4k|}
mp_input_get_delay:
 1174|   137k|{
 1175|   137k|    input_lock(ictx);
  ------------------
  |  |   56|   137k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|   137k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1176|   137k|    double seconds = INFINITY;
 1177|   137k|    adjust_max_wait_time(ictx, &seconds);
 1178|   137k|    input_unlock(ictx);
  ------------------
  |  |   57|   137k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|   137k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1179|   137k|    return seconds;
 1180|   137k|}
mp_input_read_cmd:
 1188|   137k|{
 1189|   137k|    input_lock(ictx);
  ------------------
  |  |   56|   137k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|   137k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1190|   137k|    struct mp_cmd *ret = queue_remove_head(&ictx->cmd_queue);
 1191|   137k|    if (!ret)
  ------------------
  |  Branch (1191:9): [True: 137k, False: 0]
  ------------------
 1192|   137k|        ret = check_autorepeat(ictx);
 1193|   137k|    if (ret && ret->mouse_move) {
  ------------------
  |  Branch (1193:9): [True: 0, False: 137k]
  |  Branch (1193:16): [True: 0, False: 0]
  ------------------
 1194|      0|        ictx->mouse_x = ret->mouse_x;
 1195|      0|        ictx->mouse_y = ret->mouse_y;
 1196|      0|    }
 1197|   137k|    input_unlock(ictx);
  ------------------
  |  |   57|   137k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|   137k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1198|   137k|    return ret;
 1199|   137k|}
mp_input_enable_section:
 1240|  5.81k|{
 1241|  5.81k|    bstr bname = bstr0(name);
 1242|  5.81k|    input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1243|  5.81k|    bname = normalize_section(ictx, bname);
 1244|       |
 1245|  5.81k|    disable_section(ictx, bname);
 1246|       |
 1247|  5.81k|    MP_TRACE(ictx, "enable section '%.*s'\n", BSTR_P(bname));
  ------------------
  |  |   90|  5.81k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  11.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1248|       |
 1249|  5.81k|    int top = ictx->num_active_sections;
 1250|  5.81k|    if (!(flags & MP_INPUT_ON_TOP)) {
  ------------------
  |  Branch (1250:9): [True: 5.81k, False: 0]
  ------------------
 1251|       |        // insert before the first top entry
 1252|  5.81k|        for (top = 0; top < ictx->num_active_sections; top++) {
  ------------------
  |  Branch (1252:23): [True: 0, False: 5.81k]
  ------------------
 1253|      0|            if (ictx->active_sections[top].flags & MP_INPUT_ON_TOP)
  ------------------
  |  Branch (1253:17): [True: 0, False: 0]
  ------------------
 1254|      0|                break;
 1255|      0|        }
 1256|  5.81k|    }
 1257|  5.81k|    MP_TARRAY_INSERT_AT(ictx, ictx->active_sections, ictx->num_active_sections,
  ------------------
  |  |  115|  5.81k|    do {                                            \
  |  |  116|  5.81k|        size_t at_ = (at);                          \
  |  |  117|  5.81k|        assert(at_ <= (idxvar));                    \
  |  |  118|  5.81k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.81k|    do {                                            \
  |  |  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|  5.81k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|  5.81k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|  5.81k|        (idxvar)++;                                 \
  |  |  122|  5.81k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1258|  5.81k|                        top, (struct active_section){bname, flags});
 1259|       |
 1260|  5.81k|    MP_TRACE(ictx, "active section stack:\n");
  ------------------
  |  |   90|  5.81k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.81k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1261|  11.6k|    for (int n = 0; n < ictx->num_active_sections; n++) {
  ------------------
  |  Branch (1261:21): [True: 5.81k, False: 5.81k]
  ------------------
 1262|  5.81k|        MP_TRACE(ictx, " %.*s %d\n", BSTR_P(ictx->active_sections[n].name),
  ------------------
  |  |   90|  5.81k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  11.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1263|  5.81k|                 ictx->active_sections[n].flags);
 1264|  5.81k|    }
 1265|       |
 1266|  5.81k|    input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1267|  5.81k|}
mp_input_remove_sections_by_owner:
 1332|  5.81k|{
 1333|  5.81k|    input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1334|  17.4k|    for (int n = 0; n < ictx->num_sections; n++) {
  ------------------
  |  Branch (1334:21): [True: 11.6k, False: 5.81k]
  ------------------
 1335|  11.6k|        struct cmd_bind_section *bs = ictx->sections[n];
 1336|  11.6k|        if (bs->owner && owner && strcmp(bs->owner, owner) == 0) {
  ------------------
  |  Branch (1336:13): [True: 0, False: 11.6k]
  |  Branch (1336:26): [True: 0, False: 0]
  |  Branch (1336:35): [True: 0, False: 0]
  ------------------
 1337|      0|            disable_section(ictx, bs->section);
 1338|      0|            remove_binds(bs, false);
 1339|      0|            remove_binds(bs, true);
 1340|      0|        }
 1341|  11.6k|    }
 1342|  5.81k|    input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1343|  5.81k|}
mp_input_init:
 1504|  5.81k|{
 1505|       |
 1506|  5.81k|    struct input_ctx *ictx = talloc_ptrtype(NULL, ictx);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1507|  5.81k|    *ictx = (struct input_ctx){
 1508|  5.81k|        .global = global,
 1509|  5.81k|        .ar_state = -1,
 1510|  5.81k|        .log = mp_log_new(ictx, global->log, "input"),
 1511|  5.81k|        .mouse_section = bstr0("default"),
 1512|  5.81k|        .opts_cache = m_config_cache_alloc(ictx, global, &input_config),
 1513|  5.81k|        .wakeup_cb = wakeup_cb,
 1514|  5.81k|        .wakeup_ctx = wakeup_ctx,
 1515|  5.81k|        .active_sections = talloc_array(ictx, struct active_section, 0),
  ------------------
  |  |   29|  5.81k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  5.81k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1516|  5.81k|        .touch_points = talloc_array(ictx, struct touch_point, 0),
  ------------------
  |  |   29|  5.81k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  5.81k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1517|  5.81k|    };
 1518|       |
 1519|  5.81k|    ictx->opts = ictx->opts_cache->opts;
 1520|       |
 1521|  5.81k|    mp_mutex_init(&ictx->mutex);
 1522|       |
 1523|       |    // Setup default section, so that it does nothing.
 1524|  5.81k|    mp_input_enable_section(ictx, NULL, MP_INPUT_ALLOW_VO_DRAGGING |
 1525|  5.81k|                                        MP_INPUT_ALLOW_HIDE_CURSOR);
 1526|       |
 1527|  5.81k|    return ictx;
 1528|  5.81k|}
mp_input_update_opts:
 1549|  5.81k|{
 1550|  5.81k|    input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1551|  5.81k|    reload_opts(ictx, false);
 1552|  5.81k|    input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1553|  5.81k|}
mp_input_load_config:
 1556|  5.81k|{
 1557|  5.81k|    input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1558|       |
 1559|  5.81k|    reload_opts(ictx, false);
 1560|       |
 1561|       |    // "Uncomment" the default key bindings in etc/input.conf and add them.
 1562|       |    // All lines that do not start with '# ' are parsed.
 1563|  5.81k|    bstr builtin = bstr0(builtin_input_conf);
 1564|  1.43M|    while (ictx->opts->builtin_bindings && builtin.len) {
  ------------------
  |  Branch (1564:12): [True: 1.43M, False: 0]
  |  Branch (1564:44): [True: 1.42M, False: 5.81k]
  ------------------
 1565|  1.42M|        bstr line = bstr_getline(builtin, &builtin);
 1566|  1.42M|        bstr_eatstart0(&line, "#");
 1567|  1.42M|        if (!bstr_startswith0(line, " "))
  ------------------
  |  Branch (1567:13): [True: 1.26M, False: 168k]
  ------------------
 1568|  1.26M|            parse_config(ictx, true, line, "<builtin>", (bstr){0});
 1569|  1.42M|    }
 1570|       |
 1571|  5.81k|    bool config_ok = false;
 1572|  5.81k|    if (ictx->opts->config_file && ictx->opts->config_file[0])
  ------------------
  |  Branch (1572:9): [True: 0, False: 5.81k]
  |  Branch (1572:36): [True: 0, False: 0]
  ------------------
 1573|      0|        config_ok = parse_config_file(ictx, ictx->opts->config_file);
 1574|  5.81k|    if (!config_ok) {
  ------------------
  |  Branch (1574:9): [True: 5.81k, False: 0]
  ------------------
 1575|       |        // Try global conf dir
 1576|  5.81k|        void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  5.81k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  5.81k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
 1577|  5.81k|        char **files = mp_find_all_config_files(tmp, ictx->global, "input.conf");
 1578|  5.81k|        for (int n = 0; files && files[n]; n++)
  ------------------
  |  Branch (1578:25): [True: 5.81k, False: 0]
  |  Branch (1578:34): [True: 0, False: 5.81k]
  ------------------
 1579|      0|            parse_config_file(ictx, files[n]);
 1580|  5.81k|        talloc_free(tmp);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 1581|  5.81k|    }
 1582|       |
 1583|  5.81k|    bool use_gamepad = ictx->opts->use_gamepad;
 1584|  5.81k|    input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1585|       |
 1586|       |#if HAVE_SDL2_GAMEPAD
 1587|       |    if (use_gamepad)
 1588|       |        mp_input_sdl_gamepad_add(ictx);
 1589|       |#else
 1590|  5.81k|    (void)use_gamepad;
 1591|  5.81k|#endif
 1592|  5.81k|}
mp_input_uninit:
 1612|  5.81k|{
 1613|  5.81k|    if (!ictx)
  ------------------
  |  Branch (1613:9): [True: 0, False: 5.81k]
  ------------------
 1614|      0|        return;
 1615|       |
 1616|  5.81k|    input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1617|  5.81k|    reload_opts(ictx, true);
 1618|  5.81k|    input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1619|       |
 1620|  5.81k|    close_input_sources(ictx);
 1621|  5.81k|    clear_queue(&ictx->cmd_queue);
 1622|  5.81k|    talloc_free(ictx->current_down_cmd);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 1623|  5.81k|    mp_mutex_destroy(&ictx->mutex);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
 1624|  5.81k|    talloc_free(ictx);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 1625|  5.81k|}
mp_input_parse_cmd:
 1645|  1.11M|{
 1646|  1.11M|    return mp_input_parse_cmd_str(ictx->log, str, location);
 1647|  1.11M|}
input.c:test_mouse_active:
 1086|  85.4k|{
 1087|  85.4k|    return test_mouse(ictx, x, y, MP_INPUT_ALLOW_HIDE_CURSOR);
 1088|  85.4k|}
input.c:test_mouse:
 1070|  85.4k|{
 1071|  85.4k|    bool res = false;
 1072|   170k|    for (int i = 0; i < ictx->num_active_sections; i++) {
  ------------------
  |  Branch (1072:21): [True: 85.4k, False: 85.4k]
  ------------------
 1073|  85.4k|        struct active_section *as = &ictx->active_sections[i];
 1074|  85.4k|        if (as->flags & rej_flags)
  ------------------
  |  Branch (1074:13): [True: 85.4k, False: 0]
  ------------------
 1075|  85.4k|            continue;
 1076|      0|        struct cmd_bind_section *s = get_bind_section(ictx, as->name);
 1077|      0|        if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) {
  ------------------
  |  Branch (1077:13): [True: 0, False: 0]
  |  Branch (1077:34): [True: 0, False: 0]
  ------------------
 1078|      0|            res = true;
 1079|      0|            break;
 1080|      0|        }
 1081|      0|    }
 1082|  85.4k|    return res;
 1083|  85.4k|}
input.c:adjust_max_wait_time:
 1121|   137k|{
 1122|   137k|    struct input_opts *opts = ictx->opts;
 1123|   137k|    if (ictx->last_key_down && opts->ar_rate > 0 && ictx->ar_state >= 0) {
  ------------------
  |  Branch (1123:9): [True: 0, False: 137k]
  |  Branch (1123:32): [True: 0, False: 0]
  |  Branch (1123:53): [True: 0, False: 0]
  ------------------
 1124|      0|        *time = MPMIN(*time, 1.0 / opts->ar_rate);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1125|      0|        *time = MPMIN(*time, opts->ar_delay / 1000.0);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1126|      0|    }
 1127|   137k|}
input.c:queue_remove_head:
  279|   137k|{
  280|   137k|    struct mp_cmd *ret = queue->first;
  281|   137k|    if (ret)
  ------------------
  |  Branch (281:9): [True: 0, False: 137k]
  ------------------
  282|      0|        queue_remove(queue, ret);
  283|   137k|    return ret;
  284|   137k|}
input.c:check_autorepeat:
 1140|   137k|{
 1141|   137k|    struct input_opts *opts = ictx->opts;
 1142|       |
 1143|       |    // No input : autorepeat ?
 1144|   137k|    if (opts->ar_rate <= 0 || !ictx->current_down_cmd || !ictx->last_key_down ||
  ------------------
  |  Branch (1144:9): [True: 0, False: 137k]
  |  Branch (1144:31): [True: 137k, False: 0]
  |  Branch (1144:58): [True: 0, False: 0]
  ------------------
 1145|   137k|        (ictx->last_key_down & MP_NO_REPEAT_KEY) ||
  ------------------
  |  |  235|      0|#define MP_NO_REPEAT_KEY       (1u<<23)
  ------------------
  |  Branch (1145:9): [True: 0, False: 0]
  ------------------
 1146|   137k|        !mp_input_is_repeatable_cmd(ictx->current_down_cmd))
  ------------------
  |  Branch (1146:9): [True: 0, False: 0]
  ------------------
 1147|   137k|        ictx->ar_state = -1; // disable
 1148|       |
 1149|   137k|    if (ictx->ar_state >= 0) {
  ------------------
  |  Branch (1149:9): [True: 0, False: 137k]
  ------------------
 1150|      0|        int64_t t = mp_time_ns();
 1151|      0|        if (ictx->last_ar + MP_TIME_S_TO_NS(2) < t)
  ------------------
  |  |   59|      0|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (1151:13): [True: 0, False: 0]
  ------------------
 1152|      0|            ictx->last_ar = t;
 1153|       |        // First time : wait delay
 1154|      0|        if (ictx->ar_state == 0
  ------------------
  |  Branch (1154:13): [True: 0, False: 0]
  ------------------
 1155|      0|            && (t - ictx->last_key_down_time) >= MP_TIME_MS_TO_NS(opts->ar_delay))
  ------------------
  |  |   60|      0|#define MP_TIME_MS_TO_NS(ms) ((ms) * INT64_C(1000000))
  ------------------
  |  Branch (1155:16): [True: 0, False: 0]
  ------------------
 1156|      0|        {
 1157|      0|            ictx->ar_state = 1;
 1158|      0|            ictx->last_ar = ictx->last_key_down_time + MP_TIME_MS_TO_NS(opts->ar_delay);
  ------------------
  |  |   60|      0|#define MP_TIME_MS_TO_NS(ms) ((ms) * INT64_C(1000000))
  ------------------
 1159|       |            // Then send rate / sec event
 1160|      0|        } else if (ictx->ar_state == 1
  ------------------
  |  Branch (1160:20): [True: 0, False: 0]
  ------------------
 1161|      0|                   && (t - ictx->last_ar) >= 1e9 / opts->ar_rate) {
  ------------------
  |  Branch (1161:23): [True: 0, False: 0]
  ------------------
 1162|      0|            ictx->last_ar += 1e9 / opts->ar_rate;
 1163|      0|        } else {
 1164|      0|            return NULL;
 1165|      0|        }
 1166|      0|        struct mp_cmd *ret = mp_cmd_clone(ictx->current_down_cmd);
 1167|      0|        ret->repeated = true;
 1168|      0|        return ret;
 1169|      0|    }
 1170|   137k|    return NULL;
 1171|   137k|}
input.c:disable_section:
 1219|  5.81k|{
 1220|  5.81k|    name = normalize_section(ictx, name);
 1221|       |
 1222|       |    // Remove old section, or make sure it's on top if re-enabled
 1223|  5.81k|    for (int i = ictx->num_active_sections - 1; i >= 0; i--) {
  ------------------
  |  Branch (1223:49): [True: 0, False: 5.81k]
  ------------------
 1224|      0|        struct active_section *as = &ictx->active_sections[i];
 1225|      0|        if (bstr_equals(as->name, name)) {
  ------------------
  |  Branch (1225:13): [True: 0, False: 0]
  ------------------
 1226|      0|            MP_TARRAY_REMOVE_AT(ictx->active_sections,
  ------------------
  |  |  143|      0|    do {                                            \
  |  |  144|      0|        size_t at_ = (at);                          \
  |  |  145|      0|        assert(at_ <= (idxvar));                    \
  |  |  146|      0|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|      0|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|      0|        (idxvar)--;                                 \
  |  |  149|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1227|      0|                                ictx->num_active_sections, i);
 1228|      0|        }
 1229|      0|    }
 1230|  5.81k|}
input.c:normalize_section:
 1214|  11.6k|{
 1215|  11.6k|    return get_bind_section(ictx, name)->section;
 1216|  11.6k|}
input.c:get_bind_section:
  384|  1.12M|{
  385|  1.12M|    if (section.len == 0)
  ------------------
  |  Branch (385:9): [True: 1.10M, False: 23.2k]
  ------------------
  386|  1.10M|        section = bstr0("default");
  387|  1.12M|    struct cmd_bind_section *bind_section = find_section(ictx, section);
  388|  1.12M|    if (bind_section)
  ------------------
  |  Branch (388:9): [True: 1.11M, False: 11.6k]
  ------------------
  389|  1.11M|        return bind_section;
  390|  11.6k|    bind_section = talloc_ptrtype(ictx, bind_section);
  ------------------
  |  |   34|  11.6k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  11.6k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  391|  11.6k|    *bind_section = (struct cmd_bind_section) {
  392|  11.6k|        .section = bstrdup(bind_section, section),
  393|  11.6k|        .mouse_area = {INT_MIN, INT_MIN, INT_MAX, INT_MAX},
  394|  11.6k|        .mouse_area_set = true,
  395|  11.6k|    };
  396|  11.6k|    MP_TARRAY_APPEND(ictx, ictx->sections, ictx->num_sections, bind_section);
  ------------------
  |  |  105|  11.6k|    do {                                            \
  |  |  106|  11.6k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  11.6k|    do {                                            \
  |  |  |  |   97|  11.6k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  11.6k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  11.6k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  11.6k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 5.81k]
  |  |  |  |  ------------------
  |  |  |  |   99|  11.6k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  11.6k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  11.6k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  11.6k|        (idxvar)++;                                 \
  |  |  109|  11.6k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  397|  11.6k|    return bind_section;
  398|  1.12M|}
input.c:find_section:
  373|  1.12M|{
  374|  1.14M|    for (int n = 0; n < ictx->num_sections; n++) {
  ------------------
  |  Branch (374:21): [True: 1.13M, False: 11.6k]
  ------------------
  375|  1.13M|        struct cmd_bind_section *bs = ictx->sections[n];
  376|  1.13M|        if (bstr_equals(section, bs->section))
  ------------------
  |  Branch (376:13): [True: 1.11M, False: 17.4k]
  ------------------
  377|  1.11M|            return bs;
  378|  1.13M|    }
  379|  11.6k|    return NULL;
  380|  1.12M|}
input.c:bind_dealloc:
 1287|  1.11M|{
 1288|  1.11M|    talloc_free(bind->cmd);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1289|  1.11M|    talloc_free(bind->location);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1290|  1.11M|    talloc_free(bind->desc);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1291|  1.11M|}
input.c:parse_config:
 1403|  1.26M|{
 1404|  1.26M|    int n_binds = 0;
 1405|  1.26M|    int line_no = 0;
 1406|  1.26M|    char *cur_loc = NULL;
 1407|       |
 1408|  2.52M|    while (data.len) {
  ------------------
  |  Branch (1408:12): [True: 1.26M, False: 1.26M]
  ------------------
 1409|  1.26M|        line_no++;
 1410|  1.26M|        if (cur_loc)
  ------------------
  |  Branch (1410:13): [True: 0, False: 1.26M]
  ------------------
 1411|      0|            talloc_free(cur_loc);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1412|  1.26M|        cur_loc = talloc_asprintf(NULL, "%s:%d", location, line_no);
  ------------------
  |  |   52|  1.26M|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|  1.26M|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
 1413|       |
 1414|  1.26M|        bstr line = bstr_strip_linebreaks(bstr_getline(data, &data));
 1415|  1.26M|        line = bstr_lstrip(line);
 1416|  1.26M|        if (line.len == 0 || bstr_startswith0(line, "#"))
  ------------------
  |  Branch (1416:13): [True: 133k, False: 1.12M]
  |  Branch (1416:30): [True: 5.81k, False: 1.12M]
  ------------------
 1417|   139k|            continue;
 1418|  1.12M|        if (bstr_eatstart0(&line, "default-bindings ")) {
  ------------------
  |  Branch (1418:13): [True: 5.81k, False: 1.11M]
  ------------------
 1419|  5.81k|            bstr orig = line;
 1420|  5.81k|            bstr_split_tok(line, "#", &line, &(bstr){0});
 1421|  5.81k|            line = bstr_strip(line);
 1422|  5.81k|            if (bstr_equals0(line, "start")) {
  ------------------
  |  Branch (1422:17): [True: 5.81k, False: 0]
  ------------------
 1423|  5.81k|                builtin = true;
 1424|  5.81k|            } else {
 1425|      0|                MP_ERR(ictx, "Broken line: %.*s at %s\n", BSTR_P(orig), cur_loc);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1426|      0|            }
 1427|  5.81k|            continue;
 1428|  5.81k|        }
 1429|  1.11M|        struct bstr command;
 1430|       |        // Find the key name starting a line
 1431|  1.11M|        struct bstr keyname = bstr_split(line, WHITESPACE, &command);
  ------------------
  |  |  285|  1.11M|#define WHITESPACE " \f\n\r\t\v"
  ------------------
 1432|  1.11M|        command = bstr_strip(command);
 1433|  1.11M|        if (command.len == 0) {
  ------------------
  |  Branch (1433:13): [True: 0, False: 1.11M]
  ------------------
 1434|      0|            MP_ERR(ictx, "Unfinished key binding: %.*s at %s\n", BSTR_P(line),
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1435|      0|                   cur_loc);
 1436|      0|            continue;
 1437|      0|        }
 1438|  1.11M|        char *name = bstrdup0(NULL, keyname);
 1439|  1.11M|        int keys[MP_MAX_KEY_DOWN];
 1440|  1.11M|        int num_keys = 0;
 1441|  1.11M|        if (!mp_input_get_keys_from_string(name, MP_MAX_KEY_DOWN, &num_keys, keys)) {
  ------------------
  |  |   59|  1.11M|#define MP_MAX_KEY_DOWN 16
  ------------------
  |  Branch (1441:13): [True: 0, False: 1.11M]
  ------------------
 1442|      0|            talloc_free(name);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1443|      0|            MP_ERR(ictx, "Unknown key '%.*s' at %s\n", BSTR_P(keyname), cur_loc);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1444|      0|            continue;
 1445|      0|        }
 1446|  1.11M|        talloc_free(name);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1447|       |
 1448|  1.11M|        bstr section = restrict_section;
 1449|  1.11M|        if (!section.len) {
  ------------------
  |  Branch (1449:13): [True: 1.11M, False: 0]
  ------------------
 1450|  1.11M|            if (bstr_startswith0(command, "{")) {
  ------------------
  |  Branch (1450:17): [True: 17.4k, False: 1.09M]
  ------------------
 1451|  17.4k|                int p = bstrchr(command, '}');
 1452|  17.4k|                if (p != -1) {
  ------------------
  |  Branch (1452:21): [True: 17.4k, False: 0]
  ------------------
 1453|  17.4k|                    section = bstr_strip(bstr_splice(command, 1, p));
 1454|  17.4k|                    command = bstr_lstrip(bstr_cut(command, p + 1));
 1455|  17.4k|                }
 1456|  17.4k|            }
 1457|  1.11M|        }
 1458|       |
 1459|       |        // Print warnings if invalid commands are encountered.
 1460|  1.11M|        struct mp_cmd *cmd = mp_input_parse_cmd(ictx, command, cur_loc);
 1461|  1.11M|        const char *desc = NULL;
 1462|  1.11M|        if (cmd) {
  ------------------
  |  Branch (1462:13): [True: 1.11M, False: 0]
  ------------------
 1463|  1.11M|            desc = cmd->desc;
 1464|  1.11M|            command = bstr0(cmd->original);
 1465|  1.11M|        }
 1466|       |
 1467|  1.11M|        bind_keys(ictx, builtin, section, keys, num_keys, command, cur_loc, desc);
 1468|  1.11M|        n_binds++;
 1469|       |
 1470|  1.11M|        talloc_free(cmd);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1471|  1.11M|    }
 1472|       |
 1473|  1.26M|    talloc_free(cur_loc);
  ------------------
  |  |   47|  1.26M|#define talloc_free                     ta_free
  ------------------
 1474|       |
 1475|  1.26M|    return n_binds;
 1476|  1.26M|}
input.c:reload_opts:
 1531|  17.4k|{
 1532|  17.4k|    m_config_cache_update(ictx->opts_cache);
 1533|       |
 1534|       |#if HAVE_COCOA
 1535|       |    struct input_opts *opts = ictx->opts;
 1536|       |
 1537|       |    if (ictx->using_cocoa_media_keys != (opts->use_media_keys && !shutdown)) {
 1538|       |        ictx->using_cocoa_media_keys = !ictx->using_cocoa_media_keys;
 1539|       |        if (ictx->using_cocoa_media_keys) {
 1540|       |            cocoa_init_media_keys();
 1541|       |        } else {
 1542|       |            cocoa_uninit_media_keys();
 1543|       |        }
 1544|       |    }
 1545|       |#endif
 1546|  17.4k|}
input.c:clear_queue:
 1603|  5.81k|{
 1604|  5.81k|    while (queue->first) {
  ------------------
  |  Branch (1604:12): [True: 0, False: 5.81k]
  ------------------
 1605|      0|        struct mp_cmd *item = queue->first;
 1606|      0|        queue_remove(queue, item);
 1607|      0|        talloc_free(item);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1608|      0|    }
 1609|  5.81k|}
input.c:bind_keys:
 1359|  1.11M|{
 1360|  1.11M|    struct cmd_bind_section *bs = get_bind_section(ictx, section);
 1361|  1.11M|    struct cmd_bind *bind = NULL;
 1362|       |
 1363|  1.11M|    mp_assert(num_keys <= MP_MAX_KEY_DOWN);
  ------------------
  |  |   41|  1.11M|#define mp_assert assert
  ------------------
 1364|       |
 1365|   104M|    for (int n = 0; n < bs->num_binds; n++) {
  ------------------
  |  Branch (1365:21): [True: 103M, False: 1.11M]
  ------------------
 1366|   103M|        struct cmd_bind *b = &bs->binds[n];
 1367|   103M|        if (bind_matches_key(b, num_keys, keys) && b->is_builtin == builtin) {
  ------------------
  |  Branch (1367:13): [True: 0, False: 103M]
  |  Branch (1367:52): [True: 0, False: 0]
  ------------------
 1368|      0|            bind = b;
 1369|      0|            break;
 1370|      0|        }
 1371|   103M|    }
 1372|       |
 1373|  1.11M|    if (!bind) {
  ------------------
  |  Branch (1373:9): [True: 1.11M, False: 0]
  ------------------
 1374|  1.11M|        struct cmd_bind empty = {{0}};
 1375|  1.11M|        MP_TARRAY_APPEND(bs, bs->binds, bs->num_binds, empty);
  ------------------
  |  |  105|  1.11M|    do {                                            \
  |  |  106|  1.11M|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  1.11M|    do {                                            \
  |  |  |  |   97|  1.11M|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  1.11M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  1.11M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  1.11M|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 52.2k, False: 1.06M]
  |  |  |  |  ------------------
  |  |  |  |   99|  1.11M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  52.2k|    do {                                                        \
  |  |  |  |  |  |   89|  52.2k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  52.2k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  52.2k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  52.2k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  52.2k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  52.2k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  52.2k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  1.11M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  1.11M|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  1.11M|        (idxvar)++;                                 \
  |  |  109|  1.11M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1376|  1.11M|        bind = &bs->binds[bs->num_binds - 1];
 1377|  1.11M|    }
 1378|       |
 1379|  1.11M|    bind_dealloc(bind);
 1380|       |
 1381|  1.11M|    *bind = (struct cmd_bind) {
 1382|  1.11M|        .cmd = bstrdup0(bs->binds, command),
 1383|  1.11M|        .location = talloc_strdup(bs->binds, loc),
  ------------------
  |  |   50|  1.11M|#define talloc_strdup                   ta_xstrdup
  ------------------
 1384|  1.11M|        .desc = talloc_strdup(bs->binds, desc),
  ------------------
  |  |   50|  1.11M|#define talloc_strdup                   ta_xstrdup
  ------------------
 1385|  1.11M|        .owner = bs,
 1386|  1.11M|        .is_builtin = builtin,
 1387|  1.11M|        .num_keys = num_keys,
 1388|  1.11M|    };
 1389|  1.11M|    memcpy(bind->keys, keys, num_keys * sizeof(bind->keys[0]));
 1390|  1.11M|    if (mp_msg_test(ictx->log, MSGL_DEBUG)) {
  ------------------
  |  Branch (1390:9): [True: 1.11M, False: 0]
  ------------------
 1391|  1.11M|        char *s = mp_input_get_key_combo_name(keys, num_keys);
 1392|  1.11M|        MP_TRACE(ictx, "add: section='%.*s' key='%s'%s cmd='%s' location='%s'\n",
  ------------------
  |  |   90|  1.11M|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  4.46M|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 1.11M, False: 0]
  |  |  |  |  |  Branch (82:57): [True: 1.11M, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1393|  1.11M|                 BSTR_P(bind->owner->section), s, bind->is_builtin ? " builtin" : "",
 1394|  1.11M|                 bind->cmd, bind->location);
 1395|  1.11M|        talloc_free(s);
  ------------------
  |  |   47|  1.11M|#define talloc_free                     ta_free
  ------------------
 1396|  1.11M|    }
 1397|  1.11M|}
input.c:bind_matches_key:
 1346|   103M|{
 1347|   103M|    if (bind->num_keys != num_keys)
  ------------------
  |  Branch (1347:9): [True: 15.1M, False: 88.0M]
  ------------------
 1348|  15.1M|        return false;
 1349|  88.6M|    for (int i = 0; i < num_keys; i++) {
  ------------------
  |  Branch (1349:21): [True: 88.6M, False: 0]
  ------------------
 1350|  88.6M|        if (bind->keys[i] != keys[i])
  ------------------
  |  Branch (1350:13): [True: 88.0M, False: 610k]
  ------------------
 1351|  88.0M|            return false;
 1352|  88.6M|    }
 1353|      0|    return true;
 1354|  88.0M|}
input.c:close_input_sources:
 1762|  5.81k|{
 1763|       |    // To avoid lock-order issues, we first remove each source from the context,
 1764|       |    // and then destroy it.
 1765|  5.81k|    while (1) {
  ------------------
  |  Branch (1765:12): [Folded - Ignored]
  ------------------
 1766|  5.81k|        input_lock(ictx);
  ------------------
  |  |   56|  5.81k|#define input_lock(ictx)    mp_mutex_lock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
 1767|  5.81k|        struct mp_input_src *src = ictx->num_sources ? ictx->sources[0] : NULL;
  ------------------
  |  Branch (1767:36): [True: 0, False: 5.81k]
  ------------------
 1768|  5.81k|        input_unlock(ictx);
  ------------------
  |  |   57|  5.81k|#define input_unlock(ictx)  mp_mutex_unlock(&ictx->mutex)
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
 1769|  5.81k|        if (!src)
  ------------------
  |  Branch (1769:13): [True: 5.81k, False: 0]
  ------------------
 1770|  5.81k|            break;
 1771|      0|        input_src_kill(src);
 1772|      0|    }
 1773|  5.81k|}

mp_init_ipc:
  385|  5.81k|{
  386|  5.81k|    struct MPOpts *opts = mp_get_config_group(NULL, global, &mp_opt_root);
  387|       |
  388|  5.81k|    struct mp_ipc_ctx *arg = talloc_ptrtype(NULL, arg);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  389|  5.81k|    *arg = (struct mp_ipc_ctx){
  390|  5.81k|        .log        = mp_log_new(arg, global->log, "ipc"),
  391|  5.81k|        .client_api = client_api,
  392|  5.81k|        .path       = mp_get_user_path(arg, global, opts->ipc_path),
  393|  5.81k|        .death_pipe = {-1, -1},
  394|  5.81k|    };
  395|       |
  396|  5.81k|    if (opts->ipc_client && opts->ipc_client[0]) {
  ------------------
  |  Branch (396:9): [True: 0, False: 5.81k]
  |  Branch (396:29): [True: 0, False: 0]
  ------------------
  397|      0|        int fd = -1;
  398|      0|        bstr str = bstr0(opts->ipc_client);
  399|      0|        if (bstr_eatstart0(&str, "fd://") && str.len) {
  ------------------
  |  Branch (399:13): [True: 0, False: 0]
  |  Branch (399:46): [True: 0, False: 0]
  ------------------
  400|      0|            long long ll = bstrtoll(str, &str, 0);
  401|      0|            if (!str.len && ll >= 0 && ll <= INT_MAX)
  ------------------
  |  Branch (401:17): [True: 0, False: 0]
  |  Branch (401:29): [True: 0, False: 0]
  |  Branch (401:40): [True: 0, False: 0]
  ------------------
  402|      0|                fd = ll;
  403|      0|        }
  404|      0|        if (fd < 0) {
  ------------------
  |  Branch (404:13): [True: 0, False: 0]
  ------------------
  405|      0|            MP_ERR(arg, "Invalid IPC client argument: '%s'\n", opts->ipc_client);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  406|      0|        } else {
  407|      0|            ipc_start_client_json(arg, -1, fd);
  408|      0|        }
  409|      0|    }
  410|       |
  411|  5.81k|    talloc_free(opts);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  412|       |
  413|  5.81k|    if (!arg->path || !arg->path[0])
  ------------------
  |  Branch (413:9): [True: 5.81k, False: 0]
  |  Branch (413:23): [True: 0, False: 0]
  ------------------
  414|  5.81k|        goto out;
  415|       |
  416|      0|    if (mp_make_wakeup_pipe(arg->death_pipe) < 0)
  ------------------
  |  Branch (416:9): [True: 0, False: 0]
  ------------------
  417|      0|        goto out;
  418|       |
  419|      0|    if (mp_thread_create(&arg->thread, ipc_thread, arg))
  ------------------
  |  |  211|      0|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  420|      0|        goto out;
  421|       |
  422|      0|    return arg;
  423|       |
  424|  5.81k|out:
  425|  5.81k|    if (arg->death_pipe[0] >= 0) {
  ------------------
  |  Branch (425:9): [True: 0, False: 5.81k]
  ------------------
  426|      0|        close(arg->death_pipe[0]);
  427|      0|        close(arg->death_pipe[1]);
  428|      0|    }
  429|  5.81k|    talloc_free(arg);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  430|  5.81k|    return NULL;
  431|      0|}
mp_uninit_ipc:
  434|  5.81k|{
  435|  5.81k|    if (!arg)
  ------------------
  |  Branch (435:9): [True: 5.81k, False: 0]
  ------------------
  436|  5.81k|        return;
  437|       |
  438|      0|    (void)write(arg->death_pipe[1], &(char){0}, 1);
  439|      0|    mp_thread_join(arg->thread);
  ------------------
  |  |  212|      0|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  440|       |
  441|      0|    close(arg->death_pipe[0]);
  442|      0|    close(arg->death_pipe[1]);
  443|      0|    talloc_free(arg);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  444|      0|}

mp_input_get_key_from_name:
  242|  1.20M|{
  243|  1.20M|    int modifiers = 0;
  244|  1.20M|    const char *p;
  245|  1.58M|    while ((p = strchr(name, '+'))) {
  ------------------
  |  Branch (245:12): [True: 389k, False: 1.19M]
  ------------------
  246|   842k|        for (const struct key_name *m = modifier_names; m->name; m++)
  ------------------
  |  Branch (246:57): [True: 830k, False: 11.6k]
  ------------------
  247|   830k|            if (!bstrcasecmp(bstr0(m->name),
  ------------------
  |  Branch (247:17): [True: 377k, False: 453k]
  ------------------
  248|   830k|                             (struct bstr){(char *)name, p - name})) {
  249|   377k|                modifiers |= m->key;
  250|   377k|                goto found;
  251|   377k|            }
  252|  11.6k|        if (!strcmp(name, "+"))
  ------------------
  |  Branch (252:13): [True: 11.6k, False: 0]
  ------------------
  253|  11.6k|            return '+' + modifiers;
  254|      0|        return -1;
  255|   377k|found:
  256|   377k|        name = p + 1;
  257|   377k|    }
  258|       |
  259|  1.19M|    struct bstr bname = bstr0(name);
  260|       |
  261|  1.19M|    struct bstr rest;
  262|  1.19M|    int code = bstr_decode_utf8(bname, &rest);
  263|  1.19M|    if (code >= 0 && rest.len == 0)
  ------------------
  |  Branch (263:9): [True: 1.19M, False: 0]
  |  Branch (263:22): [True: 610k, False: 581k]
  ------------------
  264|   610k|        return mp_normalize_keycode(code + modifiers);
  265|       |
  266|   581k|    if (bstr_startswith0(bname, "0x")) {
  ------------------
  |  Branch (266:9): [True: 0, False: 581k]
  ------------------
  267|      0|        char *end;
  268|      0|        long long val = strtoll(name, &end, 16);
  269|      0|        if (name == end || val > INT_MAX || val < INT_MIN)
  ------------------
  |  Branch (269:13): [True: 0, False: 0]
  |  Branch (269:28): [True: 0, False: 0]
  |  Branch (269:45): [True: 0, False: 0]
  ------------------
  270|      0|            return -1;
  271|      0|        long long keycode = val + modifiers;
  272|      0|        if (keycode > INT_MAX || keycode < INT_MIN)
  ------------------
  |  Branch (272:13): [True: 0, False: 0]
  |  Branch (272:34): [True: 0, False: 0]
  ------------------
  273|      0|            return -1;
  274|      0|        return mp_normalize_keycode(keycode);
  275|      0|    }
  276|       |
  277|  33.4M|    for (int i = 0; key_names[i].name != NULL; i++) {
  ------------------
  |  Branch (277:21): [True: 33.4M, False: 0]
  ------------------
  278|  33.4M|        if (strcasecmp(key_names[i].name, name) == 0)
  ------------------
  |  Branch (278:13): [True: 581k, False: 32.8M]
  ------------------
  279|   581k|            return mp_normalize_keycode(key_names[i].key + modifiers);
  280|  33.4M|    }
  281|       |
  282|      0|    return -1;
  283|   581k|}
mp_input_get_key_combo_name:
  317|  1.11M|{
  318|  1.11M|    bstr dst = {0};
  319|  1.20M|    while (max > 0) {
  ------------------
  |  Branch (319:12): [True: 1.20M, False: 0]
  ------------------
  320|  1.20M|        mp_input_append_key_name(&dst, *keys);
  321|  1.20M|        if (--max && *++keys)
  ------------------
  |  Branch (321:13): [True: 87.1k, False: 1.11M]
  |  Branch (321:22): [True: 87.1k, False: 0]
  ------------------
  322|  87.1k|            bstr_xappend(NULL, &dst, bstr0("-"));
  323|  1.11M|        else
  324|  1.11M|            break;
  325|  1.20M|    }
  326|  1.11M|    return dst.start;
  327|  1.11M|}
mp_input_get_keys_from_string:
  331|  1.11M|{
  332|  1.11M|    char *end, *ptr;
  333|  1.11M|    int n = 0;
  334|       |
  335|  1.11M|    ptr = name;
  336|  1.11M|    n = 0;
  337|  1.20M|    for (end = strchr(ptr, '-'); ; end = strchr(ptr, '-')) {
  338|  1.20M|        if (end && end[1] != '\0') {
  ------------------
  |  Branch (338:13): [True: 98.7k, False: 1.10M]
  |  Branch (338:20): [True: 87.1k, False: 11.6k]
  ------------------
  339|  87.1k|            if (end[1] == '-')
  ------------------
  |  Branch (339:17): [True: 0, False: 87.1k]
  ------------------
  340|      0|                end = &end[1];
  341|  87.1k|            end[0] = '\0';
  342|  87.1k|        }
  343|  1.20M|        keys[n] = mp_input_get_key_from_name(ptr);
  344|  1.20M|        if (keys[n] < 0)
  ------------------
  |  Branch (344:13): [True: 0, False: 1.20M]
  ------------------
  345|      0|            return 0;
  346|  1.20M|        n++;
  347|  1.20M|        if (end && end[1] != '\0' && n < max_num_keys)
  ------------------
  |  Branch (347:13): [True: 98.7k, False: 1.10M]
  |  Branch (347:20): [True: 87.1k, False: 11.6k]
  |  Branch (347:38): [True: 87.1k, False: 0]
  ------------------
  348|  87.1k|            ptr = &end[1];
  349|  1.11M|        else
  350|  1.11M|            break;
  351|  1.20M|    }
  352|  1.11M|    *out_num_keys = n;
  353|  1.11M|    return 1;
  354|  1.11M|}
mp_normalize_keycode:
  374|  1.19M|{
  375|  1.19M|    if (keycode <= 0)
  ------------------
  |  Branch (375:9): [True: 0, False: 1.19M]
  ------------------
  376|      0|        return keycode;
  377|  1.19M|    int code = keycode & ~MP_KEY_MODIFIER_MASK;
  ------------------
  |  |  257|  1.19M|#define MP_KEY_MODIFIER_MASK (MP_KEY_MODIFIER_SHIFT | MP_KEY_MODIFIER_CTRL | \
  |  |  ------------------
  |  |  |  |  238|  1.19M|#define MP_KEY_MODIFIER_SHIFT  (1u<<24)
  |  |  ------------------
  |  |               #define MP_KEY_MODIFIER_MASK (MP_KEY_MODIFIER_SHIFT | MP_KEY_MODIFIER_CTRL | \
  |  |  ------------------
  |  |  |  |  239|  1.19M|#define MP_KEY_MODIFIER_CTRL   (1u<<25)
  |  |  ------------------
  |  |  258|  1.19M|                              MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META | \
  |  |  ------------------
  |  |  |  |  240|  1.19M|#define MP_KEY_MODIFIER_ALT    (1u<<26)
  |  |  ------------------
  |  |                                             MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META | \
  |  |  ------------------
  |  |  |  |  241|  1.19M|#define MP_KEY_MODIFIER_META   (1u<<27)
  |  |  ------------------
  |  |  259|  1.19M|                              MP_KEY_STATE_DOWN | MP_KEY_STATE_UP)
  |  |  ------------------
  |  |  |  |  246|  1.19M|#define MP_KEY_STATE_DOWN      (1u<<28)
  |  |  ------------------
  |  |                                             MP_KEY_STATE_DOWN | MP_KEY_STATE_UP)
  |  |  ------------------
  |  |  |  |  252|  1.19M|#define MP_KEY_STATE_UP        (1u<<29)
  |  |  ------------------
  ------------------
  378|  1.19M|    int mod = keycode & MP_KEY_MODIFIER_MASK;
  ------------------
  |  |  257|  1.19M|#define MP_KEY_MODIFIER_MASK (MP_KEY_MODIFIER_SHIFT | MP_KEY_MODIFIER_CTRL | \
  |  |  ------------------
  |  |  |  |  238|  1.19M|#define MP_KEY_MODIFIER_SHIFT  (1u<<24)
  |  |  ------------------
  |  |               #define MP_KEY_MODIFIER_MASK (MP_KEY_MODIFIER_SHIFT | MP_KEY_MODIFIER_CTRL | \
  |  |  ------------------
  |  |  |  |  239|  1.19M|#define MP_KEY_MODIFIER_CTRL   (1u<<25)
  |  |  ------------------
  |  |  258|  1.19M|                              MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META | \
  |  |  ------------------
  |  |  |  |  240|  1.19M|#define MP_KEY_MODIFIER_ALT    (1u<<26)
  |  |  ------------------
  |  |                                             MP_KEY_MODIFIER_ALT | MP_KEY_MODIFIER_META | \
  |  |  ------------------
  |  |  |  |  241|  1.19M|#define MP_KEY_MODIFIER_META   (1u<<27)
  |  |  ------------------
  |  |  259|  1.19M|                              MP_KEY_STATE_DOWN | MP_KEY_STATE_UP)
  |  |  ------------------
  |  |  |  |  246|  1.19M|#define MP_KEY_STATE_DOWN      (1u<<28)
  |  |  ------------------
  |  |                                             MP_KEY_STATE_DOWN | MP_KEY_STATE_UP)
  |  |  ------------------
  |  |  |  |  252|  1.19M|#define MP_KEY_STATE_UP        (1u<<29)
  |  |  ------------------
  ------------------
  379|       |    /* On normal keyboards shift changes the character code of non-special
  380|       |     * keys, so don't count the modifier separately for those. In other words
  381|       |     * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate
  382|       |     * shift modifier is still kept for special keys like arrow keys. */
  383|  1.19M|    if (code >= 32 && code < MP_KEY_BASE) {
  ------------------
  |  |   23|  1.18M|#define MP_KEY_BASE (1<<21)
  ------------------
  |  Branch (383:9): [True: 1.18M, False: 5.81k]
  |  Branch (383:23): [True: 621k, False: 563k]
  ------------------
  384|       |        /* Still try to support ASCII case-modifications properly. For example,
  385|       |         * we want to change "Shift+a" to "A", not "a". Doing this for unicode
  386|       |         * in general would require huge lookup tables, or a libc with proper
  387|       |         * unicode support, so we don't do that. */
  388|   621k|        if (code >= 'a' && code <= 'z' && (mod & MP_KEY_MODIFIER_SHIFT))
  ------------------
  |  |  238|   337k|#define MP_KEY_MODIFIER_SHIFT  (1u<<24)
  ------------------
  |  Branch (388:13): [True: 348k, False: 273k]
  |  Branch (388:28): [True: 337k, False: 11.6k]
  |  Branch (388:43): [True: 0, False: 337k]
  ------------------
  389|      0|            code &= 0x5F;
  390|   621k|        mod &= ~MP_KEY_MODIFIER_SHIFT;
  ------------------
  |  |  238|   621k|#define MP_KEY_MODIFIER_SHIFT  (1u<<24)
  ------------------
  391|   621k|    }
  392|  1.19M|    return code | mod;
  393|  1.19M|}
keycodes.c:mp_input_append_key_name:
  286|  1.20M|{
  287|  6.01M|    for (int i = 0; modifier_names[i].name; i++) {
  ------------------
  |  Branch (287:21): [True: 4.81M, False: 1.20M]
  ------------------
  288|  4.81M|        if (modifier_names[i].key & key) {
  ------------------
  |  Branch (288:13): [True: 377k, False: 4.43M]
  ------------------
  289|   377k|            bstr_xappend_asprintf(NULL, buf, "%s+", modifier_names[i].name);
  290|   377k|            key -= modifier_names[i].key;
  291|   377k|        }
  292|  4.81M|    }
  293|   148M|    for (int i = 0; key_names[i].name != NULL; i++) {
  ------------------
  |  Branch (293:21): [True: 147M, False: 621k]
  ------------------
  294|   147M|        if (key_names[i].key == key) {
  ------------------
  |  Branch (294:13): [True: 581k, False: 147M]
  ------------------
  295|   581k|            bstr_xappend_asprintf(NULL, buf, "%s", key_names[i].name);
  296|   581k|            return;
  297|   581k|        }
  298|   147M|    }
  299|       |
  300|   621k|    if (MP_KEY_IS_UNICODE(key)) {
  ------------------
  |  |   27|   621k|#define MP_KEY_IS_UNICODE(key) ((key) >= 32 && (key) <= 0x10FFFF)
  |  |  ------------------
  |  |  |  Branch (27:33): [True: 621k, False: 0]
  |  |  |  Branch (27:48): [True: 621k, False: 0]
  |  |  ------------------
  ------------------
  301|   621k|        mp_append_utf8_bstr(NULL, buf, key);
  302|   621k|        return;
  303|   621k|    }
  304|       |
  305|       |    // Print the hex key code
  306|      0|    bstr_xappend_asprintf(NULL, buf, "0x%x", key);
  307|      0|}

bstrcmp:
   31|   205M|{
   32|   205M|    int ret = 0;
   33|   205M|    if (str1.len && str2.len)
  ------------------
  |  Branch (33:9): [True: 205M, False: 0]
  |  Branch (33:21): [True: 205M, False: 5.81k]
  ------------------
   34|   205M|        ret = memcmp(str1.start, str2.start, MPMIN(str1.len, str2.len));
  ------------------
  |  |   44|   205M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 107M, False: 98.2M]
  |  |  ------------------
  ------------------
   35|       |
   36|   205M|    if (!ret) {
  ------------------
  |  Branch (36:9): [True: 2.60M, False: 203M]
  ------------------
   37|  2.60M|        if (str1.len == str2.len)
  ------------------
  |  Branch (37:13): [True: 2.17M, False: 430k]
  ------------------
   38|  2.17M|            return 0;
   39|   430k|        else if (str1.len > str2.len)
  ------------------
  |  Branch (39:18): [True: 139k, False: 290k]
  ------------------
   40|   139k|            return 1;
   41|   290k|        else
   42|   290k|            return -1;
   43|  2.60M|    }
   44|   203M|    return ret;
   45|   205M|}
bstrcasecmp:
   48|  1.78M|{
   49|  1.78M|    int ret = 0;
   50|  1.78M|    if (str1.len && str2.len)
  ------------------
  |  Branch (50:9): [True: 1.63M, False: 147k]
  |  Branch (50:21): [True: 1.59M, False: 46.6k]
  ------------------
   51|  1.59M|        ret = strncasecmp(str1.start, str2.start, MPMIN(str1.len, str2.len));
  ------------------
  |  |   44|  1.59M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 640k, False: 951k]
  |  |  ------------------
  ------------------
   52|       |
   53|  1.78M|    if (!ret) {
  ------------------
  |  Branch (53:9): [True: 716k, False: 1.06M]
  ------------------
   54|   716k|        if (str1.len == str2.len)
  ------------------
  |  Branch (54:13): [True: 515k, False: 200k]
  ------------------
   55|   515k|            return 0;
   56|   200k|        else if (str1.len > str2.len)
  ------------------
  |  Branch (56:18): [True: 46.9k, False: 154k]
  ------------------
   57|  46.9k|            return 1;
   58|   154k|        else
   59|   154k|            return -1;
   60|   716k|    }
   61|  1.06M|    return ret;
   62|  1.78M|}
bstrchr:
   65|  24.5M|{
   66|  24.5M|    if (!str.len)
  ------------------
  |  Branch (66:9): [True: 0, False: 24.5M]
  ------------------
   67|      0|        return -1;
   68|  24.5M|    unsigned char *pos = memchr(str.start, c, str.len);
   69|  24.5M|    return pos ? pos - str.start : -1;
  ------------------
  |  Branch (69:12): [True: 23.6M, False: 836k]
  ------------------
   70|  24.5M|}
bstrrchr:
   73|  29.0k|{
   74|  29.0k|    if (!str.len)
  ------------------
  |  Branch (74:9): [True: 128, False: 28.8k]
  ------------------
   75|    128|        return -1;
   76|  28.8k|#if HAVE_MEMRCHR
   77|  28.8k|    unsigned char *pos = memrchr(str.start, c, str.len);
   78|  28.8k|    return pos ? pos - str.start : -1;
  ------------------
  |  Branch (78:12): [True: 3.59k, False: 25.2k]
  ------------------
   79|       |#else
   80|       |    for (int i = str.len - 1; i >= 0; i--)
   81|       |        if (str.start[i] == c)
   82|       |            return i;
   83|       |    return -1;
   84|       |#endif
   85|  29.0k|}
bstrcspn:
   88|  6.47M|{
   89|  6.47M|    int i;
   90|  94.9M|    for (i = 0; i < str.len; i++)
  ------------------
  |  Branch (90:17): [True: 94.2M, False: 671k]
  ------------------
   91|  94.2M|        if (strchr(reject, str.start[i]))
  ------------------
  |  Branch (91:13): [True: 5.80M, False: 88.4M]
  ------------------
   92|  5.80M|            break;
   93|  6.47M|    return i;
   94|  6.47M|}
bstrspn:
   97|  23.2k|{
   98|  23.2k|    int i;
   99|   116k|    for (i = 0; i < str.len; i++)
  ------------------
  |  Branch (99:17): [True: 92.9k, False: 23.2k]
  ------------------
  100|  92.9k|        if (!strchr(accept, str.start[i]))
  ------------------
  |  Branch (100:13): [True: 0, False: 92.9k]
  ------------------
  101|      0|            break;
  102|  23.2k|    return i;
  103|  23.2k|}
bstr_find:
  106|  2.06M|{
  107|  58.9M|    for (int i = 0; i < haystack.len; i++)
  ------------------
  |  Branch (107:21): [True: 57.9M, False: 1.02M]
  ------------------
  108|  57.9M|        if (bstr_startswith(bstr_splice(haystack, i, haystack.len), needle))
  ------------------
  |  Branch (108:13): [True: 1.03M, False: 56.8M]
  ------------------
  109|  1.03M|            return i;
  110|  1.02M|    return -1;
  111|  2.06M|}
bstr_lstrip:
  114|  21.0M|{
  115|  43.2M|    while (str.len && mp_isspace(*str.start)) {
  ------------------
  |  Branch (115:12): [True: 41.2M, False: 2.05M]
  |  Branch (115:23): [True: 22.2M, False: 18.9M]
  ------------------
  116|  22.2M|        str.start++;
  117|  22.2M|        str.len--;
  118|  22.2M|    }
  119|  21.0M|    return str;
  120|  21.0M|}
bstr_strip:
  123|  6.42M|{
  124|  6.42M|    str = bstr_lstrip(str);
  125|  24.3M|    while (str.len && mp_isspace(str.start[str.len - 1]))
  ------------------
  |  Branch (125:12): [True: 23.7M, False: 646k]
  |  Branch (125:23): [True: 17.9M, False: 5.77M]
  ------------------
  126|  17.9M|        str.len--;
  127|  6.42M|    return str;
  128|  6.42M|}
bstr_split:
  131|  1.14M|{
  132|  1.14M|    int start;
  133|  1.14M|    for (start = 0; start < str.len; start++)
  ------------------
  |  Branch (133:21): [True: 1.14M, False: 0]
  ------------------
  134|  1.14M|        if (!strchr(sep, str.start[start]))
  ------------------
  |  Branch (134:13): [True: 1.14M, False: 0]
  ------------------
  135|  1.14M|            break;
  136|  1.14M|    str = bstr_cut(str, start);
  137|  1.14M|    int end = bstrcspn(str, sep);
  138|  1.14M|    if (rest) {
  ------------------
  |  Branch (138:9): [True: 1.11M, False: 24.4k]
  ------------------
  139|  1.11M|        *rest = bstr_cut(str, end);
  140|  1.11M|    }
  141|  1.14M|    return bstr_splice(str, 0, end);
  142|  1.14M|}
bstr_split_tok:
  148|   822k|{
  149|   822k|    bstr bsep = bstr0(tok);
  150|   822k|    int pos = bstr_find(str, bsep);
  151|   822k|    if (pos < 0)
  ------------------
  |  Branch (151:9): [True: 654k, False: 167k]
  ------------------
  152|   654k|        pos = str.len;
  153|   822k|    *out_left = bstr_splice(str, 0, pos);
  154|   822k|    *out_right = bstr_cut(str, pos + bsep.len);
  155|   822k|    return pos != str.len;
  156|   822k|}
bstr_splice:
  159|  90.8M|{
  160|  90.8M|    if (start < 0)
  ------------------
  |  Branch (160:9): [True: 0, False: 90.8M]
  ------------------
  161|      0|        start += str.len;
  162|  90.8M|    if (end < 0)
  ------------------
  |  Branch (162:9): [True: 0, False: 90.8M]
  ------------------
  163|      0|        end += str.len;
  164|  90.8M|    end = MPMIN(end, str.len);
  ------------------
  |  |   44|  90.8M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 373k, False: 90.4M]
  |  |  ------------------
  ------------------
  165|  90.8M|    start = MPMAX(start, 0);
  ------------------
  |  |   43|  90.8M|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 56.1M, False: 34.6M]
  |  |  ------------------
  ------------------
  166|  90.8M|    end = MPMAX(end, start);
  ------------------
  |  |   43|  90.8M|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 90.3M, False: 510k]
  |  |  ------------------
  ------------------
  167|  90.8M|    str.start += start;
  168|  90.8M|    str.len = end - start;
  169|  90.8M|    return str;
  170|  90.8M|}
bstrtoll:
  173|  89.5k|{
  174|  89.5k|    str = bstr_lstrip(str);
  175|  89.5k|    char buf[51];
  176|  89.5k|    int len = MPMIN(str.len, 50);
  ------------------
  |  |   44|  89.5k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 89.5k]
  |  |  ------------------
  ------------------
  177|  89.5k|    memcpy(buf, str.start, len);
  178|  89.5k|    buf[len] = 0;
  179|  89.5k|    char *endptr;
  180|  89.5k|    long long r = strtoll(buf, &endptr, base);
  181|  89.5k|    if (rest)
  ------------------
  |  Branch (181:9): [True: 89.5k, False: 0]
  ------------------
  182|  89.5k|        *rest = bstr_cut(str, endptr - buf);
  183|  89.5k|    return r;
  184|  89.5k|}
bstrtod:
  187|   540k|{
  188|   540k|    str = bstr_lstrip(str);
  189|   540k|    char buf[101];
  190|   540k|    int len = MPMIN(str.len, 100);
  ------------------
  |  |   44|   540k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 5, False: 540k]
  |  |  ------------------
  ------------------
  191|   540k|    memcpy(buf, str.start, len);
  192|   540k|    buf[len] = 0;
  193|   540k|    char *endptr;
  194|   540k|    double r = strtod(buf, &endptr);
  195|   540k|    if (rest)
  ------------------
  |  Branch (195:9): [True: 540k, False: 0]
  ------------------
  196|   540k|        *rest = bstr_cut(str, endptr - buf);
  197|   540k|    return r;
  198|   540k|}
bstr_splitchar:
  201|  23.9M|{
  202|  23.9M|    int pos = bstrchr(str, c);
  203|  23.9M|    if (pos < 0)
  ------------------
  |  Branch (203:9): [True: 336k, False: 23.6M]
  ------------------
  204|   336k|        pos = str.len;
  205|  23.9M|    if (rest)
  ------------------
  |  Branch (205:9): [True: 23.9M, False: 0]
  ------------------
  206|  23.9M|        *rest = bstr_cut(str, pos + 1);
  207|  23.9M|    return bstr_splice(str, 0, pos + 1);
  208|  23.9M|}
bstr_strip_linebreaks:
  211|  1.85M|{
  212|  1.85M|    if (bstr_endswith0(str, "\r\n")) {
  ------------------
  |  Branch (212:9): [True: 504, False: 1.85M]
  ------------------
  213|    504|        str = bstr_splice(str, 0, str.len - 2);
  214|  1.85M|    } else if (bstr_endswith0(str, "\n")) {
  ------------------
  |  Branch (214:16): [True: 1.83M, False: 19.8k]
  ------------------
  215|  1.83M|        str = bstr_splice(str, 0, str.len - 1);
  216|  1.83M|    }
  217|  1.85M|    return str;
  218|  1.85M|}
bstr_eatstart:
  221|  44.8M|{
  222|  44.8M|    if (!bstr_startswith(*s, prefix))
  ------------------
  |  Branch (222:9): [True: 41.0M, False: 3.83M]
  ------------------
  223|  41.0M|        return false;
  224|  3.83M|    *s = bstr_cut(*s, prefix.len);
  225|  3.83M|    return true;
  226|  44.8M|}
bstr_sscanf:
  243|   261k|{
  244|   261k|    char *ptr = bstrdup0(NULL, str);
  245|   261k|    va_list va;
  246|   261k|    va_start(va, format);
  247|   261k|    int ret = vsscanf(ptr, format, va);
  248|   261k|    va_end(va);
  249|   261k|    talloc_free(ptr);
  ------------------
  |  |   47|   261k|#define talloc_free                     ta_free
  ------------------
  250|   261k|    return ret;
  251|   261k|}
bstr_parse_utf8_code_length:
  254|  6.69M|{
  255|  6.69M|    if (b < 128)
  ------------------
  |  Branch (255:9): [True: 0, False: 6.69M]
  ------------------
  256|      0|        return 1;
  257|  6.69M|    int bytes = 7 - mp_log2(b ^ 255);
  258|  6.69M|    return (bytes >= 2 && bytes <= 4) ? bytes : -1;
  ------------------
  |  Branch (258:13): [True: 5.97M, False: 720k]
  |  Branch (258:27): [True: 4.99M, False: 981k]
  ------------------
  259|  6.69M|}
bstr_decode_utf8:
  262|  17.1M|{
  263|  17.1M|    if (s.len == 0)
  ------------------
  |  Branch (263:9): [True: 0, False: 17.1M]
  ------------------
  264|      0|        return -1;
  265|  17.1M|    unsigned int codepoint = s.start[0];
  266|  17.1M|    s.start++; s.len--;
  267|  17.1M|    if (codepoint >= 128) {
  ------------------
  |  Branch (267:9): [True: 6.53M, False: 10.6M]
  ------------------
  268|  6.53M|        int bytes = bstr_parse_utf8_code_length(codepoint);
  269|  6.53M|        if (bytes < 1 || s.len < bytes - 1)
  ------------------
  |  Branch (269:13): [True: 1.57M, False: 4.96M]
  |  Branch (269:26): [True: 7.45k, False: 4.95M]
  ------------------
  270|  1.58M|            return -1;
  271|  4.95M|        codepoint &= 127 >> bytes;
  272|  8.32M|        for (int n = 1; n < bytes; n++) {
  ------------------
  |  Branch (272:25): [True: 5.88M, False: 2.43M]
  ------------------
  273|  5.88M|            int tmp = (unsigned char)s.start[0];
  274|  5.88M|            if ((tmp & 0xC0) != 0x80)
  ------------------
  |  Branch (274:17): [True: 2.51M, False: 3.36M]
  ------------------
  275|  2.51M|                return -1;
  276|  3.36M|            codepoint = (codepoint << 6) | (tmp & ~0xC0);
  277|  3.36M|            s.start++; s.len--;
  278|  3.36M|        }
  279|  2.43M|        if (codepoint > 0x10FFFF || (codepoint >= 0xD800 && codepoint <= 0xDFFF))
  ------------------
  |  Branch (279:13): [True: 1.08k, False: 2.43M]
  |  Branch (279:38): [True: 100k, False: 2.33M]
  |  Branch (279:61): [True: 57, False: 100k]
  ------------------
  280|  1.14k|            return -1;
  281|       |        // Overlong sequences - check taken from libavcodec.
  282|       |        // (The only reason we even bother with this is to make libavcodec's
  283|       |        //  retarded subtitle utf-8 check happy.)
  284|  2.43M|        unsigned int min = bytes == 2 ? 0x80 : 1 << (5 * bytes - 4);
  ------------------
  |  Branch (284:28): [True: 1.52M, False: 912k]
  ------------------
  285|  2.43M|        if (codepoint < min)
  ------------------
  |  Branch (285:13): [True: 899, False: 2.43M]
  ------------------
  286|    899|            return -1;
  287|  2.43M|    }
  288|  13.0M|    if (out_next)
  ------------------
  |  Branch (288:9): [True: 13.0M, False: 0]
  ------------------
  289|  13.0M|        *out_next = s;
  290|  13.0M|    return codepoint;
  291|  17.1M|}
bstr_validate_utf8:
  305|   645k|{
  306|  7.12M|    while (s.len) {
  ------------------
  |  Branch (306:12): [True: 6.64M, False: 482k]
  ------------------
  307|  6.64M|        if (bstr_decode_utf8(s, &s) < 0) {
  ------------------
  |  Branch (307:13): [True: 163k, False: 6.47M]
  ------------------
  308|       |            // Try to guess whether the sequence was just cut-off.
  309|   163k|            unsigned int codepoint = (unsigned char)s.start[0];
  310|   163k|            int bytes = bstr_parse_utf8_code_length(codepoint);
  311|   163k|            if (bytes > 1 && s.len < 6) {
  ------------------
  |  Branch (311:17): [True: 34.9k, False: 128k]
  |  Branch (311:30): [True: 9.86k, False: 25.0k]
  ------------------
  312|       |                // Manually check validity of left bytes
  313|  10.7k|                for (int n = 1; n < bytes; n++) {
  ------------------
  |  Branch (313:33): [True: 10.1k, False: 604]
  ------------------
  314|  10.1k|                    if (n >= s.len) {
  ------------------
  |  Branch (314:25): [True: 4.23k, False: 5.89k]
  ------------------
  315|       |                        // Everything valid until now - just cut off.
  316|  4.23k|                        return -(bytes - s.len);
  317|  4.23k|                    }
  318|  5.89k|                    int tmp = (unsigned char)s.start[n];
  319|  5.89k|                    if ((tmp & 0xC0) != 0x80)
  ------------------
  |  Branch (319:25): [True: 5.02k, False: 872]
  ------------------
  320|  5.02k|                        break;
  321|  5.89k|                }
  322|  9.86k|            }
  323|   159k|            return -8;
  324|   163k|        }
  325|  6.64M|    }
  326|   482k|    return 0;
  327|   645k|}
bstr_sanitize_utf8_latin1:
  330|  17.2k|{
  331|  17.2k|    bstr new = {0};
  332|  17.2k|    bstr left = s;
  333|  17.2k|    unsigned char *first_ok = s.start;
  334|  9.26M|    while (left.len) {
  ------------------
  |  Branch (334:12): [True: 9.24M, False: 17.2k]
  ------------------
  335|  9.24M|        int r = bstr_decode_utf8(left, &left);
  336|  9.24M|        if (r < 0) {
  ------------------
  |  Branch (336:13): [True: 3.93M, False: 5.31M]
  ------------------
  337|  3.93M|            bstr_xappend(talloc_ctx, &new, (bstr){first_ok, left.start - first_ok});
  338|  3.93M|            mp_append_utf8_bstr(talloc_ctx, &new, (unsigned char)left.start[0]);
  339|  3.93M|            left.start += 1;
  340|  3.93M|            left.len -= 1;
  341|  3.93M|            first_ok = left.start;
  342|  3.93M|        }
  343|  9.24M|    }
  344|  17.2k|    if (!new.start)
  ------------------
  |  Branch (344:9): [True: 910, False: 16.3k]
  ------------------
  345|    910|        return s;
  346|  16.3k|    if (first_ok != left.start)
  ------------------
  |  Branch (346:9): [True: 12.6k, False: 3.69k]
  ------------------
  347|  12.6k|        bstr_xappend(talloc_ctx, &new, (bstr){first_ok, left.start - first_ok});
  348|  16.3k|    return new;
  349|  17.2k|}
bstr_xappend:
  365|  94.0M|{
  366|  94.0M|    if (!append.len)
  ------------------
  |  Branch (366:9): [True: 80.9M, False: 13.1M]
  ------------------
  367|  80.9M|        return;
  368|  13.1M|    resize_append(talloc_ctx, s, append.len + 1);
  369|  13.1M|    memmove(s->start + s->len, append.start, append.len);
  370|  13.1M|    s->len += append.len;
  371|  13.1M|    s->start[s->len] = '\0';
  372|  13.1M|}
bstr_xappend_asprintf:
  375|  84.0M|{
  376|  84.0M|    va_list ap;
  377|  84.0M|    va_start(ap, fmt);
  378|  84.0M|    int ret = bstr_xappend_vasprintf(talloc_ctx, s, fmt, ap);
  379|  84.0M|    va_end(ap);
  380|  84.0M|    return ret;
  381|  84.0M|}
bstr_xappend_vasprintf:
  385|  98.6M|{
  386|  98.6M|    int size;
  387|  98.6M|    va_list copy;
  388|  98.6M|    va_copy(copy, ap);
  389|  98.6M|    size_t avail = talloc_get_size(s->start) - s->len;
  ------------------
  |  |   45|  98.6M|#define talloc_get_size                 ta_get_size
  ------------------
  390|  98.6M|    char *dest = s->start ? s->start + s->len : NULL;
  ------------------
  |  Branch (390:18): [True: 98.0M, False: 680k]
  ------------------
  391|  98.6M|    size = vsnprintf(dest, avail, fmt, copy);
  392|  98.6M|    va_end(copy);
  393|       |
  394|  98.6M|    if (size < 0)
  ------------------
  |  Branch (394:9): [True: 0, False: 98.6M]
  ------------------
  395|      0|        return size;
  396|       |
  397|  98.6M|    if (avail < 1 || size + 1 > avail) {
  ------------------
  |  Branch (397:9): [True: 679k, False: 98.0M]
  |  Branch (397:22): [True: 348k, False: 97.6M]
  ------------------
  398|  1.02M|        resize_append(talloc_ctx, s, size + 1);
  399|  1.02M|        vsnprintf(s->start + s->len, size + 1, fmt, ap);
  400|  1.02M|    }
  401|  98.6M|    s->len += size;
  402|  98.6M|    return size;
  403|  98.6M|}
bstr_case_startswith:
  406|   370k|{
  407|   370k|    struct bstr start = bstr_splice(s, 0, prefix.len);
  408|   370k|    return start.len == prefix.len && bstrcasecmp(start, prefix) == 0;
  ------------------
  |  Branch (408:12): [True: 334k, False: 36.6k]
  |  Branch (408:39): [True: 4.29k, False: 329k]
  ------------------
  409|   370k|}
bstr_strip_ext:
  418|  4.53k|{
  419|  4.53k|    int dotpos = bstrrchr(str, '.');
  420|  4.53k|    if (dotpos < 0)
  ------------------
  |  Branch (420:9): [True: 3.36k, False: 1.17k]
  ------------------
  421|  3.36k|        return str;
  422|  1.17k|    return (struct bstr){str.start, dotpos};
  423|  4.53k|}
bstr_get_ext:
  426|  24.4k|{
  427|  24.4k|    int dotpos = bstrrchr(s, '.');
  428|  24.4k|    if (dotpos < 0)
  ------------------
  |  Branch (428:9): [True: 22.0k, False: 2.42k]
  ------------------
  429|  22.0k|        return (struct bstr){NULL, 0};
  430|  2.42k|    return bstr_splice(s, dotpos + 1, s.len);
  431|  24.4k|}
bstr_decode_hex:
  446|      4|{
  447|      4|    if (!out)
  ------------------
  |  Branch (447:9): [True: 0, False: 4]
  ------------------
  448|      0|        return false;
  449|       |
  450|      4|    char *arr = talloc_array(talloc_ctx, char, hex.len / 2);
  ------------------
  |  |   29|      4|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|      4|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      4|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  451|      4|    int len = 0;
  452|       |
  453|      4|    while (hex.len >= 2) {
  ------------------
  |  Branch (453:12): [True: 3, False: 1]
  ------------------
  454|      3|        int a = h_to_i(hex.start[0]);
  455|      3|        int b = h_to_i(hex.start[1]);
  456|      3|        hex = bstr_splice(hex, 2, hex.len);
  457|       |
  458|      3|        if (a < 0 || b < 0) {
  ------------------
  |  Branch (458:13): [True: 3, False: 0]
  |  Branch (458:22): [True: 0, False: 0]
  ------------------
  459|      3|            talloc_free(arr);
  ------------------
  |  |   47|      3|#define talloc_free                     ta_free
  ------------------
  460|      3|            return false;
  461|      3|        }
  462|       |
  463|      0|        arr[len++] = (a << 4) | b;
  464|      0|    }
  465|       |
  466|      1|    *out = (struct bstr){ .start = arr, .len = len };
  467|      1|    return true;
  468|      4|}
bstr.c:resize_append:
  352|  14.1M|{
  353|  14.1M|    size_t size = talloc_get_size(s->start);
  ------------------
  |  |   45|  14.1M|#define talloc_get_size                 ta_get_size
  ------------------
  354|  14.1M|    mp_assert(s->len <= size);
  ------------------
  |  |   41|  14.1M|#define mp_assert assert
  ------------------
  355|  14.1M|    if (append_min > size - s->len) {
  ------------------
  |  Branch (355:9): [True: 1.85M, False: 12.3M]
  ------------------
  356|  1.85M|        if (append_min < size)
  ------------------
  |  Branch (356:13): [True: 370k, False: 1.48M]
  ------------------
  357|   370k|            append_min = size; // preallocate in power of 2s
  358|  1.85M|        if (size >= SIZE_MAX / 2 || append_min >= SIZE_MAX / 2)
  ------------------
  |  Branch (358:13): [True: 0, False: 1.85M]
  |  Branch (358:37): [True: 0, False: 1.85M]
  ------------------
  359|      0|            abort(); // oom
  360|  1.85M|        s->start = talloc_realloc_size(talloc_ctx, s->start, size + append_min);
  ------------------
  |  |   39|  1.85M|#define talloc_realloc_size             ta_xrealloc_size
  |  |  ------------------
  |  |  |  |  158|  1.85M|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  1.85M|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  1.85M|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  1.85M|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  361|  1.85M|    }
  362|  14.1M|}
bstr.c:h_to_i:
  434|      6|{
  435|      6|    if (c >= '0' && c <= '9')
  ------------------
  |  Branch (435:9): [True: 5, False: 1]
  |  Branch (435:21): [True: 0, False: 5]
  ------------------
  436|      0|        return c - '0';
  437|      6|    if (c >= 'a' && c <= 'f')
  ------------------
  |  Branch (437:9): [True: 5, False: 1]
  |  Branch (437:21): [True: 0, False: 5]
  ------------------
  438|      0|        return c - 'a' + 10;
  439|      6|    if (c >= 'A' && c <= 'F')
  ------------------
  |  Branch (439:9): [True: 5, False: 1]
  |  Branch (439:21): [True: 0, False: 5]
  ------------------
  440|      0|        return c - 'A' + 10;
  441|       |
  442|      6|    return -1; // invalid char
  443|      6|}

client.c:bstr0:
   62|  40.6k|{
   63|  40.6k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 40.6k, False: 0]
  ------------------
   64|  40.6k|}
command.c:bstr0:
   62|   673k|{
   63|   673k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 673k, False: 0]
  ------------------
   64|   673k|}
configfiles.c:bstr0:
   62|   116k|{
   63|   116k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 110k, False: 5.90k]
  ------------------
   64|   116k|}
external_files.c:bstr0:
   62|  9.07k|{
   63|  9.07k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 9.07k, False: 0]
  ------------------
   64|  9.07k|}
external_files.c:bstrdup:
   52|  4.53k|{
   53|  4.53k|    struct bstr r = { NULL, str.len };
   54|  4.53k|    if (str.start)
  ------------------
  |  Branch (54:9): [True: 4.53k, False: 0]
  ------------------
   55|  4.53k|        r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len);
  ------------------
  |  |   49|  4.53k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  4.53k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  4.53k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  4.53k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  4.53k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   56|  4.53k|    return r;
   57|  4.53k|}
external_files.c:bstrdup0:
   40|  4.53k|{
   41|  4.53k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  4.53k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  4.53k|}
main.c:bstr0:
   62|  5.81k|{
   63|  5.81k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 5.81k, False: 0]
  ------------------
   64|  5.81k|}
misc.c:bstr0:
   62|   391k|{
   63|   391k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 391k, False: 0]
  ------------------
   64|   391k|}
misc.c:bstrcasecmp0:
  257|   375k|{
  258|   375k|    return bstrcasecmp(str1, bstr0(str2));
  259|   375k|}
misc.c:bstr_xappend0:
  154|  15.6k|{
  155|  15.6k|    return bstr_xappend(talloc_ctx, s, bstr0(append));
  156|  15.6k|}
misc.c:bstrto0:
   46|  5.22k|{
   47|  5.22k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 5.22k, False: 0]
  ------------------
   48|  5.22k|}
misc.c:bstrdup0:
   40|  5.22k|{
   41|  5.22k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  5.22k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  5.22k|}
stream.c:bstr0:
   62|  91.0k|{
   63|  91.0k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 91.0k, False: 0]
  ------------------
   64|  91.0k|}
stream.c:bstr_startswith0:
  222|  90.3k|{
  223|  90.3k|    return bstr_startswith(str, bstr0(prefix));
  224|  90.3k|}
stream.c:bstr_startswith:
  215|  90.3k|{
  216|  90.3k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 520, False: 89.8k]
  ------------------
  217|    520|        return false;
  218|  89.8k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  90.3k|}
stream_cb.c:bstr0:
   62|     17|{
   63|     17|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 17, False: 0]
  ------------------
   64|     17|}
stream_cb.c:bstrto0:
   46|     17|{
   47|     17|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 17, False: 0]
  ------------------
   48|     17|}
stream_cb.c:bstrdup0:
   40|     17|{
   41|     17|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|     17|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|     17|}
stream_file.c:bstrcasecmp0:
  257|  95.4k|{
  258|  95.4k|    return bstrcasecmp(str1, bstr0(str2));
  259|  95.4k|}
stream_file.c:bstr0:
   62|  97.4k|{
   63|  97.4k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 97.4k, False: 0]
  ------------------
   64|  97.4k|}
stream_file.c:bstr_startswith0:
  222|    665|{
  223|    665|    return bstr_startswith(str, bstr0(prefix));
  224|    665|}
stream_file.c:bstr_startswith:
  215|    665|{
  216|    665|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 95, False: 570]
  ------------------
  217|     95|        return false;
  218|    570|    return !memcmp(str.start, prefix.start, prefix.len);
  219|    665|}
stream_lavf.c:bstr0:
   62|     13|{
   63|     13|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 13, False: 0]
  ------------------
   64|     13|}
stream_lavf.c:bstr_eatstart0:
  267|      6|{
  268|      6|    return bstr_eatstart(s, bstr0(prefix));
  269|      6|}
stream_lavf.c:bstr_equals0:
  252|      5|{
  253|      5|    return bstr_equals(str1, bstr0(str2));
  254|      5|}
stream_lavf.c:bstr_equals:
  244|      5|{
  245|      5|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 5, False: 0]
  ------------------
  246|      5|        return false;
  247|       |
  248|      0|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 0, False: 0]
  |  Branch (248:40): [True: 0, False: 0]
  ------------------
  249|      5|}
stream_memory.c:bstr0:
   62|   158k|{
   63|   158k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 158k, False: 0]
  ------------------
   64|   158k|}
stream_memory.c:bstr_eatstart0:
  267|   105k|{
  268|   105k|    return bstr_eatstart(s, bstr0(prefix));
  269|   105k|}
stream_memory.c:bstrdup:
   52|  52.9k|{
   53|  52.9k|    struct bstr r = { NULL, str.len };
   54|  52.9k|    if (str.start)
  ------------------
  |  Branch (54:9): [True: 52.9k, False: 0]
  ------------------
   55|  52.9k|        r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len);
  ------------------
  |  |   49|  52.9k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  52.9k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  52.9k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  52.9k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  52.9k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   56|  52.9k|    return r;
   57|  52.9k|}
vo.c:bstr0:
   62|  2.78k|{
   63|  2.78k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 2.78k, False: 0]
  ------------------
   64|  2.78k|}
chmap.c:bstr_eatstart0:
  267|  31.4k|{
  268|  31.4k|    return bstr_eatstart(s, bstr0(prefix));
  269|  31.4k|}
chmap.c:bstr_equals0:
  252|   745k|{
  253|   745k|    return bstr_equals(str1, bstr0(str2));
  254|   745k|}
chmap.c:bstr_equals:
  244|   745k|{
  245|   745k|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 365k, False: 379k]
  ------------------
  246|   365k|        return false;
  247|       |
  248|   379k|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 49.1k, False: 330k]
  |  Branch (248:40): [True: 65.5k, False: 264k]
  ------------------
  249|   745k|}
chmap.c:bstr0:
   62|   839k|{
   63|   839k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 839k, False: 0]
  ------------------
   64|   839k|}
ao.c:bstr0:
   62|  1.35k|{
   63|  1.35k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.35k, False: 0]
  ------------------
   64|  1.35k|}
codecs.c:bstr0:
   62|  10.4k|{
   63|  10.4k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 0, False: 10.4k]
  ------------------
   64|  10.4k|}
common.c:bstr_cut:
  203|  58.1k|{
  204|  58.1k|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 58.1k]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  58.1k|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 58.1k]
  ------------------
  210|      0|        n = str.len;
  211|  58.1k|    return (struct bstr){str.start + n, str.len - n};
  212|  58.1k|}
msg.c:bstr_eatstart0:
  267|  20.3M|{
  268|  20.3M|    return bstr_eatstart(s, bstr0(prefix));
  269|  20.3M|}
msg.c:bstr0:
   62|  20.3M|{
   63|  20.3M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 20.3M, False: 0]
  ------------------
   64|  20.3M|}
msg.c:bstr_getline:
  130|  20.6M|{
  131|  20.6M|    return bstr_splitchar(str, rest, '\n');
  132|  20.6M|}
msg.c:bstrdup0:
   40|  2.45M|{
   41|  2.45M|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  2.45M|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  2.45M|}
playlist.c:bstr0:
   62|  94.7k|{
   63|  94.7k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 94.7k, False: 0]
  ------------------
   64|  94.7k|}
tags.c:bstr0:
   62|  1.99M|{
   63|  1.99M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.99M, False: 0]
  ------------------
   64|  1.99M|}
tags.c:bstrcasecmp0:
  257|  48.3k|{
  258|  48.3k|    return bstrcasecmp(str1, bstr0(str2));
  259|  48.3k|}
tags.c:bstrto0:
   46|   152k|{
   47|   152k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 152k, False: 0]
  ------------------
   48|   152k|}
tags.c:bstrdup0:
   40|   152k|{
   41|   152k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|   152k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|   152k|}
demux.c:bstr0:
   62|  88.1k|{
   63|  88.1k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 88.1k, False: 0]
  ------------------
   64|  88.1k|}
demux_edl.c:bstr0:
   62|  1.59M|{
   63|  1.59M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.59M, False: 0]
  ------------------
   64|  1.59M|}
demux_edl.c:bstr_eatstart0:
  267|  1.00M|{
  268|  1.00M|    return bstr_eatstart(s, bstr0(prefix));
  269|  1.00M|}
demux_edl.c:bstr_cut:
  203|  76.2k|{
  204|  76.2k|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 76.2k]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  76.2k|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 76.2k]
  ------------------
  210|      0|        n = str.len;
  211|  76.2k|    return (struct bstr){str.start + n, str.len - n};
  212|  76.2k|}
demux_edl.c:bstr_equals:
  244|   153k|{
  245|   153k|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 78.9k, False: 74.3k]
  ------------------
  246|  78.9k|        return false;
  247|       |
  248|  74.3k|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 74.2k, False: 129]
  |  Branch (248:40): [True: 0, False: 129]
  ------------------
  249|   153k|}
demux_edl.c:bstr_equals0:
  252|  74.1k|{
  253|  74.1k|    return bstr_equals(str1, bstr0(str2));
  254|  74.1k|}
demux_edl.c:bstrdup0:
   40|   148k|{
   41|   148k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|   148k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|   148k|}
demux_edl.c:bstrcasecmp0:
  257|    562|{
  258|    562|    return bstrcasecmp(str1, bstr0(str2));
  259|    562|}
demux_lavf.c:bstrcasecmp0:
  257|  74.7k|{
  258|  74.7k|    return bstrcasecmp(str1, bstr0(str2));
  259|  74.7k|}
demux_lavf.c:bstr0:
   62|   117k|{
   63|   117k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 117k, False: 0]
  ------------------
   64|   117k|}
demux_lavf.c:bstr_endswith0:
  234|  9.03k|{
  235|  9.03k|    return bstr_endswith(str, bstr0(suffix));
  236|  9.03k|}
demux_lavf.c:bstr_endswith:
  227|  9.03k|{
  228|  9.03k|    if (str.len < suffix.len)
  ------------------
  |  Branch (228:9): [True: 7.56k, False: 1.46k]
  ------------------
  229|  7.56k|        return false;
  230|  1.46k|    return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len);
  231|  9.03k|}
demux_null.c:bstr_startswith0:
  222|  4.02k|{
  223|  4.02k|    return bstr_startswith(str, bstr0(prefix));
  224|  4.02k|}
demux_null.c:bstr_startswith:
  215|  4.02k|{
  216|  4.02k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 2, False: 4.02k]
  ------------------
  217|      2|        return false;
  218|  4.02k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  4.02k|}
demux_null.c:bstr0:
   62|  8.04k|{
   63|  8.04k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 8.04k, False: 0]
  ------------------
   64|  8.04k|}
demux_playlist.c:bstr_equals0:
  252|  8.79k|{
  253|  8.79k|    return bstr_equals(str1, bstr0(str2));
  254|  8.79k|}
demux_playlist.c:bstr_equals:
  244|  8.79k|{
  245|  8.79k|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 8.28k, False: 503]
  ------------------
  246|  8.28k|        return false;
  247|       |
  248|    503|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 0, False: 503]
  |  Branch (248:40): [True: 407, False: 96]
  ------------------
  249|  8.79k|}
demux_playlist.c:bstr_eatstart0:
  267|   171k|{
  268|   171k|    return bstr_eatstart(s, bstr0(prefix));
  269|   171k|}
demux_playlist.c:bstrto0:
   46|  88.9k|{
   47|  88.9k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 88.9k, False: 0]
  ------------------
   48|  88.9k|}
demux_playlist.c:bstrdup0:
   40|  88.9k|{
   41|  88.9k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  88.9k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  88.9k|}
demux_playlist.c:bstr_startswith0:
  222|   261k|{
  223|   261k|    return bstr_startswith(str, bstr0(prefix));
  224|   261k|}
demux_playlist.c:bstr_startswith:
  215|   261k|{
  216|   261k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 126k, False: 135k]
  ------------------
  217|   126k|        return false;
  218|   135k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|   261k|}
demux_playlist.c:bstr0:
   62|  1.21M|{
   63|  1.21M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.21M, False: 838]
  ------------------
   64|  1.21M|}
demux_playlist.c:bstrcasecmp0:
  257|  9.07k|{
  258|  9.07k|    return bstrcasecmp(str1, bstr0(str2));
  259|  9.07k|}
cmd.c:bstr_equals0:
  252|  14.8M|{
  253|  14.8M|    return bstr_equals(str1, bstr0(str2));
  254|  14.8M|}
cmd.c:bstr_equals:
  244|  14.8M|{
  245|  14.8M|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 13.7M, False: 1.12M]
  ------------------
  246|  13.7M|        return false;
  247|       |
  248|  1.12M|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 0, False: 1.12M]
  |  Branch (248:40): [True: 81.3k, False: 1.04M]
  ------------------
  249|  14.8M|}
cmd.c:bstr0:
   62|  30.8M|{
   63|  30.8M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 30.8M, False: 0]
  ------------------
   64|  30.8M|}
cmd.c:bstr_cut:
  203|  3.17M|{
  204|  3.17M|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 3.17M]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  3.17M|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 3.17M]
  ------------------
  210|      0|        n = str.len;
  211|  3.17M|    return (struct bstr){str.start + n, str.len - n};
  212|  3.17M|}
cmd.c:bstr_eatstart0:
  267|  13.2M|{
  268|  13.2M|    return bstr_eatstart(s, bstr0(prefix));
  269|  13.2M|}
cmd.c:bstrto0:
   46|  3.19M|{
   47|  3.19M|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 3.19M, False: 0]
  ------------------
   48|  3.19M|}
cmd.c:bstrdup0:
   40|  3.19M|{
   41|  3.19M|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  3.19M|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  3.19M|}
cmd.c:bstr_startswith0:
  222|   854k|{
  223|   854k|    return bstr_startswith(str, bstr0(prefix));
  224|   854k|}
cmd.c:bstr_startswith:
  215|   854k|{
  216|   854k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 0, False: 854k]
  ------------------
  217|      0|        return false;
  218|   854k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|   854k|}
input.c:bstr0:
   62|  8.46M|{
   63|  8.46M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 8.46M, False: 5.81k]
  ------------------
   64|  8.46M|}
input.c:bstrdup:
   52|  11.6k|{
   53|  11.6k|    struct bstr r = { NULL, str.len };
   54|  11.6k|    if (str.start)
  ------------------
  |  Branch (54:9): [True: 11.6k, False: 0]
  ------------------
   55|  11.6k|        r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len);
  ------------------
  |  |   49|  11.6k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  11.6k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  11.6k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  11.6k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  11.6k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   56|  11.6k|    return r;
   57|  11.6k|}
input.c:bstr_equals0:
  252|  5.81k|{
  253|  5.81k|    return bstr_equals(str1, bstr0(str2));
  254|  5.81k|}
input.c:bstrdup0:
   40|  2.23M|{
   41|  2.23M|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  2.23M|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  2.23M|}
input.c:bstr_cut:
  203|  17.4k|{
  204|  17.4k|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 17.4k]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  17.4k|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 17.4k]
  ------------------
  210|      0|        n = str.len;
  211|  17.4k|    return (struct bstr){str.start + n, str.len - n};
  212|  17.4k|}
input.c:bstr_getline:
  130|  2.69M|{
  131|  2.69M|    return bstr_splitchar(str, rest, '\n');
  132|  2.69M|}
input.c:bstr_eatstart0:
  267|  2.55M|{
  268|  2.55M|    return bstr_eatstart(s, bstr0(prefix));
  269|  2.55M|}
input.c:bstr_startswith0:
  222|  3.67M|{
  223|  3.67M|    return bstr_startswith(str, bstr0(prefix));
  224|  3.67M|}
input.c:bstr_startswith:
  215|  3.67M|{
  216|  3.67M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 0, False: 3.67M]
  ------------------
  217|      0|        return false;
  218|  3.67M|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  3.67M|}
input.c:bstr_equals:
  244|  1.13M|{
  245|  1.13M|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 17.4k, False: 1.12M]
  ------------------
  246|  17.4k|        return false;
  247|       |
  248|  1.12M|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 5.81k, False: 1.11M]
  |  Branch (248:40): [True: 1.11M, False: 0]
  ------------------
  249|  1.13M|}
keycodes.c:bstr0:
   62|  2.69M|{
   63|  2.69M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 2.69M, False: 0]
  ------------------
   64|  2.69M|}
keycodes.c:bstr_startswith0:
  222|   581k|{
  223|   581k|    return bstr_startswith(str, bstr0(prefix));
  224|   581k|}
keycodes.c:bstr_startswith:
  215|   581k|{
  216|   581k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 0, False: 581k]
  ------------------
  217|      0|        return false;
  218|   581k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|   581k|}
bstr.c:bstr_startswith:
  215|   102M|{
  216|   102M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 8.10M, False: 94.6M]
  ------------------
  217|  8.10M|        return false;
  218|  94.6M|    return !memcmp(str.start, prefix.start, prefix.len);
  219|   102M|}
bstr.c:bstr_cut:
  203|  31.4M|{
  204|  31.4M|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 31.4M]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  31.4M|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 991k, False: 30.4M]
  ------------------
  210|   991k|        n = str.len;
  211|  31.4M|    return (struct bstr){str.start + n, str.len - n};
  212|  31.4M|}
bstr.c:bstr0:
   62|  4.52M|{
   63|  4.52M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 4.52M, False: 0]
  ------------------
   64|  4.52M|}
bstr.c:bstr_endswith0:
  234|  3.70M|{
  235|  3.70M|    return bstr_endswith(str, bstr0(suffix));
  236|  3.70M|}
bstr.c:bstr_endswith:
  227|  3.70M|{
  228|  3.70M|    if (str.len < suffix.len)
  ------------------
  |  Branch (228:9): [True: 209k, False: 3.49M]
  ------------------
  229|   209k|        return false;
  230|  3.49M|    return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len);
  231|  3.70M|}
bstr.c:bstrdup0:
   40|   261k|{
   41|   261k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|   261k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|   261k|}
charset_conv.c:bstr0:
   62|  1.93M|{
   63|  1.93M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.93M, False: 0]
  ------------------
   64|  1.93M|}
charset_conv.c:bstr_startswith0:
  222|  1.93M|{
  223|  1.93M|    return bstr_startswith(str, bstr0(prefix));
  224|  1.93M|}
charset_conv.c:bstr_startswith:
  215|  1.93M|{
  216|  1.93M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 1.35M, False: 586k]
  ------------------
  217|  1.35M|        return false;
  218|   586k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  1.93M|}
json.c:bstr0:
   62|   116k|{
   63|   116k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 87.1k, False: 29.0k]
  ------------------
   64|   116k|}
node.c:bstr0:
   62|  5.81k|{
   63|  5.81k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 5.81k, False: 0]
  ------------------
   64|  5.81k|}
node.c:bstrdup0:
   40|  5.81k|{
   41|  5.81k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  5.81k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  5.81k|}
path_utils.c:bstr0:
   62|  1.14M|{
   63|  1.14M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 1.14M, False: 0]
  ------------------
   64|  1.14M|}
path_utils.c:bstrdup0:
   40|  11.7k|{
   41|  11.7k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  11.7k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  11.7k|}
path_utils.c:bstr_find0:
  262|   831k|{
  263|   831k|    return bstr_find(haystack, bstr0(needle));
  264|   831k|}
m_config_frontend.c:bstr0:
   62|   223M|{
   63|   223M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 223M, False: 0]
  ------------------
   64|   223M|}
m_config_frontend.c:bstr_eatstart0:
  267|  46.4k|{
  268|  46.4k|    return bstr_eatstart(s, bstr0(prefix));
  269|  46.4k|}
m_config_frontend.c:bstr_startswith:
  215|  19.3M|{
  216|  19.3M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 14.7M, False: 4.60M]
  ------------------
  217|  14.7M|        return false;
  218|  4.60M|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  19.3M|}
m_config_frontend.c:bstr_endswith:
  227|  40.6k|{
  228|  40.6k|    if (str.len < suffix.len)
  ------------------
  |  Branch (228:9): [True: 0, False: 40.6k]
  ------------------
  229|      0|        return false;
  230|  40.6k|    return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len);
  231|  40.6k|}
m_config_frontend.c:bstr_equals0:
  252|  1.81M|{
  253|  1.81M|    return bstr_equals(str1, bstr0(str2));
  254|  1.81M|}
m_config_frontend.c:bstr_equals:
  244|  1.81M|{
  245|  1.81M|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 1.66M, False: 156k]
  ------------------
  246|  1.66M|        return false;
  247|       |
  248|   156k|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 5.81k, False: 151k]
  |  Branch (248:40): [True: 11.6k, False: 139k]
  ------------------
  249|  1.81M|}
m_config_frontend.c:bstrto0:
   46|   650k|{
   47|   650k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 650k, False: 0]
  ------------------
   48|   650k|}
m_config_frontend.c:bstrdup0:
   40|   650k|{
   41|   650k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|   650k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|   650k|}
m_option.c:bstr_equals0:
  252|  2.90M|{
  253|  2.90M|    return bstr_equals(str1, bstr0(str2));
  254|  2.90M|}
m_option.c:bstr_equals:
  244|  2.90M|{
  245|  2.90M|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 2.36M, False: 538k]
  ------------------
  246|  2.36M|        return false;
  247|       |
  248|   538k|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 34.8k, False: 503k]
  |  Branch (248:40): [True: 213k, False: 290k]
  ------------------
  249|  2.90M|}
m_option.c:bstr0:
   62|  5.45M|{
   63|  5.45M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 5.43M, False: 11.6k]
  ------------------
   64|  5.45M|}
m_option.c:bstrcasecmp0:
  257|  17.4k|{
  258|  17.4k|    return bstrcasecmp(str1, bstr0(str2));
  259|  17.4k|}
m_option.c:bstrcmp0:
  239|   424k|{
  240|   424k|    return bstrcmp(str1, bstr0(str2));
  241|   424k|}
m_option.c:bstr_eatstart0:
  267|  1.48M|{
  268|  1.48M|    return bstr_eatstart(s, bstr0(prefix));
  269|  1.48M|}
m_option.c:bstrdup0:
   40|  1.28M|{
   41|  1.28M|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  1.28M|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  1.28M|}
m_option.c:bstr_endswith0:
  234|   441k|{
  235|   441k|    return bstr_endswith(str, bstr0(suffix));
  236|   441k|}
m_option.c:bstr_endswith:
  227|   441k|{
  228|   441k|    if (str.len < suffix.len)
  ------------------
  |  Branch (228:9): [True: 185k, False: 255k]
  ------------------
  229|   185k|        return false;
  230|   255k|    return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len);
  231|   441k|}
m_option.c:bstr_cut:
  203|   116k|{
  204|   116k|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 116k]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|   116k|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 17.4k, False: 98.7k]
  ------------------
  210|  17.4k|        n = str.len;
  211|   116k|    return (struct bstr){str.start + n, str.len - n};
  212|   116k|}
m_option.c:bstrdup:
   52|  17.4k|{
   53|  17.4k|    struct bstr r = { NULL, str.len };
   54|  17.4k|    if (str.start)
  ------------------
  |  Branch (54:9): [True: 17.4k, False: 0]
  ------------------
   55|  17.4k|        r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len);
  ------------------
  |  |   49|  17.4k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  17.4k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  17.4k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  17.4k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  17.4k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   56|  17.4k|    return r;
   57|  17.4k|}
m_option.c:bstrto0:
   46|  81.3k|{
   47|  81.3k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 81.3k, False: 0]
  ------------------
   48|  81.3k|}
m_option.c:bstr_find0:
  262|   174k|{
  263|   174k|    return bstr_find(haystack, bstr0(needle));
  264|   174k|}
m_property.c:bstr0:
   62|  6.03M|{
   63|  6.03M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 6.03M, False: 0]
  ------------------
   64|  6.03M|}
m_property.c:bstr_eatstart0:
  267|  4.40M|{
  268|  4.40M|    return bstr_eatstart(s, bstr0(prefix));
  269|  4.40M|}
m_property.c:bstr_startswith0:
  222|  1.23M|{
  223|  1.23M|    return bstr_startswith(str, bstr0(prefix));
  224|  1.23M|}
m_property.c:bstr_startswith:
  215|  1.23M|{
  216|  1.23M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 77.3k, False: 1.15M]
  ------------------
  217|  77.3k|        return false;
  218|  1.15M|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  1.23M|}
m_property.c:bstr_find0:
  262|   231k|{
  263|   231k|    return bstr_find(haystack, bstr0(needle));
  264|   231k|}
m_property.c:bstr_cut:
  203|  1.46M|{
  204|  1.46M|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 1.46M]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  1.46M|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 1.46M]
  ------------------
  210|      0|        n = str.len;
  211|  1.46M|    return (struct bstr){str.start + n, str.len - n};
  212|  1.46M|}
m_property.c:bstrdup0:
   40|   231k|{
   41|   231k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|   231k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|   231k|}
parse_configfile.c:bstr_eatstart0:
  267|  1.47M|{
  268|  1.47M|    return bstr_eatstart(s, bstr0(prefix));
  269|  1.47M|}
parse_configfile.c:bstr0:
   62|  3.14M|{
   63|  3.14M|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 3.14M, False: 0]
  ------------------
   64|  3.14M|}
parse_configfile.c:bstr_getline:
  130|   563k|{
  131|   563k|    return bstr_splitchar(str, rest, '\n');
  132|   563k|}
parse_configfile.c:bstr_startswith0:
  222|  1.67M|{
  223|  1.67M|    return bstr_startswith(str, bstr0(prefix));
  224|  1.67M|}
parse_configfile.c:bstr_startswith:
  215|  1.67M|{
  216|  1.67M|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 493k, False: 1.18M]
  ------------------
  217|   493k|        return false;
  218|  1.18M|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  1.67M|}
parse_configfile.c:bstrto0:
   46|  69.7k|{
   47|  69.7k|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 69.7k, False: 0]
  ------------------
   48|  69.7k|}
parse_configfile.c:bstrdup0:
   40|  69.7k|{
   41|  69.7k|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|  69.7k|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|  69.7k|}
parse_configfile.c:bstr_cut:
  203|  4.37M|{
  204|  4.37M|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 4.37M]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  4.37M|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 4.37M]
  ------------------
  210|      0|        n = str.len;
  211|  4.37M|    return (struct bstr){str.start + n, str.len - n};
  212|  4.37M|}
path.c:bstr0:
   62|   231k|{
   63|   231k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 220k, False: 11.6k]
  ------------------
   64|   231k|}
path.c:bstr_eatstart0:
  267|  34.8k|{
  268|  34.8k|    return bstr_eatstart(s, bstr0(prefix));
  269|  34.8k|}
path.c:bstr_equals0:
  252|  23.2k|{
  253|  23.2k|    return bstr_equals(str1, bstr0(str2));
  254|  23.2k|}
path.c:bstr_equals:
  244|  23.2k|{
  245|  23.2k|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 23.2k, False: 0]
  ------------------
  246|  23.2k|        return false;
  247|       |
  248|      0|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 0, False: 0]
  |  Branch (248:40): [True: 0, False: 0]
  ------------------
  249|  23.2k|}
vd_lavc.c:bstr0:
   62|  91.0k|{
   63|  91.0k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 91.0k, False: 0]
  ------------------
   64|  91.0k|}
vd_lavc.c:bstr_equals0:
  252|  83.4k|{
  253|  83.4k|    return bstr_equals(str1, bstr0(str2));
  254|  83.4k|}
vd_lavc.c:bstr_equals:
  244|  83.4k|{
  245|  83.4k|    if (str1.len != str2.len)
  ------------------
  |  Branch (245:9): [True: 75.9k, False: 7.59k]
  ------------------
  246|  75.9k|        return false;
  247|       |
  248|  7.59k|    return str1.start == str2.start || bstrcmp(str1, str2) == 0;
  ------------------
  |  Branch (248:12): [True: 0, False: 7.59k]
  |  Branch (248:40): [True: 7.59k, False: 0]
  ------------------
  249|  83.4k|}
ad_spdif.c:bstr0:
   62|      5|{
   63|      5|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 0, False: 5]
  ------------------
   64|      5|}
cue.c:bstr_startswith0:
  222|  24.4k|{
  223|  24.4k|    return bstr_startswith(str, bstr0(prefix));
  224|  24.4k|}
cue.c:bstr_startswith:
  215|  24.4k|{
  216|  24.4k|    if (str.len < prefix.len)
  ------------------
  |  Branch (216:9): [True: 8, False: 24.4k]
  ------------------
  217|      8|        return false;
  218|  24.4k|    return !memcmp(str.start, prefix.start, prefix.len);
  219|  24.4k|}
cue.c:bstr_cut:
  203|  4.08k|{
  204|  4.08k|    if (n < 0) {
  ------------------
  |  Branch (204:9): [True: 0, False: 4.08k]
  ------------------
  205|      0|        n += str.len;
  206|      0|        if (n < 0)
  ------------------
  |  Branch (206:13): [True: 0, False: 0]
  ------------------
  207|      0|            n = 0;
  208|      0|    }
  209|  4.08k|    if (((size_t)n) > str.len)
  ------------------
  |  Branch (209:9): [True: 0, False: 4.08k]
  ------------------
  210|      0|        n = str.len;
  211|  4.08k|    return (struct bstr){str.start + n, str.len - n};
  212|  4.08k|}
cue.c:bstr_getline:
  130|  28.3k|{
  131|  28.3k|    return bstr_splitchar(str, rest, '\n');
  132|  28.3k|}
cue.c:bstr_find0:
  262|    217|{
  263|    217|    return bstr_find(haystack, bstr0(needle));
  264|    217|}
cue.c:bstr0:
   62|   377k|{
   63|   377k|    return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
  ------------------
  |  Branch (63:46): [True: 377k, False: 0]
  ------------------
   64|   377k|}
cue.c:bstrto0:
   46|     82|{
   47|     82|    return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, "");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (47:12): [True: 82, False: 0]
  ------------------
   48|     82|}
cue.c:bstrdup0:
   40|     82|{
   41|     82|    return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
  ------------------
  |  |   51|     82|#define talloc_strndup                  ta_xstrndup
  ------------------
   42|     82|}

mp_charset_is_utf8:
   42|   899k|{
   43|   899k|    return user_cp && (strcasecmp(user_cp, "utf8") == 0 ||
  ------------------
  |  Branch (43:12): [True: 899k, False: 0]
  |  Branch (43:24): [True: 0, False: 899k]
  ------------------
   44|   899k|                       strcasecmp(user_cp, "utf-8") == 0);
  ------------------
  |  Branch (44:24): [True: 483k, False: 416k]
  ------------------
   45|   899k|}
mp_charset_is_utf16:
   48|    458|{
   49|    458|    bstr s = bstr0(user_cp);
   50|    458|    return bstr_case_startswith(s, bstr0("utf16")) ||
  ------------------
  |  Branch (50:12): [True: 0, False: 458]
  ------------------
   51|    458|           bstr_case_startswith(s, bstr0("utf-16"));
  ------------------
  |  Branch (51:12): [True: 3, False: 455]
  ------------------
   52|    458|}
mp_charset_guess:
  103|   646k|{
  104|   646k|    if (user_cp[0] == '+') {
  ------------------
  |  Branch (104:9): [True: 0, False: 646k]
  ------------------
  105|      0|        mp_verbose(log, "Forcing charset '%s'.\n", user_cp + 1);
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  106|      0|        return user_cp + 1;
  107|      0|    }
  108|       |
  109|   646k|    const char *bom_cp = ms_bom_guess(buf);
  110|   646k|    if (bom_cp) {
  ------------------
  |  Branch (110:9): [True: 338, False: 645k]
  ------------------
  111|    338|        mp_verbose(log, "Data has a BOM, assuming %s as charset.\n", bom_cp);
  ------------------
  |  |   75|    338|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  112|    338|        return bom_cp;
  113|    338|    }
  114|       |
  115|   645k|    int r = bstr_validate_utf8(buf);
  116|   645k|    if (r >= 0 || (r > -8 && (flags & MP_ICONV_ALLOW_CUTOFF))) {
  ------------------
  |  Branch (116:9): [True: 482k, False: 163k]
  |  Branch (116:20): [True: 4.23k, False: 159k]
  |  Branch (116:30): [True: 0, False: 4.23k]
  ------------------
  117|   482k|        if (strcmp(user_cp, "auto") != 0 && !mp_charset_is_utf8(user_cp))
  ------------------
  |  Branch (117:13): [True: 0, False: 482k]
  |  Branch (117:45): [True: 0, False: 0]
  ------------------
  118|      0|            mp_verbose(log, "Data looks like UTF-8, ignoring user-provided charset.\n");
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  119|   482k|        return "utf-8";
  120|   482k|    }
  121|       |
  122|   163k|    const char *res = NULL;
  123|   163k|    if (strcasecmp(user_cp, "auto") == 0) {
  ------------------
  |  Branch (123:9): [True: 163k, False: 0]
  ------------------
  124|   163k|#if HAVE_UCHARDET
  125|   163k|        res = mp_uchardet(talloc_ctx, log, buf);
  126|   163k|#endif
  127|   163k|        if (!res) {
  ------------------
  |  Branch (127:13): [True: 6.75k, False: 156k]
  ------------------
  128|  6.75k|            mp_verbose(log, "Charset auto-detection failed.\n");
  ------------------
  |  |   75|  6.75k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  129|  6.75k|            res = "UTF-8-BROKEN";
  130|  6.75k|        }
  131|   163k|    } else {
  132|      0|        res = user_cp;
  133|      0|    }
  134|       |
  135|   163k|    mp_verbose(log, "Using charset '%s'.\n", res);
  ------------------
  |  |   75|   163k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  136|   163k|    return res;
  137|   645k|}
mp_iconv_to_utf8:
  151|   233k|{
  152|   233k|#if HAVE_ICONV
  153|   233k|    if (!buf.len)
  ------------------
  |  Branch (153:9): [True: 2.10k, False: 231k]
  ------------------
  154|  2.10k|        return buf;
  155|       |
  156|   231k|    if (!cp || !cp[0] || mp_charset_is_utf8(cp))
  ------------------
  |  Branch (156:9): [True: 0, False: 231k]
  |  Branch (156:16): [True: 0, False: 231k]
  |  Branch (156:26): [True: 0, False: 231k]
  ------------------
  157|      0|        return buf;
  158|       |
  159|   231k|    if (strcasecmp(cp, "ASCII") == 0)
  ------------------
  |  Branch (159:9): [True: 0, False: 231k]
  ------------------
  160|      0|        return buf;
  161|       |
  162|   231k|    if (strcasecmp(cp, "UTF-8-BROKEN") == 0)
  ------------------
  |  Branch (162:9): [True: 13.7k, False: 217k]
  ------------------
  163|  13.7k|        return bstr_sanitize_utf8_latin1(NULL, buf);
  164|       |
  165|       |    // Force CP949 over EUC-KR since iconv distinguishes them and
  166|       |    // EUC-KR causes error on CP949 encoded data
  167|   217k|    if (strcasecmp(cp, "EUC-KR") == 0)
  ------------------
  |  Branch (167:9): [True: 0, False: 217k]
  ------------------
  168|      0|        cp = "CP949";
  169|       |
  170|   217k|    iconv_t icdsc;
  171|   217k|    if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) {
  ------------------
  |  Branch (171:9): [True: 4.41k, False: 213k]
  ------------------
  172|  4.41k|        if (flags & MP_ICONV_VERBOSE)
  ------------------
  |  Branch (172:13): [True: 0, False: 4.41k]
  ------------------
  173|      0|            mp_err(log, "Error opening iconv with codepage '%s'\n", cp);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  174|  4.41k|        goto failure;
  175|  4.41k|    }
  176|       |
  177|   213k|    size_t size = buf.len;
  178|   213k|    size_t osize = size;
  179|   213k|    size_t ileft = size;
  180|   213k|    size_t oleft = size - 1;
  181|       |
  182|   213k|    char *outbuf = talloc_size(NULL, osize);
  ------------------
  |  |   43|   213k|#define talloc_size                     ta_xalloc_size
  |  |  ------------------
  |  |  |  |  120|   213k|#define ta_xalloc_size(...)             ta_oom_p(ta_alloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  153|   213k|#define ta_alloc_size(...)      ta_dbg_set_loc(ta_alloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|   213k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|   213k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|   213k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  183|   213k|    char *ip = buf.start;
  184|   213k|    char *op = outbuf;
  185|       |
  186|   716k|    while (1) {
  ------------------
  |  Branch (186:12): [Folded - Ignored]
  ------------------
  187|   716k|        int clear = 0;
  188|   716k|        size_t rc;
  189|   716k|        if (ileft)
  ------------------
  |  Branch (189:13): [True: 505k, False: 210k]
  ------------------
  190|   505k|            rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
  191|   210k|        else {
  192|   210k|            clear = 1; // clear the conversion state and leave
  193|   210k|            rc = iconv(icdsc, NULL, NULL, &op, &oleft);
  194|   210k|        }
  195|   716k|        if (rc == (size_t) (-1)) {
  ------------------
  |  Branch (195:13): [True: 296k, False: 419k]
  ------------------
  196|   296k|            if (errno == E2BIG) {
  ------------------
  |  Branch (196:17): [True: 293k, False: 3.47k]
  ------------------
  197|   293k|                size_t offset = op - outbuf;
  198|   293k|                outbuf = talloc_realloc_size(NULL, outbuf, osize + size);
  ------------------
  |  |   39|   293k|#define talloc_realloc_size             ta_xrealloc_size
  |  |  ------------------
  |  |  |  |  158|   293k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|   293k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|   293k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|   293k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  199|   293k|                op = outbuf + offset;
  200|   293k|                osize += size;
  201|   293k|                oleft += size;
  202|   293k|            } else {
  203|  3.47k|                if (errno == EINVAL && (flags & MP_ICONV_ALLOW_CUTOFF)) {
  ------------------
  |  Branch (203:21): [True: 886, False: 2.58k]
  |  Branch (203:40): [True: 0, False: 886]
  ------------------
  204|       |                    // This is intended for cases where the input buffer is cut
  205|       |                    // at a random byte position. If this happens in the middle
  206|       |                    // of the buffer, it should still be an error. We say it's
  207|       |                    // fine if the error is within 10 bytes of the end.
  208|      0|                    if (ileft <= 10)
  ------------------
  |  Branch (208:25): [True: 0, False: 0]
  ------------------
  209|      0|                        break;
  210|      0|                }
  211|  3.47k|                if (flags & MP_ICONV_VERBOSE) {
  ------------------
  |  Branch (211:21): [True: 501, False: 2.97k]
  ------------------
  212|    501|                    mp_err(log, "Error recoding text with codepage '%s'\n", cp);
  ------------------
  |  |   72|    501|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  213|    501|                }
  214|  3.47k|                talloc_free(outbuf);
  ------------------
  |  |   47|  3.47k|#define talloc_free                     ta_free
  ------------------
  215|  3.47k|                iconv_close(icdsc);
  216|  3.47k|                goto failure;
  217|  3.47k|            }
  218|   419k|        } else if (clear)
  ------------------
  |  Branch (218:20): [True: 209k, False: 209k]
  ------------------
  219|   209k|            break;
  220|   716k|    }
  221|       |
  222|   209k|    iconv_close(icdsc);
  223|       |
  224|   209k|    outbuf[osize - oleft - 1] = 0;
  225|   209k|    return (bstr){outbuf, osize - oleft - 1};
  226|       |
  227|  7.88k|failure:
  228|  7.88k|#endif
  229|       |
  230|  7.88k|    if (flags & MP_NO_LATIN1_FALLBACK) {
  ------------------
  |  Branch (230:9): [True: 4.41k, False: 3.47k]
  ------------------
  231|  4.41k|        return buf;
  232|  4.41k|    } else {
  233|  3.47k|        return bstr_sanitize_utf8_latin1(NULL, buf);
  234|  3.47k|    }
  235|  7.88k|}
charset_conv.c:ms_bom_guess:
   58|   646k|{
   59|  2.58M|    for (int n = 0; n < 3; n++) {
  ------------------
  |  Branch (59:21): [True: 1.93M, False: 645k]
  ------------------
   60|  1.93M|        if (bstr_startswith0(buf, utf_bom[n]))
  ------------------
  |  Branch (60:13): [True: 338, False: 1.93M]
  ------------------
   61|    338|            return utf_enc[n];
   62|  1.93M|    }
   63|   645k|    return NULL;
   64|   646k|}
charset_conv.c:mp_uchardet:
   68|   163k|{
   69|   163k|    uchardet_t det = uchardet_new();
   70|   163k|    if (!det)
  ------------------
  |  Branch (70:9): [True: 0, False: 163k]
  ------------------
   71|      0|        return NULL;
   72|   163k|    if (uchardet_handle_data(det, buf.start, buf.len) != 0) {
  ------------------
  |  Branch (72:9): [True: 0, False: 163k]
  ------------------
   73|      0|        uchardet_delete(det);
   74|      0|        return NULL;
   75|      0|    }
   76|   163k|    uchardet_data_end(det);
   77|   163k|    char *res = talloc_strdup(talloc_ctx, uchardet_get_charset(det));
  ------------------
  |  |   50|   163k|#define talloc_strdup                   ta_xstrdup
  ------------------
   78|   163k|    if (res && !res[0])
  ------------------
  |  Branch (78:9): [True: 163k, False: 0]
  |  Branch (78:16): [True: 6.75k, False: 156k]
  ------------------
   79|  6.75k|        res = NULL;
   80|   163k|    if (res) {
  ------------------
  |  Branch (80:9): [True: 156k, False: 6.75k]
  ------------------
   81|   156k|        mp_verbose(log, "libuchardet detected charset as %s\n", res);
  ------------------
  |  |   75|   156k|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
   82|   156k|        iconv_t icdsc = iconv_open("UTF-8", res);
   83|   156k|        if (icdsc == (iconv_t)(-1)) {
  ------------------
  |  Branch (83:13): [True: 0, False: 156k]
  ------------------
   84|      0|            mp_warn(log, "Charset '%s' not supported by iconv.\n", res);
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
   85|      0|            res = NULL;
   86|   156k|        } else {
   87|   156k|            iconv_close(icdsc);
   88|   156k|        }
   89|   156k|    }
   90|   163k|    uchardet_delete(det);
   91|   163k|    return res;
   92|   163k|}

client.c:mp_isalnum:
   14|  23.2k|static inline int mp_isalnum(char c) { return mp_isalpha(c) || mp_isdigit(c); }
  ------------------
  |  Branch (14:47): [True: 23.2k, False: 0]
  |  Branch (14:64): [True: 0, False: 0]
  ------------------
client.c:mp_isalpha:
   13|  23.2k|static inline int mp_isalpha(char c) { return mp_isupper(c) || mp_islower(c); }
  ------------------
  |  Branch (13:47): [True: 0, False: 23.2k]
  |  Branch (13:64): [True: 23.2k, False: 0]
  ------------------
client.c:mp_isupper:
   10|  23.2k|static inline int mp_isupper(char c) { return c >= 'A' && c <= 'Z'; }
  ------------------
  |  Branch (10:47): [True: 23.2k, False: 0]
  |  Branch (10:59): [True: 0, False: 23.2k]
  ------------------
client.c:mp_islower:
   11|  23.2k|static inline int mp_islower(char c) { return c >= 'a' && c <= 'z'; }
  ------------------
  |  Branch (11:47): [True: 23.2k, False: 0]
  |  Branch (11:59): [True: 23.2k, False: 0]
  ------------------
bstr.c:mp_isspace:
    8|  64.9M|static inline int mp_isspace(char c) { return c == ' ' || c == '\f' || c == '\n' ||
  ------------------
  |  Branch (8:47): [True: 40.0M, False: 24.8M]
  |  Branch (8:59): [True: 214, False: 24.8M]
  |  Branch (8:72): [True: 363, False: 24.8M]
  ------------------
    9|  64.9M|                                              c == '\r' || c == '\t' || c =='\v'; }
  ------------------
  |  Branch (9:47): [True: 28.7k, False: 24.8M]
  |  Branch (9:60): [True: 86.0k, False: 24.7M]
  |  Branch (9:73): [True: 2.15k, False: 24.7M]
  ------------------
path_utils.c:mp_isalpha:
   13|  4.43M|static inline int mp_isalpha(char c) { return mp_isupper(c) || mp_islower(c); }
  ------------------
  |  Branch (13:47): [True: 18.6k, False: 4.41M]
  |  Branch (13:64): [True: 4.34M, False: 67.0k]
  ------------------
path_utils.c:mp_isupper:
   10|  4.43M|static inline int mp_isupper(char c) { return c >= 'A' && c <= 'Z'; }
  ------------------
  |  Branch (10:47): [True: 4.36M, False: 65.6k]
  |  Branch (10:59): [True: 18.6k, False: 4.34M]
  ------------------
path_utils.c:mp_islower:
   11|  4.41M|static inline int mp_islower(char c) { return c >= 'a' && c <= 'z'; }
  ------------------
  |  Branch (11:47): [True: 4.34M, False: 66.6k]
  |  Branch (11:59): [True: 4.34M, False: 453]
  ------------------
path_utils.c:mp_isalnum:
   14|  3.79M|static inline int mp_isalnum(char c) { return mp_isalpha(c) || mp_isdigit(c); }
  ------------------
  |  Branch (14:47): [True: 3.74M, False: 51.3k]
  |  Branch (14:64): [True: 15.7k, False: 35.6k]
  ------------------
path_utils.c:mp_isdigit:
   12|  51.3k|static inline int mp_isdigit(char c) { return c >= '0' && c <= '9'; }
  ------------------
  |  Branch (12:47): [True: 17.5k, False: 33.8k]
  |  Branch (12:59): [True: 15.7k, False: 1.79k]
  ------------------
parse_configfile.c:mp_isalnum:
   14|  4.72M|static inline int mp_isalnum(char c) { return mp_isalpha(c) || mp_isdigit(c); }
  ------------------
  |  Branch (14:47): [True: 3.99M, False: 726k]
  |  Branch (14:64): [True: 0, False: 726k]
  ------------------
parse_configfile.c:mp_isalpha:
   13|  4.72M|static inline int mp_isalpha(char c) { return mp_isupper(c) || mp_islower(c); }
  ------------------
  |  Branch (13:47): [True: 0, False: 4.72M]
  |  Branch (13:64): [True: 3.99M, False: 726k]
  ------------------
parse_configfile.c:mp_isupper:
   10|  4.72M|static inline int mp_isupper(char c) { return c >= 'A' && c <= 'Z'; }
  ------------------
  |  Branch (10:47): [True: 3.99M, False: 726k]
  |  Branch (10:59): [True: 0, False: 3.99M]
  ------------------
parse_configfile.c:mp_islower:
   11|  4.72M|static inline int mp_islower(char c) { return c >= 'a' && c <= 'z'; }
  ------------------
  |  Branch (11:47): [True: 3.99M, False: 726k]
  |  Branch (11:59): [True: 3.99M, False: 0]
  ------------------
parse_configfile.c:mp_isdigit:
   12|   726k|static inline int mp_isdigit(char c) { return c >= '0' && c <= '9'; }
  ------------------
  |  Branch (12:47): [True: 348k, False: 377k]
  |  Branch (12:59): [True: 0, False: 348k]
  ------------------

mp_dispatch_create:
   84|  8.59k|{
   85|  8.59k|    struct mp_dispatch_queue *queue = talloc_ptrtype(ta_parent, queue);
  ------------------
  |  |   34|  8.59k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  8.59k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  8.59k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   86|  8.59k|    *queue = (struct mp_dispatch_queue){0};
   87|  8.59k|    talloc_set_destructor(queue, queue_dtor);
  ------------------
  |  |   41|  8.59k|#define talloc_set_destructor           ta_set_destructor
  ------------------
   88|  8.59k|    mp_mutex_init(&queue->lock);
   89|  8.59k|    mp_cond_init(&queue->cond);
   90|  8.59k|    return queue;
   91|  8.59k|}
mp_dispatch_set_wakeup_fn:
  105|  2.78k|{
  106|  2.78k|    queue->wakeup_fn = wakeup_fn;
  107|  2.78k|    queue->wakeup_ctx = wakeup_ctx;
  108|  2.78k|}
mp_dispatch_enqueue_autofree:
  186|  50.9k|{
  187|  50.9k|    struct mp_dispatch_item *item = talloc_ptrtype(NULL, item);
  ------------------
  |  |   34|  50.9k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  50.9k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  50.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  188|  50.9k|    *item = (struct mp_dispatch_item){
  189|  50.9k|        .fn = fn,
  190|  50.9k|        .fn_data = talloc_steal(item, fn_data),
  ------------------
  |  |   38|  50.9k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  50.9k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  191|  50.9k|        .asynchronous = true,
  192|  50.9k|    };
  193|  50.9k|    mp_dispatch_append(queue, item);
  194|  50.9k|}
mp_dispatch_cancel_fn:
  220|  8.59k|{
  221|  8.59k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  8.59k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  222|  8.59k|    struct mp_dispatch_item **pcur = &queue->head;
  223|  8.59k|    queue->tail = NULL;
  224|  8.59k|    while (*pcur) {
  ------------------
  |  Branch (224:12): [True: 0, False: 8.59k]
  ------------------
  225|      0|        struct mp_dispatch_item *cur = *pcur;
  226|      0|        if (cur->fn == fn && cur->fn_data == fn_data) {
  ------------------
  |  Branch (226:13): [True: 0, False: 0]
  |  Branch (226:30): [True: 0, False: 0]
  ------------------
  227|      0|            *pcur = cur->next;
  228|      0|            talloc_free(cur);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  229|      0|        } else {
  230|      0|            queue->tail = cur;
  231|      0|            pcur = &cur->next;
  232|      0|        }
  233|      0|    }
  234|  8.59k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  8.59k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  235|  8.59k|}
mp_dispatch_run:
  243|  33.1k|{
  244|  33.1k|    struct mp_dispatch_item item = {
  245|  33.1k|        .fn = fn,
  246|  33.1k|        .fn_data = fn_data,
  247|  33.1k|    };
  248|  33.1k|    mp_dispatch_append(queue, &item);
  249|       |
  250|  33.1k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  33.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  251|  66.1k|    while (!item.completed)
  ------------------
  |  Branch (251:12): [True: 33.0k, False: 33.1k]
  ------------------
  252|  33.0k|        mp_cond_wait(&queue->cond, &queue->lock);
  253|  33.1k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  33.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  254|  33.1k|}
mp_dispatch_queue_process:
  273|   257k|{
  274|   257k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|   257k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  275|   257k|    queue->wait = timeout > 0 ? mp_time_ns_add(mp_time_ns(), timeout) : 0;
  ------------------
  |  Branch (275:19): [True: 130k, False: 126k]
  ------------------
  276|   257k|    mp_assert(!queue->in_process); // recursion not allowed
  ------------------
  |  |   41|   257k|#define mp_assert assert
  ------------------
  277|   257k|    queue->in_process = true;
  278|   257k|    queue->in_process_thread_id = mp_thread_current_id();
  ------------------
  |  |  214|   257k|#define mp_thread_current_id      pthread_self
  ------------------
  279|       |    // Wake up thread which called mp_dispatch_lock().
  280|   257k|    if (queue->lock_requests)
  ------------------
  |  Branch (280:9): [True: 8.61k, False: 248k]
  ------------------
  281|  8.61k|        mp_cond_broadcast(&queue->cond);
  282|   478k|    while (1) {
  ------------------
  |  Branch (282:12): [Folded - Ignored]
  ------------------
  283|   478k|        if (queue->lock_requests) {
  ------------------
  |  Branch (283:13): [True: 39.3k, False: 439k]
  ------------------
  284|       |            // Block due to something having called mp_dispatch_lock().
  285|  39.3k|            mp_cond_wait(&queue->cond, &queue->lock);
  286|   439k|        } else if (queue->head) {
  ------------------
  |  Branch (286:20): [True: 84.1k, False: 355k]
  ------------------
  287|  84.1k|            struct mp_dispatch_item *item = queue->head;
  288|  84.1k|            queue->head = item->next;
  289|  84.1k|            if (!queue->head)
  ------------------
  |  Branch (289:17): [True: 81.8k, False: 2.24k]
  ------------------
  290|  81.8k|                queue->tail = NULL;
  291|  84.1k|            item->next = NULL;
  292|       |            // Unlock, because we want to allow other threads to queue items
  293|       |            // while the dispatch item is processed.
  294|       |            // At the same time, we must prevent other threads from returning
  295|       |            // from mp_dispatch_lock(), which is done by locked=true.
  296|  84.1k|            mp_assert(!queue->locked);
  ------------------
  |  |   41|  84.1k|#define mp_assert assert
  ------------------
  297|  84.1k|            queue->locked = true;
  298|  84.1k|            mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  84.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  299|       |
  300|  84.1k|            item->fn(item->fn_data);
  301|       |
  302|  84.1k|            mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  84.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  303|  84.1k|            mp_assert(queue->locked);
  ------------------
  |  |   41|  84.1k|#define mp_assert assert
  ------------------
  304|  84.1k|            queue->locked = false;
  305|       |            // Wakeup mp_dispatch_run(), also mp_dispatch_lock().
  306|  84.1k|            mp_cond_broadcast(&queue->cond);
  307|  84.1k|            if (item->asynchronous) {
  ------------------
  |  Branch (307:17): [True: 50.9k, False: 33.1k]
  ------------------
  308|  50.9k|                talloc_free(item);
  ------------------
  |  |   47|  50.9k|#define talloc_free                     ta_free
  ------------------
  309|  50.9k|            } else {
  310|  33.1k|                item->completed = true;
  311|  33.1k|            }
  312|   355k|        } else if (queue->wait > 0 && !queue->interrupted) {
  ------------------
  |  Branch (312:20): [True: 228k, False: 127k]
  |  Branch (312:39): [True: 98.3k, False: 129k]
  ------------------
  313|  98.3k|            if (mp_cond_timedwait_until(&queue->cond, &queue->lock, queue->wait))
  ------------------
  |  Branch (313:17): [True: 810, False: 97.4k]
  ------------------
  314|    810|                queue->wait = 0;
  315|   257k|        } else {
  316|   257k|            break;
  317|   257k|        }
  318|   478k|    }
  319|   257k|    mp_assert(!queue->locked);
  ------------------
  |  |   41|   257k|#define mp_assert assert
  ------------------
  320|   257k|    queue->in_process = false;
  321|   257k|    queue->interrupted = false;
  322|   257k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|   257k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  323|   257k|}
mp_dispatch_interrupt:
  332|   546k|{
  333|   546k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|   546k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  334|   546k|    queue->interrupted = true;
  335|   546k|    mp_cond_broadcast(&queue->cond);
  336|   546k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|   546k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  337|   546k|}
mp_dispatch_adjust_timeout:
  348|   295k|{
  349|   295k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|   295k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  350|   295k|    if (queue->in_process && queue->wait > until) {
  ------------------
  |  Branch (350:9): [True: 0, False: 295k]
  |  Branch (350:30): [True: 0, False: 0]
  ------------------
  351|      0|        queue->wait = until;
  352|      0|        mp_cond_broadcast(&queue->cond);
  353|      0|    }
  354|   295k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|   295k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  355|   295k|}
mp_dispatch_lock:
  365|  68.4k|{
  366|  68.4k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  68.4k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  367|       |    // Must not be called recursively from dispatched callbacks.
  368|  68.4k|    if (queue->in_process)
  ------------------
  |  Branch (368:9): [True: 59.8k, False: 8.61k]
  ------------------
  369|  68.4k|        mp_assert(!mp_thread_id_equal(queue->in_process_thread_id, mp_thread_current_id()));
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  370|       |    // Must not be called recursively at all.
  371|  68.4k|    if (queue->locked_explicit)
  ------------------
  |  Branch (371:9): [True: 0, False: 68.4k]
  ------------------
  372|  68.4k|        mp_assert(!mp_thread_id_equal(queue->locked_explicit_thread_id, mp_thread_current_id()));
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  373|  68.4k|    queue->lock_requests += 1;
  374|       |    // And now wait until the target thread gets "trapped" within the
  375|       |    // mp_dispatch_queue_process() call, which will mean we get exclusive
  376|       |    // access to the target's thread state.
  377|  68.4k|    if (queue->onlock_fn)
  ------------------
  |  Branch (377:9): [True: 0, False: 68.4k]
  ------------------
  378|      0|        queue->onlock_fn(queue->onlock_ctx);
  379|  77.0k|    while (!queue->in_process) {
  ------------------
  |  Branch (379:12): [True: 8.62k, False: 68.4k]
  ------------------
  380|  8.62k|        mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  8.62k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  381|  8.62k|        if (queue->wakeup_fn)
  ------------------
  |  Branch (381:13): [True: 0, False: 8.62k]
  ------------------
  382|      0|            queue->wakeup_fn(queue->wakeup_ctx);
  383|  8.62k|        mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  8.62k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  384|  8.62k|        if (queue->in_process)
  ------------------
  |  Branch (384:13): [True: 4, False: 8.61k]
  ------------------
  385|      4|            break;
  386|  8.61k|        mp_cond_wait(&queue->cond, &queue->lock);
  387|  8.61k|    }
  388|       |    // Wait until we can get the lock.
  389|  68.4k|    while (!queue->in_process || queue->locked)
  ------------------
  |  Branch (389:12): [True: 0, False: 68.4k]
  |  Branch (389:34): [True: 0, False: 68.4k]
  ------------------
  390|      0|        mp_cond_wait(&queue->cond, &queue->lock);
  391|       |    // "Lock".
  392|  68.4k|    mp_assert(queue->lock_requests);
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  393|  68.4k|    mp_assert(!queue->locked);
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  394|  68.4k|    mp_assert(!queue->locked_explicit);
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  395|  68.4k|    queue->locked = true;
  396|  68.4k|    queue->locked_explicit = true;
  397|  68.4k|    queue->locked_explicit_thread_id = mp_thread_current_id();
  ------------------
  |  |  214|  68.4k|#define mp_thread_current_id      pthread_self
  ------------------
  398|  68.4k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  68.4k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  399|  68.4k|}
mp_dispatch_unlock:
  403|  68.4k|{
  404|  68.4k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  68.4k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  405|  68.4k|    mp_assert(queue->locked);
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  406|       |    // Must be called after a mp_dispatch_lock(), from the same thread.
  407|  68.4k|    mp_assert(queue->locked_explicit);
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  408|  68.4k|    mp_assert(mp_thread_id_equal(queue->locked_explicit_thread_id, mp_thread_current_id()));
  ------------------
  |  |   41|  68.4k|#define mp_assert assert
  ------------------
  409|       |    // "Unlock".
  410|  68.4k|    queue->locked = false;
  411|  68.4k|    queue->locked_explicit = false;
  412|  68.4k|    queue->lock_requests -= 1;
  413|       |    // Wakeup mp_dispatch_queue_process(), and maybe other mp_dispatch_lock()s.
  414|       |    // (Would be nice to wake up only 1 other locker if lock_requests>0.)
  415|  68.4k|    mp_cond_broadcast(&queue->cond);
  416|  68.4k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  68.4k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  417|  68.4k|}
dispatch.c:queue_dtor:
   64|  8.59k|{
   65|  8.59k|    struct mp_dispatch_queue *queue = p;
   66|  8.59k|    mp_assert(!queue->head);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
   67|  8.59k|    mp_assert(!queue->in_process);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
   68|  8.59k|    mp_assert(!queue->lock_requests);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
   69|  8.59k|    mp_assert(!queue->locked);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
   70|  8.59k|    mp_cond_destroy(&queue->cond);
   71|  8.59k|    mp_mutex_destroy(&queue->lock);
  ------------------
  |  |  130|  8.59k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
   72|  8.59k|}
dispatch.c:mp_dispatch_append:
  128|  84.1k|{
  129|  84.1k|    mp_mutex_lock(&queue->lock);
  ------------------
  |  |  131|  84.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  130|  84.1k|    if (item->mergeable) {
  ------------------
  |  Branch (130:9): [True: 0, False: 84.1k]
  ------------------
  131|      0|        for (struct mp_dispatch_item *cur = queue->head; cur; cur = cur->next) {
  ------------------
  |  Branch (131:58): [True: 0, False: 0]
  ------------------
  132|      0|            if (cur->mergeable && cur->fn == item->fn &&
  ------------------
  |  Branch (132:17): [True: 0, False: 0]
  |  Branch (132:35): [True: 0, False: 0]
  ------------------
  133|      0|                cur->fn_data == item->fn_data)
  ------------------
  |  Branch (133:17): [True: 0, False: 0]
  ------------------
  134|      0|            {
  135|      0|                talloc_free(item);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  136|      0|                mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  137|      0|                return;
  138|      0|            }
  139|      0|        }
  140|      0|    }
  141|       |
  142|  84.1k|    if (queue->tail) {
  ------------------
  |  Branch (142:9): [True: 2.24k, False: 81.8k]
  ------------------
  143|  2.24k|        queue->tail->next = item;
  144|  81.8k|    } else {
  145|  81.8k|        queue->head = item;
  146|  81.8k|    }
  147|  84.1k|    queue->tail = item;
  148|       |
  149|       |    // Wake up the main thread; note that other threads might wait on this
  150|       |    // condition for reasons, so broadcast the condition.
  151|  84.1k|    mp_cond_broadcast(&queue->cond);
  152|       |    // No wakeup callback -> assume mp_dispatch_queue_process() needs to be
  153|       |    // interrupted instead.
  154|  84.1k|    if (!queue->wakeup_fn)
  ------------------
  |  Branch (154:9): [True: 0, False: 84.1k]
  ------------------
  155|      0|        queue->interrupted = true;
  156|  84.1k|    mp_mutex_unlock(&queue->lock);
  ------------------
  |  |  133|  84.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  157|       |
  158|  84.1k|    if (queue->wakeup_fn)
  ------------------
  |  Branch (158:9): [True: 84.1k, False: 0]
  ------------------
  159|  84.1k|        queue->wakeup_fn(queue->wakeup_ctx);
  160|  84.1k|}

json_append:
  295|  29.0k|{
  296|  29.0k|    switch (src->format) {
  ------------------
  |  Branch (296:13): [True: 0, False: 29.0k]
  ------------------
  297|      0|    case MPV_FORMAT_NONE:
  ------------------
  |  Branch (297:5): [True: 0, False: 29.0k]
  ------------------
  298|      0|        APPEND(b, "null");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  299|      0|        return 0;
  300|      0|    case MPV_FORMAT_FLAG:
  ------------------
  |  Branch (300:5): [True: 0, False: 29.0k]
  ------------------
  301|      0|        APPEND(b, src->u.flag ? "true" : "false");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  |  |  ------------------
  |  |  |  Branch (248:52): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  302|      0|        return 0;
  303|      0|    case MPV_FORMAT_INT64:
  ------------------
  |  Branch (303:5): [True: 0, False: 29.0k]
  ------------------
  304|      0|        bstr_xappend_asprintf(NULL, b, "%"PRId64, src->u.int64);
  305|      0|        return 0;
  306|      0|    case MPV_FORMAT_DOUBLE: {
  ------------------
  |  Branch (306:5): [True: 0, False: 29.0k]
  ------------------
  307|      0|        const char *px = (isfinite(src->u.double_) || indent == 0) ? "" : "\"";
  ------------------
  |  Branch (307:55): [True: 0, False: 0]
  ------------------
  308|      0|        bstr_xappend_asprintf(NULL, b, "%s%f%s", px, src->u.double_, px);
  309|      0|        return 0;
  310|      0|    }
  311|  29.0k|    case MPV_FORMAT_STRING:
  ------------------
  |  Branch (311:5): [True: 29.0k, False: 0]
  ------------------
  312|  29.0k|        if (indent == 0)
  ------------------
  |  Branch (312:13): [True: 0, False: 29.0k]
  ------------------
  313|      0|            APPEND(b, src->u.string);
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  314|  29.0k|        else
  315|  29.0k|            write_json_str(b, src->u.string);
  316|  29.0k|        return 0;
  317|      0|    case MPV_FORMAT_NODE_ARRAY:
  ------------------
  |  Branch (317:5): [True: 0, False: 29.0k]
  ------------------
  318|      0|    case MPV_FORMAT_NODE_MAP: {
  ------------------
  |  Branch (318:5): [True: 0, False: 29.0k]
  ------------------
  319|      0|        struct mpv_node_list *list = src->u.list;
  320|      0|        bool is_obj = src->format == MPV_FORMAT_NODE_MAP;
  321|      0|        APPEND(b, is_obj ? "{" : "[");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  |  |  ------------------
  |  |  |  Branch (248:52): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  322|      0|        int next_indent = indent >= 0 ? indent + 1 : -1;
  ------------------
  |  Branch (322:27): [True: 0, False: 0]
  ------------------
  323|      0|        for (int n = 0; n < list->num; n++) {
  ------------------
  |  Branch (323:25): [True: 0, False: 0]
  ------------------
  324|      0|            if (n)
  ------------------
  |  Branch (324:17): [True: 0, False: 0]
  ------------------
  325|      0|                APPEND(b, ",");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  326|      0|            add_indent(b, next_indent);
  327|      0|            if (is_obj) {
  ------------------
  |  Branch (327:17): [True: 0, False: 0]
  ------------------
  328|      0|                write_json_str(b, list->keys[n]);
  329|      0|                APPEND(b, ":");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  330|      0|            }
  331|      0|            json_append(b, &list->values[n], next_indent);
  332|      0|        }
  333|      0|        add_indent(b, indent);
  334|      0|        APPEND(b, is_obj ? "}" : "]");
  ------------------
  |  |  248|      0|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  |  |  ------------------
  |  |  |  Branch (248:52): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  335|      0|        return 0;
  336|      0|    }
  337|  29.0k|    }
  338|      0|    return -1; // unknown format
  339|  29.0k|}
json_write:
  355|  29.0k|{
  356|  29.0k|    return json_append_str(dst, src, -1);
  357|  29.0k|}
json.c:write_json_str:
  259|  29.0k|{
  260|  29.0k|    mp_assert(str);
  ------------------
  |  |   41|  29.0k|#define mp_assert assert
  ------------------
  261|       |
  262|  29.0k|    APPEND(b, "\"");
  ------------------
  |  |  248|  29.0k|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  263|  83.9M|    while (1) {
  ------------------
  |  Branch (263:12): [Folded - Ignored]
  ------------------
  264|  83.9M|        unsigned char *cur = str;
  265|   252M|        while (cur[0] >= 32 && cur[0] != '"' && cur[0] != '\\')
  ------------------
  |  Branch (265:16): [True: 169M, False: 83.0M]
  |  Branch (265:32): [True: 169M, False: 179k]
  |  Branch (265:49): [True: 168M, False: 674k]
  ------------------
  266|   168M|            cur++;
  267|  83.9M|        if (!cur[0])
  ------------------
  |  Branch (267:13): [True: 29.0k, False: 83.8M]
  ------------------
  268|  29.0k|            break;
  269|  83.8M|        bstr_xappend(NULL, b, (bstr){str, cur - str});
  270|  83.8M|        if (cur[0] == '\"') {
  ------------------
  |  Branch (270:13): [True: 179k, False: 83.7M]
  ------------------
  271|   179k|            bstr_xappend(NULL, b, (bstr){"\\\"", 2});
  272|  83.7M|        } else if (cur[0] == '\\') {
  ------------------
  |  Branch (272:20): [True: 674k, False: 83.0M]
  ------------------
  273|   674k|            bstr_xappend(NULL, b, (bstr){"\\\\", 2});
  274|  83.0M|        } else if (cur[0] < sizeof(special_escape) && special_escape[cur[0]]) {
  ------------------
  |  Branch (274:20): [True: 30.5M, False: 52.4M]
  |  Branch (274:55): [True: 21.8M, False: 8.76M]
  ------------------
  275|  21.8M|            bstr_xappend_asprintf(NULL, b, "\\%c", special_escape[cur[0]]);
  276|  61.2M|        } else {
  277|  61.2M|            bstr_xappend_asprintf(NULL, b, "\\u%04x", (unsigned char)cur[0]);
  278|  61.2M|        }
  279|  83.8M|        str = cur + 1;
  280|  83.8M|    }
  281|  29.0k|    APPEND(b, str);
  ------------------
  |  |  248|  29.0k|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  282|  29.0k|    APPEND(b, "\"");
  ------------------
  |  |  248|  29.0k|#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
  ------------------
  283|  29.0k|}
json.c:json_append_str:
  342|  29.0k|{
  343|  29.0k|    bstr buffer = bstr0(*dst);
  344|  29.0k|    int r = json_append(&buffer, src, indent);
  345|  29.0k|    *dst = buffer.start;
  346|  29.0k|    return r;
  347|  29.0k|}

mp_match_lang:
  252|    341|{
  253|    341|    if (!lang)
  ------------------
  |  Branch (253:9): [True: 341, False: 0]
  ------------------
  254|    341|        return 0;
  255|       |
  256|      0|    void *ta_ctx = talloc_new(NULL);
  ------------------
  |  |   40|      0|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      0|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  257|      0|    int lang_parts_n = 0;
  258|      0|    bstr *lang_parts = NULL;
  259|      0|    bstr rest = bstr0(lang);
  260|      0|    while (rest.len) {
  ------------------
  |  Branch (260:12): [True: 0, False: 0]
  ------------------
  261|      0|        bstr s = bstr_split(rest, "-", &rest);
  262|      0|        MP_TARRAY_APPEND(ta_ctx, lang_parts, lang_parts_n, s);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  263|      0|    }
  264|       |
  265|      0|    int best_score = 0;
  266|      0|    if (!lang_parts_n)
  ------------------
  |  Branch (266:9): [True: 0, False: 0]
  ------------------
  267|      0|        goto done;
  268|       |
  269|      0|    for (int idx = 0; langs && langs[idx]; idx++) {
  ------------------
  |  Branch (269:23): [True: 0, False: 0]
  |  Branch (269:32): [True: 0, False: 0]
  ------------------
  270|      0|        rest = bstr0(langs[idx]);
  271|      0|        int part = 0;
  272|      0|        int score = 0;
  273|      0|        while (rest.len) {
  ------------------
  |  Branch (273:16): [True: 0, False: 0]
  ------------------
  274|      0|            bstr s = bstr_split(rest, "-", &rest);
  275|      0|            if (!part) {
  ------------------
  |  Branch (275:17): [True: 0, False: 0]
  ------------------
  276|      0|                if (bstrcasecmp(canonicalize(lang_parts[0]), canonicalize(s)))
  ------------------
  |  Branch (276:21): [True: 0, False: 0]
  ------------------
  277|      0|                    break;
  278|      0|                score = INT_MAX - idx;
  279|      0|                part++;
  280|      0|                continue;
  281|      0|            }
  282|       |
  283|      0|            if (part >= lang_parts_n)
  ------------------
  |  Branch (283:17): [True: 0, False: 0]
  ------------------
  284|      0|                break;
  285|       |
  286|      0|            if (bstrcasecmp(lang_parts[part], s))
  ------------------
  |  Branch (286:17): [True: 0, False: 0]
  ------------------
  287|      0|                score -= 1000;
  288|       |
  289|      0|            part++;
  290|      0|        }
  291|      0|        score -= (lang_parts_n - part) * 1000;
  292|      0|        best_score = MPMAX(best_score, score);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  293|      0|    }
  294|       |
  295|      0|done:
  296|      0|    talloc_free(ta_ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  297|      0|    return best_score;
  298|      0|}

node_init:
   13|  23.2k|{
   14|       |    // Other formats need to be initialized manually.
   15|  23.2k|    mp_assert(format == MPV_FORMAT_NODE_MAP || format == MPV_FORMAT_NODE_ARRAY ||
  ------------------
  |  |   41|  23.2k|#define mp_assert assert
  ------------------
   16|  23.2k|           format == MPV_FORMAT_FLAG || format == MPV_FORMAT_INT64 ||
   17|  23.2k|           format == MPV_FORMAT_DOUBLE || format == MPV_FORMAT_BYTE_ARRAY ||
   18|  23.2k|           format == MPV_FORMAT_NONE);
   19|       |
   20|  23.2k|    void *ta_parent = NULL;
   21|  23.2k|    if (parent) {
  ------------------
  |  Branch (21:9): [True: 5.81k, False: 17.4k]
  ------------------
   22|  5.81k|        mp_assert(parent->format == MPV_FORMAT_NODE_MAP ||
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   23|  5.81k|               parent->format == MPV_FORMAT_NODE_ARRAY);
   24|  5.81k|        ta_parent = parent->u.list;
   25|  5.81k|    }
   26|       |
   27|  23.2k|    *dst = (struct mpv_node){ .format = format };
   28|  23.2k|    if (format == MPV_FORMAT_NODE_MAP || format == MPV_FORMAT_NODE_ARRAY)
  ------------------
  |  Branch (28:9): [True: 11.6k, False: 11.6k]
  |  Branch (28:42): [True: 5.81k, False: 5.81k]
  ------------------
   29|  17.4k|        dst->u.list = talloc_zero(ta_parent, struct mpv_node_list);
  ------------------
  |  |   27|  17.4k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  17.4k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  17.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   30|  23.2k|    if (format == MPV_FORMAT_BYTE_ARRAY)
  ------------------
  |  Branch (30:9): [True: 0, False: 23.2k]
  ------------------
   31|      0|        dst->u.ba = talloc_zero(ta_parent, struct mpv_byte_array);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   32|  23.2k|}
node_map_add:
   49|  5.81k|{
   50|  5.81k|    mp_assert(key);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   51|  5.81k|    return node_map_badd(dst, bstr0(key), format);
   52|  5.81k|}
node_map_badd:
   55|  5.81k|{
   56|  5.81k|    mp_assert(key.start);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   57|       |
   58|  5.81k|    struct mpv_node_list *list = dst->u.list;
   59|  5.81k|    mp_assert(dst->format == MPV_FORMAT_NODE_MAP && dst->u.list);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
   60|  5.81k|    MP_TARRAY_GROW(list, list->values, list->num);
  ------------------
  |  |   96|  5.81k|    do {                                            \
  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   61|  5.81k|    MP_TARRAY_GROW(list, list->keys, list->num);
  ------------------
  |  |   96|  5.81k|    do {                                            \
  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   62|  5.81k|    list->keys[list->num] = bstrdup0(list, key);
   63|  5.81k|    node_init(&list->values[list->num], format, dst);
   64|  5.81k|    return &list->values[list->num++];
   65|  5.81k|}
node_map_add_int64:
   89|  5.81k|{
   90|  5.81k|    node_map_add(dst, key, MPV_FORMAT_INT64)->u.int64 = v;
   91|  5.81k|}

mp_basename:
   43|   549k|{
   44|   549k|    char *s;
   45|       |
   46|       |#if HAVE_DOS_PATHS
   47|       |    if (!mp_is_url(bstr0(path))) {
   48|       |        s = strrchr(path, '\\');
   49|       |        if (s)
   50|       |            path = s + 1;
   51|       |        s = strrchr(path, ':');
   52|       |        if (s)
   53|       |            path = s + 1;
   54|       |    }
   55|       |#endif
   56|   549k|    s = strrchr(path, '/');
   57|   549k|    return s ? s + 1 : (char *)path;
  ------------------
  |  Branch (57:12): [True: 549k, False: 0]
  ------------------
   58|   549k|}
mp_dirname:
   61|  4.53k|{
   62|  4.53k|    struct bstr ret = {
   63|  4.53k|        (uint8_t *)path, mp_basename(path) - path
   64|  4.53k|    };
   65|  4.53k|    if (ret.len == 0)
  ------------------
  |  Branch (65:9): [True: 0, False: 4.53k]
  ------------------
   66|      0|        return bstr0(".");
   67|  4.53k|    return ret;
   68|  4.53k|}
mp_splitext:
   86|  9.32k|{
   87|  9.32k|    mp_assert(path);
  ------------------
  |  |   41|  9.32k|#define mp_assert assert
  ------------------
   88|  9.32k|    int skip = (*path == '.'); // skip leading dot for "hidden" unix files
   89|  9.32k|    const char *split = strrchr(path + skip, '.');
   90|  9.32k|    if (!split || !split[1] || strchr(split, '/'))
  ------------------
  |  Branch (90:9): [True: 4.51k, False: 4.81k]
  |  Branch (90:19): [True: 223, False: 4.58k]
  |  Branch (90:32): [True: 2.56k, False: 2.01k]
  ------------------
   91|  7.30k|        return NULL;
   92|  2.01k|    if (root)
  ------------------
  |  Branch (92:9): [True: 0, False: 2.01k]
  ------------------
   93|      0|        *root = (bstr){(char *)path, split - path};
   94|  2.01k|    return (char *)split + 1;
   95|  9.32k|}
mp_path_is_absolute:
   98|   158k|{
   99|   158k|    if (path.len && strchr(mp_path_separators, path.start[0]))
  ------------------
  |  Branch (99:9): [True: 158k, False: 123]
  |  Branch (99:21): [True: 1.84k, False: 156k]
  ------------------
  100|  1.84k|        return true;
  101|       |
  102|       |#if HAVE_DOS_PATHS
  103|       |    // Note: "X:filename" is a path relative to the current working directory
  104|       |    //       of drive X, and thus is not an absolute path. It needs to be
  105|       |    //       followed by \ or /.
  106|       |    if (path.len >= 3 && path.start[1] == ':' &&
  107|       |        strchr(mp_path_separators, path.start[2]))
  108|       |        return true;
  109|       |#endif
  110|       |
  111|   156k|    return false;
  112|   158k|}
mp_path_join_bstr:
  115|  89.9k|{
  116|  89.9k|    if (p1.len == 0)
  ------------------
  |  Branch (116:9): [True: 11.6k, False: 78.3k]
  ------------------
  117|  11.6k|        return bstrdup0(talloc_ctx, p2);
  118|  78.3k|    if (p2.len == 0)
  ------------------
  |  Branch (118:9): [True: 123, False: 78.1k]
  ------------------
  119|    123|        return bstrdup0(talloc_ctx, p1);
  120|       |
  121|  78.1k|    if (mp_path_is_absolute(p2))
  ------------------
  |  Branch (121:9): [True: 0, False: 78.1k]
  ------------------
  122|      0|        return bstrdup0(talloc_ctx, p2);
  123|       |
  124|  78.1k|    bool have_separator = strchr(mp_path_separators, p1.start[p1.len - 1]);
  125|       |#if HAVE_DOS_PATHS
  126|       |    // "X:" only => path relative to "X:" current working directory.
  127|       |    if (p1.len == 2 && p1.start[1] == ':')
  128|       |        have_separator = true;
  129|       |#endif
  130|       |
  131|  78.1k|    return talloc_asprintf(talloc_ctx, "%.*s%s%.*s", BSTR_P(p1),
  ------------------
  |  |   52|  78.1k|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|   469k|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 78.1k, False: 0]
  |  |  |  |  |  Branch (127:62): [True: 0, False: 78.1k]
  |  |  |  |  |  Branch (127:62): [True: 78.1k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|  78.1k|                           have_separator ? "" : "/", BSTR_P(p2));
  133|  78.1k|}
mp_path_join:
  136|  78.3k|{
  137|  78.3k|    return mp_path_join_bstr(talloc_ctx, bstr0(p1), bstr0(p2));
  138|  78.3k|}
mp_getcwd:
  141|  78.3k|{
  142|  78.3k|    char *e_wd = getenv("PWD");
  143|  78.3k|    if (e_wd)
  ------------------
  |  Branch (143:9): [True: 78.3k, False: 0]
  ------------------
  144|  78.3k|        return talloc_strdup(talloc_ctx, e_wd);
  ------------------
  |  |   50|  78.3k|#define talloc_strdup                   ta_xstrdup
  ------------------
  145|       |
  146|      0|    char *wd = talloc_array(talloc_ctx, char, 20);
  ------------------
  |  |   29|      0|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|      0|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  147|      0|    while (getcwd(wd, talloc_get_size(wd)) == NULL) {
  ------------------
  |  |   45|      0|#define talloc_get_size                 ta_get_size
  ------------------
  |  Branch (147:12): [True: 0, False: 0]
  ------------------
  148|      0|        if (errno != ERANGE) {
  ------------------
  |  Branch (148:13): [True: 0, False: 0]
  ------------------
  149|      0|            talloc_free(wd);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  150|      0|            return NULL;
  151|      0|        }
  152|      0|        wd = talloc_realloc(talloc_ctx, wd, char, talloc_get_size(wd) * 2);
  ------------------
  |  |   33|      0|#define talloc_realloc                  ta_xrealloc
  |  |  ------------------
  |  |  |  |  144|      0|    (type *)ta_xrealloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count))
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  153|      0|    }
  154|      0|    return wd;
  155|      0|}
mp_normalize_path:
  158|  80.1k|{
  159|  80.1k|    if (!path)
  ------------------
  |  Branch (159:9): [True: 0, False: 80.1k]
  ------------------
  160|      0|        return NULL;
  161|       |
  162|  80.1k|    if (mp_is_url(bstr0(path)))
  ------------------
  |  Branch (162:9): [True: 0, False: 80.1k]
  ------------------
  163|      0|        return talloc_strdup(talloc_ctx, path);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  164|       |
  165|  80.1k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  80.1k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  80.1k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  166|  80.1k|    if (!mp_path_is_absolute(bstr0(path))) {
  ------------------
  |  Branch (166:9): [True: 78.3k, False: 1.84k]
  ------------------
  167|  78.3k|        char *cwd = mp_getcwd(tmp);
  168|  78.3k|        if (!cwd) {
  ------------------
  |  Branch (168:13): [True: 0, False: 78.3k]
  ------------------
  169|      0|            talloc_free(tmp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  170|      0|            return NULL;
  171|      0|        }
  172|  78.3k|        path = mp_path_join(tmp, cwd, path);
  173|  78.3k|    }
  174|       |
  175|       |#if HAVE_DOS_PATHS
  176|       |    wchar_t *pathw = mp_from_utf8(tmp, path);
  177|       |    wchar_t *read = pathw, *write = pathw;
  178|       |    wchar_t prev = '\0';
  179|       |    // preserve leading double backslashes
  180|       |    if (read[0] == '\\' && read[1] == '\\') {
  181|       |        prev = '\\';
  182|       |        write += 2;
  183|       |        read += 2;
  184|       |    }
  185|       |    wchar_t curr;
  186|       |    while ((curr = *read)) {
  187|       |        if (curr == '/')
  188|       |            curr = '\\';
  189|       |        if (curr != '\\' || prev != '\\')
  190|       |            *write++ = curr;
  191|       |        prev = curr;
  192|       |        read++;
  193|       |    }
  194|       |    *write = '\0';
  195|       |    size_t max_size = wcslen(pathw) + 1;
  196|       |    wchar_t *pathc = talloc_array(tmp, wchar_t, max_size);
  197|       |    HRESULT hr = PathCchCanonicalizeEx(pathc, max_size, pathw, PATHCCH_ALLOW_LONG_PATHS);
  198|       |    char *ret = SUCCEEDED(hr) ? mp_to_utf8(talloc_ctx, pathc) : talloc_strdup(talloc_ctx, path);
  199|       |    talloc_free(tmp);
  200|       |    return ret;
  201|       |#else
  202|  80.1k|    char *result = talloc_strdup(tmp, "");
  ------------------
  |  |   50|  80.1k|#define talloc_strdup                   ta_xstrdup
  ------------------
  203|  80.1k|    const char *next;
  204|  80.1k|    const char *end = path + strlen(path);
  205|       |
  206|   520k|    for (const char *ptr = path; ptr < end; ptr = next + 1) {
  ------------------
  |  Branch (206:34): [True: 440k, False: 80.1k]
  ------------------
  207|   440k|        next = memchr(ptr, '/', end - ptr);
  208|   440k|        if (next == NULL)
  ------------------
  |  Branch (208:13): [True: 75.3k, False: 365k]
  ------------------
  209|  75.3k|            next = end;
  210|       |
  211|   440k|        switch (next - ptr) {
  ------------------
  |  Branch (211:17): [True: 293k, False: 146k]
  ------------------
  212|  99.7k|            case 0:
  ------------------
  |  Branch (212:13): [True: 99.7k, False: 340k]
  ------------------
  213|  99.7k|                continue;
  214|  37.2k|            case 1:
  ------------------
  |  Branch (214:13): [True: 37.2k, False: 403k]
  ------------------
  215|  37.2k|                if (ptr[0] == '.')
  ------------------
  |  Branch (215:21): [True: 87, False: 37.1k]
  ------------------
  216|     87|                    continue;
  217|  37.1k|                break;
  218|  37.1k|            case 2:
  ------------------
  |  Branch (218:13): [True: 9.63k, False: 430k]
  ------------------
  219|       |                // Normalizing symlink/.. results in a wrong path: if the
  220|       |                // current working directory is /tmp/foo, and it is a symlink to
  221|       |                // /usr/bin, mpv ../file.mkv opens /usr/file.mkv, so we can't
  222|       |                // normalize the path to /tmp/file.mkv. Resolve symlinks to fix
  223|       |                // this. Otherwise we don't use realpath so users can use
  224|       |                // symlinks e.g. to hide how media files are distributed over
  225|       |                // real storage and move them while still resuming playback as
  226|       |                // long as the symlinked path doesn't change.
  227|  9.63k|                if (ptr[0] == '.' && ptr[1] == '.') {
  ------------------
  |  Branch (227:21): [True: 317, False: 9.31k]
  |  Branch (227:38): [True: 11, False: 306]
  ------------------
  228|     11|                    char *tmp_result = realpath(path, NULL);
  229|     11|                    result = talloc_strdup(talloc_ctx, tmp_result);
  ------------------
  |  |   50|     11|#define talloc_strdup                   ta_xstrdup
  ------------------
  230|     11|                    free(tmp_result);
  231|     11|                    talloc_free(tmp);
  ------------------
  |  |   47|     11|#define talloc_free                     ta_free
  ------------------
  232|     11|                    return result;
  233|     11|                }
  234|   440k|        }
  235|       |
  236|   340k|        result = talloc_strdup_append_buffer(result, "/");
  ------------------
  |  |   58|   340k|#define talloc_strdup_append_buffer     ta_talloc_strdup_append_buffer
  ------------------
  237|   340k|        result = talloc_strndup_append_buffer(result, ptr, next - ptr);
  ------------------
  |  |   60|   340k|#define talloc_strndup_append_buffer    ta_talloc_strndup_append_buffer
  ------------------
  238|   340k|    }
  239|       |
  240|  80.1k|    result = talloc_steal(talloc_ctx, result);
  ------------------
  |  |   38|  80.1k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  80.1k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  241|  80.1k|    talloc_free(tmp);
  ------------------
  |  |   47|  80.1k|#define talloc_free                     ta_free
  ------------------
  242|  80.1k|    return result;
  243|  80.1k|#endif
  244|  80.1k|}
mp_is_url:
  260|   831k|{
  261|   831k|    int proto = bstr_find0(path, "://");
  262|   831k|    if (proto < 1)
  ------------------
  |  Branch (262:9): [True: 195k, False: 635k]
  ------------------
  263|   195k|        return false;
  264|       |    // Per RFC3986, the first character of the protocol must be alphabetic.
  265|       |    // The rest must be alphanumeric plus -, + and .
  266|  4.40M|    for (int i = 0; i < proto; i++) {
  ------------------
  |  Branch (266:21): [True: 3.81M, False: 589k]
  ------------------
  267|  3.81M|        unsigned char c = path.start[i];
  268|  3.81M|        if ((i == 0 && !mp_isalpha(c)) ||
  ------------------
  |  Branch (268:14): [True: 635k, False: 3.17M]
  |  Branch (268:24): [True: 15.6k, False: 620k]
  ------------------
  269|  3.81M|            (!mp_isalnum(c) && c != '.' && c != '-' && c != '+'))
  ------------------
  |  Branch (269:14): [True: 35.6k, False: 3.76M]
  |  Branch (269:32): [True: 35.0k, False: 568]
  |  Branch (269:44): [True: 33.5k, False: 1.50k]
  |  Branch (269:56): [True: 30.6k, False: 2.86k]
  ------------------
  270|  46.3k|        {
  271|  46.3k|            return false;
  272|  46.3k|        }
  273|  3.81M|    }
  274|   589k|    return true;
  275|   635k|}
mp_split_proto:
  280|   104k|{
  281|   104k|    if (!mp_is_url(path))
  ------------------
  |  Branch (281:9): [True: 80.8k, False: 23.2k]
  ------------------
  282|  80.8k|        return (bstr){0};
  283|  23.2k|    bstr r;
  284|  23.2k|    bstr_split_tok(path, "://", &r, out_url ? out_url : &(bstr){0});
  ------------------
  |  Branch (284:37): [True: 15.1k, False: 8.05k]
  ------------------
  285|  23.2k|    return r;
  286|   104k|}

mp_rendezvous:
   33|  5.56k|{
   34|  5.56k|    struct waiter wait = { .tag = tag, .value = &value };
   35|  5.56k|    mp_mutex_lock(&lock);
  ------------------
  |  |  131|  5.56k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   36|  5.56k|    struct waiter **prev = &waiters;
   37|  5.56k|    while (*prev) {
  ------------------
  |  Branch (37:12): [True: 2.78k, False: 2.78k]
  ------------------
   38|  2.78k|        if ((*prev)->tag == tag) {
  ------------------
  |  Branch (38:13): [True: 2.78k, False: 0]
  ------------------
   39|  2.78k|            intptr_t tmp = *(*prev)->value;
   40|  2.78k|            *(*prev)->value = value;
   41|  2.78k|            value = tmp;
   42|  2.78k|            (*prev)->value = NULL; // signals completion
   43|  2.78k|            *prev = (*prev)->next; // unlink
   44|  2.78k|            mp_cond_broadcast(&wakeup);
   45|  2.78k|            goto done;
   46|  2.78k|        }
   47|      0|        prev = &(*prev)->next;
   48|      0|    }
   49|  2.78k|    *prev = &wait;
   50|  5.56k|    while (wait.value)
  ------------------
  |  Branch (50:12): [True: 2.78k, False: 2.78k]
  ------------------
   51|  2.78k|        mp_cond_wait(&wakeup, &lock);
   52|  5.56k|done:
   53|  5.56k|    mp_mutex_unlock(&lock);
  ------------------
  |  |  133|  5.56k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   54|  5.56k|    return value;
   55|  2.78k|}

mp_thread_pool_create:
  155|  5.81k|{
  156|  5.81k|    mp_assert(min_threads >= 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  157|  5.81k|    mp_assert(init_threads <= min_threads);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  158|  5.81k|    mp_assert(max_threads > 0 && max_threads >= min_threads);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  159|       |
  160|  5.81k|    struct mp_thread_pool *pool = talloc_zero(ta_parent, struct mp_thread_pool);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  161|  5.81k|    talloc_set_destructor(pool, thread_pool_dtor);
  ------------------
  |  |   41|  5.81k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  162|       |
  163|  5.81k|    mp_mutex_init(&pool->lock);
  164|  5.81k|    mp_cond_init(&pool->wakeup);
  165|       |
  166|  5.81k|    pool->min_threads = min_threads;
  167|  5.81k|    pool->max_threads = max_threads;
  168|       |
  169|  5.81k|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  170|  5.81k|    for (int n = 0; n < init_threads; n++)
  ------------------
  |  Branch (170:21): [True: 0, False: 5.81k]
  ------------------
  171|      0|        add_thread(pool);
  172|  5.81k|    bool ok = pool->num_threads >= init_threads;
  173|  5.81k|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  174|       |
  175|  5.81k|    if (!ok)
  ------------------
  |  Branch (175:9): [True: 0, False: 5.81k]
  ------------------
  176|      0|        TA_FREEP(&pool);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  177|       |
  178|  5.81k|    return pool;
  179|  5.81k|}
mp_thread_pool_queue:
  215|  4.53k|{
  216|  4.53k|    return thread_pool_add(pool, fn, fn_ctx, true);
  217|  4.53k|}
thread_pool.c:thread_pool_dtor:
  116|  5.81k|{
  117|  5.81k|    struct mp_thread_pool *pool = ctx;
  118|       |
  119|       |
  120|  5.81k|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  121|       |
  122|  5.81k|    pool->terminate = true;
  123|  5.81k|    mp_cond_broadcast(&pool->wakeup);
  124|       |
  125|  5.81k|    mp_thread *threads = pool->threads;
  126|  5.81k|    int num_threads = pool->num_threads;
  127|       |
  128|  5.81k|    pool->threads = NULL;
  129|  5.81k|    pool->num_threads = 0;
  130|       |
  131|  5.81k|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  132|       |
  133|  10.1k|    for (int n = 0; n < num_threads; n++)
  ------------------
  |  Branch (133:21): [True: 4.31k, False: 5.81k]
  ------------------
  134|  4.31k|        mp_thread_join(threads[n]);
  ------------------
  |  |  212|  4.31k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  135|       |
  136|  5.81k|    mp_assert(pool->num_work == 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  137|  5.81k|    mp_assert(pool->num_threads == 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  138|  5.81k|    mp_cond_destroy(&pool->wakeup);
  139|  5.81k|    mp_mutex_destroy(&pool->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  140|  5.81k|}
thread_pool.c:add_thread:
  143|  4.31k|{
  144|  4.31k|    mp_thread thread;
  145|       |
  146|  4.31k|    if (mp_thread_create(&thread, worker_thread, pool) != 0)
  ------------------
  |  |  211|  4.31k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  ------------------
  |  Branch (146:9): [True: 0, False: 4.31k]
  ------------------
  147|      0|        return false;
  148|       |
  149|  4.31k|    MP_TARRAY_APPEND(pool, pool->threads, pool->num_threads, thread);
  ------------------
  |  |  105|  4.31k|    do {                                            \
  |  |  106|  4.31k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.31k|    do {                                            \
  |  |  |  |   97|  4.31k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.31k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.31k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.31k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.31k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.31k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.31k|    do {                                                        \
  |  |  |  |  |  |   89|  4.31k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.31k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.31k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.31k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.31k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.31k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.31k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.31k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.31k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.31k|        (idxvar)++;                                 \
  |  |  109|  4.31k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  150|  4.31k|    return true;
  151|  4.31k|}
thread_pool.c:worker_thread:
   52|  4.31k|{
   53|  4.31k|    struct mp_thread_pool *pool = arg;
   54|       |
   55|  4.31k|    mp_thread_set_name("worker");
   56|       |
   57|  4.31k|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  4.31k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   58|       |
   59|  4.31k|    int64_t destroy_deadline = 0;
   60|  4.31k|    bool got_timeout = false;
   61|  13.3k|    while (1) {
  ------------------
  |  Branch (61:12): [Folded - Ignored]
  ------------------
   62|  13.3k|        struct work work = {0};
   63|  13.3k|        if (pool->num_work > 0) {
  ------------------
  |  Branch (63:13): [True: 4.53k, False: 8.85k]
  ------------------
   64|  4.53k|            work = pool->work[pool->num_work - 1];
   65|  4.53k|            pool->num_work -= 1;
   66|  4.53k|        }
   67|       |
   68|  13.3k|        if (!work.fn) {
  ------------------
  |  Branch (68:13): [True: 8.85k, False: 4.53k]
  ------------------
   69|  8.85k|            if (got_timeout || pool->terminate)
  ------------------
  |  Branch (69:17): [True: 0, False: 8.85k]
  |  Branch (69:32): [True: 4.31k, False: 4.53k]
  ------------------
   70|  4.31k|                break;
   71|       |
   72|  4.53k|            if (pool->num_threads > pool->min_threads) {
  ------------------
  |  Branch (72:17): [True: 0, False: 4.53k]
  ------------------
   73|      0|                if (!destroy_deadline)
  ------------------
  |  Branch (73:21): [True: 0, False: 0]
  ------------------
   74|      0|                    destroy_deadline = mp_time_ns() + MP_TIME_S_TO_NS(DESTROY_TIMEOUT);
  ------------------
  |  |   59|      0|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
   75|      0|                if (mp_cond_timedwait_until(&pool->wakeup, &pool->lock, destroy_deadline))
  ------------------
  |  Branch (75:21): [True: 0, False: 0]
  ------------------
   76|      0|                    got_timeout = pool->num_threads > pool->min_threads;
   77|  4.53k|            } else {
   78|  4.53k|                mp_cond_wait(&pool->wakeup, &pool->lock);
   79|  4.53k|            }
   80|  4.53k|            continue;
   81|  8.85k|        }
   82|       |
   83|  4.53k|        pool->busy_threads += 1;
   84|  4.53k|        mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  4.53k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   85|       |
   86|  4.53k|        work.fn(work.fn_ctx);
   87|       |
   88|  4.53k|        mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  4.53k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   89|  4.53k|        pool->busy_threads -= 1;
   90|       |
   91|  4.53k|        destroy_deadline = 0;
   92|  4.53k|        got_timeout = false;
   93|  4.53k|    }
   94|       |
   95|       |    // If no termination signal was given, it must mean we died because of a
   96|       |    // timeout, and nobody is waiting for us. We have to remove ourselves.
   97|  4.31k|    if (!pool->terminate) {
  ------------------
  |  Branch (97:9): [True: 0, False: 4.31k]
  ------------------
   98|      0|        for (int n = 0; n < pool->num_threads; n++) {
  ------------------
  |  Branch (98:25): [True: 0, False: 0]
  ------------------
   99|      0|            if (mp_thread_id_equal(mp_thread_get_id(pool->threads[n]),
  ------------------
  |  |  215|      0|#define mp_thread_id_equal(a, b)  ((a) == (b))
  |  |  ------------------
  |  |  |  Branch (215:35): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  100|      0|                                   mp_thread_current_id()))
  101|      0|            {
  102|      0|                mp_thread_detach(pool->threads[n]);
  ------------------
  |  |  213|      0|#define mp_thread_detach          pthread_detach
  ------------------
  103|      0|                MP_TARRAY_REMOVE_AT(pool->threads, pool->num_threads, n);
  ------------------
  |  |  143|      0|    do {                                            \
  |  |  144|      0|        size_t at_ = (at);                          \
  |  |  145|      0|        assert(at_ <= (idxvar));                    \
  |  |  146|      0|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|      0|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|      0|        (idxvar)--;                                 \
  |  |  149|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  104|      0|                mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  105|      0|                MP_THREAD_RETURN();
  ------------------
  |  |  209|      0|#define MP_THREAD_RETURN() return NULL
  ------------------
  106|      0|            }
  107|      0|        }
  108|      0|        MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
  109|      0|    }
  110|       |
  111|  4.31k|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  4.31k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  112|  4.31k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  4.31k|#define MP_THREAD_RETURN() return NULL
  ------------------
  113|  4.31k|}
thread_pool.c:thread_pool_add:
  183|  4.53k|{
  184|  4.53k|    bool ok = true;
  185|       |
  186|  4.53k|    mp_assert(fn);
  ------------------
  |  |   41|  4.53k|#define mp_assert assert
  ------------------
  187|       |
  188|  4.53k|    mp_mutex_lock(&pool->lock);
  ------------------
  |  |  131|  4.53k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  189|  4.53k|    struct work work = {fn, fn_ctx};
  190|       |
  191|       |    // If there are not enough threads to process all at once, but we can
  192|       |    // create a new thread, then do so. If work is queued quickly, it can
  193|       |    // happen that not all available threads have picked up work yet (up to
  194|       |    // num_threads - busy_threads threads), which has to be accounted for.
  195|  4.53k|    if (pool->busy_threads + pool->num_work + 1 > pool->num_threads &&
  ------------------
  |  Branch (195:9): [True: 4.31k, False: 219]
  ------------------
  196|  4.53k|        pool->num_threads < pool->max_threads)
  ------------------
  |  Branch (196:9): [True: 4.31k, False: 0]
  ------------------
  197|  4.31k|    {
  198|  4.31k|        if (!add_thread(pool)) {
  ------------------
  |  Branch (198:13): [True: 0, False: 4.31k]
  ------------------
  199|       |            // If we can queue it, it'll get done as long as there is 1 thread.
  200|      0|            ok = allow_queue && pool->num_threads > 0;
  ------------------
  |  Branch (200:18): [True: 0, False: 0]
  |  Branch (200:33): [True: 0, False: 0]
  ------------------
  201|      0|        }
  202|  4.31k|    }
  203|       |
  204|  4.53k|    if (ok) {
  ------------------
  |  Branch (204:9): [True: 4.53k, False: 0]
  ------------------
  205|  4.53k|        MP_TARRAY_INSERT_AT(pool, pool->work, pool->num_work, 0, work);
  ------------------
  |  |  115|  4.53k|    do {                                            \
  |  |  116|  4.53k|        size_t at_ = (at);                          \
  |  |  117|  4.53k|        assert(at_ <= (idxvar));                    \
  |  |  118|  4.53k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.53k|    do {                                            \
  |  |  |  |   97|  4.53k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.53k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.53k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.53k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.31k, False: 219]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.53k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.31k|    do {                                                        \
  |  |  |  |  |  |   89|  4.31k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.31k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.31k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.31k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.31k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.31k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.31k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.53k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|  4.53k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|  4.53k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|  4.53k|        (idxvar)++;                                 \
  |  |  122|  4.53k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|  4.53k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  206|  4.53k|        mp_cond_signal(&pool->wakeup);
  207|  4.53k|    }
  208|       |
  209|  4.53k|    mp_mutex_unlock(&pool->lock);
  ------------------
  |  |  133|  4.53k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  210|  4.53k|    return ok;
  211|  4.53k|}

mp_waiter_wait:
   36|  16.1k|{
   37|  16.1k|    mp_mutex_lock(&waiter->lock);
  ------------------
  |  |  131|  16.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   38|  16.1k|    while (!waiter->done)
  ------------------
  |  Branch (38:12): [True: 0, False: 16.1k]
  ------------------
   39|      0|        mp_cond_wait(&waiter->wakeup, &waiter->lock);
   40|  16.1k|    mp_mutex_unlock(&waiter->lock);
  ------------------
  |  |  133|  16.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   41|       |
   42|  16.1k|    uintptr_t ret = waiter->value;
   43|       |
   44|       |    // We document that after mp_waiter_wait() the waiter object becomes
   45|       |    // invalid. (It strictly returns only after mp_waiter_wakeup() has returned,
   46|       |    // and the object is "single-shot".) So destroy it here.
   47|       |
   48|       |    // Normally, we expect that the system uses futexes, in which case the
   49|       |    // following functions will do nearly nothing. This is true for Windows
   50|       |    // and Linux. But some lesser OSes still might allocate kernel objects
   51|       |    // when initializing mutexes, so destroy them here.
   52|  16.1k|    mp_mutex_destroy(&waiter->lock);
  ------------------
  |  |  130|  16.1k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
   53|  16.1k|    mp_cond_destroy(&waiter->wakeup);
   54|       |
   55|  16.1k|    memset(waiter, 0xCA, sizeof(*waiter)); // for debugging
   56|       |
   57|  16.1k|    return ret;
   58|  16.1k|}
mp_waiter_wakeup:
   61|  16.1k|{
   62|  16.1k|    mp_mutex_lock(&waiter->lock);
  ------------------
  |  |  131|  16.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   63|  16.1k|    mp_assert(!waiter->done);
  ------------------
  |  |   41|  16.1k|#define mp_assert assert
  ------------------
   64|  16.1k|    waiter->done = true;
   65|  16.1k|    waiter->value = value;
   66|  16.1k|    mp_cond_signal(&waiter->wakeup);
   67|  16.1k|    mp_mutex_unlock(&waiter->lock);
  ------------------
  |  |  133|  16.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   68|  16.1k|}
mp_waiter_poll:
   71|  9.18k|{
   72|  9.18k|    mp_mutex_lock(&waiter->lock);
  ------------------
  |  |  131|  9.18k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   73|  9.18k|    bool r = waiter->done;
   74|  9.18k|    mp_mutex_unlock(&waiter->lock);
  ------------------
  |  |  133|  9.18k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   75|  9.18k|    return r;
   76|  9.18k|}
mp_cancel_new:
  124|  36.9k|{
  125|  36.9k|    struct mp_cancel *c = talloc_ptrtype(talloc_ctx, c);
  ------------------
  |  |   34|  36.9k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  36.9k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  36.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  126|  36.9k|    talloc_set_destructor(c, cancel_destroy);
  ------------------
  |  |   41|  36.9k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  127|  36.9k|    *c = (struct mp_cancel){
  128|  36.9k|        .triggered = false,
  129|  36.9k|        .wakeup_pipe = {-1, -1},
  130|  36.9k|    };
  131|  36.9k|    mp_mutex_init(&c->lock);
  132|  36.9k|    mp_cond_init(&c->wakeup);
  133|  36.9k|    return c;
  134|  36.9k|}
mp_cancel_trigger:
  158|   109k|{
  159|   109k|    mp_mutex_lock(&c->lock);
  ------------------
  |  |  131|   109k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  160|   109k|    trigger_locked(c);
  161|   109k|    mp_mutex_unlock(&c->lock);
  ------------------
  |  |  133|   109k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  162|   109k|}
mp_cancel_reset:
  165|  94.7k|{
  166|  94.7k|    mp_mutex_lock(&c->lock);
  ------------------
  |  |  131|  94.7k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  167|       |
  168|  94.7k|    atomic_store(&c->triggered, false);
  169|       |
  170|  94.7k|    if (c->wakeup_pipe[0] >= 0) {
  ------------------
  |  Branch (170:9): [True: 0, False: 94.7k]
  ------------------
  171|       |        // Flush it fully.
  172|      0|        while (1) {
  ------------------
  |  Branch (172:16): [Folded - Ignored]
  ------------------
  173|      0|            int r = read(c->wakeup_pipe[0], &(char[256]){0}, 256);
  174|      0|            if (r <= 0 && !(r < 0 && errno == EINTR))
  ------------------
  |  Branch (174:17): [True: 0, False: 0]
  |  Branch (174:29): [True: 0, False: 0]
  |  Branch (174:38): [True: 0, False: 0]
  ------------------
  175|      0|                break;
  176|      0|        }
  177|      0|    }
  178|       |
  179|       |#ifdef _WIN32
  180|       |    if (c->win32_event)
  181|       |        ResetEvent(c->win32_event);
  182|       |#endif
  183|       |
  184|  94.7k|    mp_mutex_unlock(&c->lock);
  ------------------
  |  |  133|  94.7k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  185|  94.7k|}
mp_cancel_test:
  188|  6.26M|{
  189|  6.26M|    return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
  ------------------
  |  Branch (189:12): [True: 6.20M, False: 56.1k]
  ------------------
  190|  6.26M|}
mp_cancel_set_parent:
  223|  73.2k|{
  224|       |    // We can access c->parent without synchronization, because:
  225|       |    //  - concurrent mp_cancel_set_parent() calls to slave are not allowed
  226|       |    //  - slave->parent needs to stay valid as long as the slave exists
  227|  73.2k|    if (slave->parent == parent)
  ------------------
  |  Branch (227:9): [True: 5.86k, False: 67.3k]
  ------------------
  228|  5.86k|        return;
  229|  67.3k|    if (slave->parent) {
  ------------------
  |  Branch (229:9): [True: 36.2k, False: 31.1k]
  ------------------
  230|  36.2k|        mp_mutex_lock(&slave->parent->lock);
  ------------------
  |  |  131|  36.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  231|  36.2k|        LL_REMOVE(siblings, &slave->parent->slaves, slave);
  ------------------
  |  |   78|  36.2k|#define LL_REMOVE(field, list, item) do {                               \
  |  |   79|  36.2k|    if ((item)->field.prev) {                                           \
  |  |  ------------------
  |  |  |  Branch (79:9): [True: 109, False: 36.1k]
  |  |  ------------------
  |  |   80|    109|        (item)->field.prev->field.next = (item)->field.next;            \
  |  |   81|  36.1k|    } else {                                                            \
  |  |   82|  36.1k|        (list)->head = (item)->field.next;                              \
  |  |   83|  36.1k|    }                                                                   \
  |  |   84|  36.2k|    if ((item)->field.next) {                                           \
  |  |  ------------------
  |  |  |  Branch (84:9): [True: 20.5k, False: 15.6k]
  |  |  ------------------
  |  |   85|  20.5k|        (item)->field.next->field.prev = (item)->field.prev;            \
  |  |   86|  20.5k|    } else {                                                            \
  |  |   87|  15.6k|        (list)->tail = (item)->field.prev;                              \
  |  |   88|  15.6k|    }                                                                   \
  |  |   89|  36.2k|} while (0)
  |  |  ------------------
  |  |  |  Branch (89:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  232|  36.2k|        mp_mutex_unlock(&slave->parent->lock);
  ------------------
  |  |  133|  36.2k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  233|  36.2k|    }
  234|  67.3k|    slave->parent = parent;
  235|  67.3k|    if (slave->parent) {
  ------------------
  |  Branch (235:9): [True: 36.2k, False: 31.1k]
  ------------------
  236|  36.2k|        mp_mutex_lock(&slave->parent->lock);
  ------------------
  |  |  131|  36.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  237|  36.2k|        LL_APPEND(siblings, &slave->parent->slaves, slave);
  ------------------
  |  |   44|  36.2k|#define LL_APPEND(field, list, item)  do {                              \
  |  |   45|  36.2k|    (item)->field.prev = (list)->tail;                                  \
  |  |   46|  36.2k|    (item)->field.next = NULL;                                          \
  |  |   47|  36.2k|    LL_RELINK_(field, list, item)                                       \
  |  |  ------------------
  |  |  |  |   98|  36.2k|    if ((item)->field.prev) {                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:9): [True: 20.6k, False: 15.5k]
  |  |  |  |  ------------------
  |  |  |  |   99|  20.6k|        (item)->field.prev->field.next = (item);                        \
  |  |  |  |  100|  20.6k|    } else {                                                            \
  |  |  |  |  101|  15.5k|        (list)->head = (item);                                          \
  |  |  |  |  102|  15.5k|    }                                                                   \
  |  |  |  |  103|  36.2k|    if ((item)->field.next) {                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:9): [True: 0, False: 36.2k]
  |  |  |  |  ------------------
  |  |  |  |  104|      0|        (item)->field.next->field.prev = (item);                        \
  |  |  |  |  105|  36.2k|    } else {                                                            \
  |  |  |  |  106|  36.2k|        (list)->tail = (item);                                          \
  |  |  |  |  107|  36.2k|    }
  |  |  ------------------
  |  |   48|  36.2k|} while (0)
  |  |  ------------------
  |  |  |  Branch (48:10): [Folded - Ignored]
  |  |  ------------------
  ------------------
  238|  36.2k|        retrigger_locked(slave->parent);
  239|  36.2k|        mp_mutex_unlock(&slave->parent->lock);
  ------------------
  |  |  133|  36.2k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  240|  36.2k|    }
  241|  67.3k|}
thread_tools.c:cancel_destroy:
  102|  36.9k|{
  103|  36.9k|    struct mp_cancel *c = p;
  104|       |
  105|  36.9k|    mp_assert(!c->slaves.head); // API user error
  ------------------
  |  |   41|  36.9k|#define mp_assert assert
  ------------------
  106|       |
  107|  36.9k|    mp_cancel_set_parent(c, NULL);
  108|       |
  109|  36.9k|    if (c->wakeup_pipe[0] >= 0) {
  ------------------
  |  Branch (109:9): [True: 0, False: 36.9k]
  ------------------
  110|      0|        close(c->wakeup_pipe[0]);
  111|      0|        close(c->wakeup_pipe[1]);
  112|      0|    }
  113|       |
  114|       |#ifdef _WIN32
  115|       |    if (c->win32_event)
  116|       |        CloseHandle(c->win32_event);
  117|       |#endif
  118|       |
  119|  36.9k|    mp_mutex_destroy(&c->lock);
  ------------------
  |  |  130|  36.9k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  120|  36.9k|    mp_cond_destroy(&c->wakeup);
  121|  36.9k|}
thread_tools.c:trigger_locked:
  137|   109k|{
  138|   109k|    atomic_store(&c->triggered, true);
  139|       |
  140|   109k|    mp_cond_broadcast(&c->wakeup); // condition bound to c->triggered
  141|       |
  142|   109k|    if (c->cb)
  ------------------
  |  Branch (142:9): [True: 0, False: 109k]
  ------------------
  143|      0|        c->cb(c->cb_ctx);
  144|       |
  145|   109k|    for (struct mp_cancel *sub = c->slaves.head; sub; sub = sub->siblings.next)
  ------------------
  |  Branch (145:50): [True: 0, False: 109k]
  ------------------
  146|      0|        mp_cancel_trigger(sub);
  147|       |
  148|   109k|    if (c->wakeup_pipe[1] >= 0)
  ------------------
  |  Branch (148:9): [True: 0, False: 109k]
  ------------------
  149|      0|        (void)write(c->wakeup_pipe[1], &(char){0}, 1);
  150|       |
  151|       |#ifdef _WIN32
  152|       |    if (c->win32_event)
  153|       |        SetEvent(c->win32_event);
  154|       |#endif
  155|   109k|}
thread_tools.c:retrigger_locked:
  208|  36.2k|{
  209|  36.2k|    if (mp_cancel_test(c))
  ------------------
  |  Branch (209:9): [True: 0, False: 36.2k]
  ------------------
  210|      0|        trigger_locked(c);
  211|  36.2k|}

m_config_shadow_get_next_opt:
  187|  4.34M|{
  188|  4.34M|    return iter_next(shadow, 0, shadow->num_groups, p_id);
  189|  4.34M|}
m_config_shadow_get_opt:
  212|  4.33M|{
  213|  4.33M|    int group_index, opt_index;
  214|  4.33M|    get_opt_from_id(shadow, id, &group_index, &opt_index);
  215|       |
  216|  4.33M|    return &shadow->groups[group_index].group->opts[opt_index];
  217|  4.33M|}
m_config_shadow_get_opt_name:
  221|  4.33M|{
  222|  4.33M|    int group_index, opt_index;
  223|  4.33M|    get_opt_from_id(shadow, id, &group_index, &opt_index);
  224|       |
  225|  4.33M|    struct m_config_group *g = &shadow->groups[group_index];
  226|  4.33M|    return concat_name_buf(buf, buf_size, g->prefix,
  227|  4.33M|                           g->group->opts[opt_index].name);
  228|  4.33M|}
m_config_shadow_get_alias_from_opt:
  232|   267k|{
  233|   267k|    int group_index, opt_index;
  234|   267k|    get_opt_from_id(shadow, id, &group_index, &opt_index);
  235|       |
  236|   267k|    struct m_config_group *g = &shadow->groups[group_index];
  237|   267k|    const struct m_option *opt = &shadow->groups[group_index].group->opts[opt_index];
  238|   267k|    if (opt->alias_use_prefix)
  ------------------
  |  Branch (238:9): [True: 69.7k, False: 197k]
  ------------------
  239|  69.7k|        return concat_name_buf(buf, buf_size, g->prefix, (const char *)opt->priv);
  240|   197k|    return (const char *)opt->priv;
  241|   267k|}
m_config_cache_get_opt_data:
  265|  4.33M|{
  266|  4.33M|    int group_index, opt_index;
  267|  4.33M|    get_opt_from_id(cache->shadow, id, &group_index, &opt_index);
  268|       |
  269|  4.33M|    mp_assert(group_index >= cache->internal->group_start &&
  ------------------
  |  |   41|  4.33M|#define mp_assert assert
  ------------------
  270|  4.33M|           group_index < cache->internal->group_end);
  271|       |
  272|  4.33M|    struct m_group_data *gd = m_config_gdata(cache->internal->data, group_index);
  273|  4.33M|    const struct m_option *opt =
  274|  4.33M|        &cache->shadow->groups[group_index].group->opts[opt_index];
  275|       |
  276|  4.33M|    return gd && opt->offset >= 0 ? gd->udata + opt->offset : NULL;
  ------------------
  |  Branch (276:12): [True: 4.33M, False: 0]
  |  Branch (276:18): [True: 4.04M, False: 290k]
  ------------------
  277|  4.33M|}
m_config_cache_get_option_change_mask:
  293|  87.1k|{
  294|  87.1k|    struct m_config_shadow *shadow = cache->shadow;
  295|  87.1k|    int group_index, opt_index;
  296|  87.1k|    get_opt_from_id(shadow, id, &group_index, &opt_index);
  297|       |
  298|  87.1k|    mp_assert(group_index >= cache->internal->group_start &&
  ------------------
  |  |   41|  87.1k|#define mp_assert assert
  ------------------
  299|  87.1k|           group_index < cache->internal->group_end);
  300|       |
  301|  87.1k|    return get_opt_change_mask(cache->shadow, group_index,
  302|  87.1k|                               cache->internal->data->group_index,
  303|  87.1k|                               &shadow->groups[group_index].group->opts[opt_index]);
  304|  87.1k|}
m_config_shadow_new:
  443|  5.81k|{
  444|  5.81k|    struct m_config_shadow *shadow = talloc_zero(NULL, struct m_config_shadow);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  445|  5.81k|    talloc_set_destructor(shadow, shadow_destroy);
  ------------------
  |  |   41|  5.81k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  446|  5.81k|    mp_mutex_init(&shadow->lock);
  447|       |
  448|  5.81k|    add_sub_group(shadow, NULL, -1, -1, root);
  449|       |
  450|  5.81k|    if (!root->size)
  ------------------
  |  Branch (450:9): [True: 0, False: 5.81k]
  ------------------
  451|      0|        return shadow;
  452|       |
  453|  5.81k|    shadow->data = allocate_option_data(shadow, shadow, 0, NULL);
  454|       |
  455|  5.81k|    return shadow;
  456|  5.81k|}
m_config_cache_from_shadow:
  561|   559k|{
  562|   559k|    int group_index = -1;
  563|       |
  564|  15.6M|    for (int n = 0; n < shadow->num_groups; n++) {
  ------------------
  |  Branch (564:21): [True: 15.6M, False: 0]
  ------------------
  565|  15.6M|        if (shadow->groups[n].group == group) {
  ------------------
  |  Branch (565:13): [True: 559k, False: 15.1M]
  ------------------
  566|   559k|            group_index = n;
  567|   559k|            break;
  568|   559k|        }
  569|  15.6M|    }
  570|       |
  571|   559k|    mp_assert(group_index >= 0); // invalid group (or not in option tree)
  ------------------
  |  |   41|   559k|#define mp_assert assert
  ------------------
  572|       |
  573|   559k|    struct cache_alloc {
  574|   559k|        struct m_config_cache a;
  575|   559k|        struct config_cache b;
  576|   559k|    };
  577|   559k|    struct cache_alloc *alloc = talloc_zero(ta_parent, struct cache_alloc);
  ------------------
  |  |   27|   559k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   559k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   559k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  578|   559k|    mp_assert((void *)&alloc->a == (void *)alloc);
  ------------------
  |  |   41|   559k|#define mp_assert assert
  ------------------
  579|   559k|    struct m_config_cache *cache = &alloc->a;
  580|   559k|    talloc_set_destructor(cache, cache_destroy);
  ------------------
  |  |   41|   559k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  581|   559k|    cache->internal = &alloc->b;
  582|   559k|    cache->shadow = shadow;
  583|       |
  584|   559k|    struct config_cache *in = cache->internal;
  585|   559k|    in->shadow = shadow;
  586|   559k|    in->src = shadow->data;
  587|       |
  588|   559k|    mp_mutex_lock(&shadow->lock);
  ------------------
  |  |  131|   559k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  589|   559k|    in->data = allocate_option_data(cache, shadow, group_index, in->src);
  590|   559k|    mp_mutex_unlock(&shadow->lock);
  ------------------
  |  |  133|   559k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  591|       |
  592|   559k|    cache->opts = in->data->gdata[0].udata;
  593|       |
  594|   559k|    in->group_start = in->data->group_index;
  595|   559k|    in->group_end = in->group_start + in->data->num_gdata;
  596|   559k|    mp_assert(shadow->groups[in->group_start].group_count == in->data->num_gdata);
  ------------------
  |  |   41|   559k|#define mp_assert assert
  ------------------
  597|       |
  598|   559k|    in->upd_group = -1;
  599|       |
  600|   559k|    return cache;
  601|   559k|}
m_config_cache_alloc:
  606|   553k|{
  607|   553k|    return m_config_cache_from_shadow(ta_parent, global->config, group);
  608|   553k|}
m_config_cache_update:
  720|  6.25M|{
  721|  6.25M|    struct config_cache *in = cache->internal;
  722|  6.25M|    struct m_config_shadow *shadow = in->shadow;
  723|       |
  724|  6.25M|    if (!cache_check_update(cache))
  ------------------
  |  Branch (724:9): [True: 6.20M, False: 50.8k]
  ------------------
  725|  6.20M|        return false;
  726|       |
  727|  50.8k|    mp_mutex_lock(&shadow->lock);
  ------------------
  |  |  131|  50.8k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  728|  50.8k|    bool res = false;
  729|  68.6k|    while (1) {
  ------------------
  |  Branch (729:12): [Folded - Ignored]
  ------------------
  730|  68.6k|        void *p;
  731|  68.6k|        update_next_option(cache, &p);
  732|  68.6k|        if (!p)
  ------------------
  |  Branch (732:13): [True: 51.2k, False: 17.4k]
  ------------------
  733|  51.2k|            break;
  734|  17.4k|        res = true;
  735|  17.4k|    }
  736|  50.8k|    mp_mutex_unlock(&shadow->lock);
  ------------------
  |  |  133|  50.8k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  737|  50.8k|    return res;
  738|  6.25M|}
m_config_cache_write_opt:
  782|   185k|{
  783|   185k|    struct config_cache *in = cache->internal;
  784|   185k|    struct m_config_shadow *shadow = in->shadow;
  785|       |
  786|   185k|    int group_idx = -1;
  787|   185k|    int opt_idx = -1;
  788|   185k|    find_opt(shadow, in->data, ptr, &group_idx, &opt_idx);
  789|       |
  790|       |    // ptr was not in cache->opts, or no option declaration matching it.
  791|   185k|    mp_assert(group_idx >= 0);
  ------------------
  |  |   41|   185k|#define mp_assert assert
  ------------------
  792|       |
  793|   185k|    struct m_config_group *g = &shadow->groups[group_idx];
  794|   185k|    const struct m_option *opt = &g->group->opts[opt_idx];
  795|       |
  796|   185k|    mp_mutex_lock(&shadow->lock);
  ------------------
  |  |  131|   185k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  797|       |
  798|   185k|    struct m_group_data *gdst = m_config_gdata(in->data, group_idx);
  799|   185k|    struct m_group_data *gsrc = m_config_gdata(in->src, group_idx);
  800|   185k|    mp_assert(gdst && gsrc);
  ------------------
  |  |   41|   185k|#define mp_assert assert
  ------------------
  801|       |
  802|   185k|    bool changed = !m_option_equal(opt, gsrc->udata + opt->offset, ptr) ||
  ------------------
  |  Branch (802:20): [True: 87.1k, False: 98.7k]
  ------------------
  803|   185k|                   opt->force_update;
  ------------------
  |  Branch (803:20): [True: 0, False: 98.7k]
  ------------------
  804|   185k|    if (changed) {
  ------------------
  |  Branch (804:9): [True: 87.1k, False: 98.7k]
  ------------------
  805|  87.1k|        m_option_copy(opt, gsrc->udata + opt->offset, ptr);
  806|       |
  807|  87.1k|        gsrc->ts = atomic_fetch_add(&shadow->ts, 1) + 1;
  808|       |
  809|  87.1k|        for (int n = 0; n < shadow->num_listeners; n++) {
  ------------------
  |  Branch (809:25): [True: 0, False: 87.1k]
  ------------------
  810|      0|            struct config_cache *listener = shadow->listeners[n];
  811|      0|            if (listener->wakeup_cb && m_config_gdata(listener->data, group_idx))
  ------------------
  |  Branch (811:17): [True: 0, False: 0]
  |  Branch (811:40): [True: 0, False: 0]
  ------------------
  812|      0|                listener->wakeup_cb(listener->wakeup_cb_ctx);
  813|      0|        }
  814|  87.1k|    }
  815|       |
  816|   185k|    if (opt->force_update)
  ------------------
  |  Branch (816:9): [True: 0, False: 185k]
  ------------------
  817|      0|        append_force_update(cache, gsrc, opt->name);
  818|       |
  819|   185k|    mp_mutex_unlock(&shadow->lock);
  ------------------
  |  |  133|   185k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  820|       |
  821|   185k|    return changed;
  822|   185k|}
m_config_cache_set_wakeup_cb:
  826|  1.13M|{
  827|  1.13M|    struct config_cache *in = cache->internal;
  828|  1.13M|    struct m_config_shadow *shadow = in->shadow;
  829|       |
  830|  1.13M|    mp_mutex_lock(&shadow->lock);
  ------------------
  |  |  131|  1.13M|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  831|  1.13M|    if (in->in_list) {
  ------------------
  |  Branch (831:9): [True: 17.1k, False: 1.11M]
  ------------------
  832|  22.7k|        for (int n = 0; n < shadow->num_listeners; n++) {
  ------------------
  |  Branch (832:25): [True: 14.1k, False: 8.59k]
  ------------------
  833|  14.1k|            if (shadow->listeners[n] == in) {
  ------------------
  |  Branch (833:17): [True: 8.59k, False: 5.56k]
  ------------------
  834|  8.59k|                MP_TARRAY_REMOVE_AT(shadow->listeners, shadow->num_listeners, n);
  ------------------
  |  |  143|  8.59k|    do {                                            \
  |  |  144|  8.59k|        size_t at_ = (at);                          \
  |  |  145|  8.59k|        assert(at_ <= (idxvar));                    \
  |  |  146|  8.59k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  8.59k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  8.59k|        (idxvar)--;                                 \
  |  |  149|  8.59k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  835|  8.59k|                break;
  836|  8.59k|            }
  837|  14.1k|        }
  838|  22.7k|        for (int n = 0; n < shadow->num_listeners; n++)
  ------------------
  |  Branch (838:25): [True: 5.56k, False: 17.1k]
  ------------------
  839|  17.1k|            mp_assert(shadow->listeners[n] != in); // only 1 wakeup_cb per cache
  ------------------
  |  |   41|  17.1k|#define mp_assert assert
  ------------------
  840|       |        // (The deinitialization path relies on this to free all memory.)
  841|  17.1k|        if (!shadow->num_listeners) {
  ------------------
  |  Branch (841:13): [True: 11.6k, False: 5.56k]
  ------------------
  842|  11.6k|            talloc_free(shadow->listeners);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
  843|  11.6k|            shadow->listeners = NULL;
  844|  11.6k|        }
  845|  17.1k|    }
  846|  1.13M|    if (cb) {
  ------------------
  |  Branch (846:9): [True: 8.59k, False: 1.12M]
  ------------------
  847|  8.59k|        MP_TARRAY_APPEND(NULL, shadow->listeners, shadow->num_listeners, in);
  ------------------
  |  |  105|  8.59k|    do {                                            \
  |  |  106|  8.59k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  8.59k|    do {                                            \
  |  |  |  |   97|  8.59k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  8.59k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  8.59k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  8.59k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 2.78k]
  |  |  |  |  ------------------
  |  |  |  |   99|  8.59k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  8.59k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  8.59k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  8.59k|        (idxvar)++;                                 \
  |  |  109|  8.59k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  848|  8.59k|        in->in_list = true;
  849|  8.59k|        in->wakeup_cb = cb;
  850|  8.59k|        in->wakeup_cb_ctx = cb_ctx;
  851|  8.59k|    }
  852|  1.13M|    mp_mutex_unlock(&shadow->lock);
  ------------------
  |  |  133|  1.13M|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  853|  1.13M|}
m_config_cache_set_dispatch_change_cb:
  868|   567k|{
  869|   567k|    struct config_cache *in = cache->internal;
  870|       |
  871|       |    // Removing the old one is tricky. First make sure no new notifications will
  872|       |    // come.
  873|   567k|    m_config_cache_set_wakeup_cb(cache, NULL, NULL);
  874|       |    // Remove any pending notifications (assume we're on the same thread as
  875|       |    // any potential mp_dispatch_queue_process() callers).
  876|   567k|    if (in->wakeup_dispatch_queue) {
  ------------------
  |  Branch (876:9): [True: 8.59k, False: 559k]
  ------------------
  877|  8.59k|        mp_dispatch_cancel_fn(in->wakeup_dispatch_queue,
  878|  8.59k|                              in->wakeup_dispatch_cb,
  879|  8.59k|                              in->wakeup_dispatch_cb_ctx);
  880|  8.59k|    }
  881|       |
  882|   567k|    in->wakeup_dispatch_queue = NULL;
  883|   567k|    in->wakeup_dispatch_cb = NULL;
  884|   567k|    in->wakeup_dispatch_cb_ctx = NULL;
  885|       |
  886|   567k|    if (cb) {
  ------------------
  |  Branch (886:9): [True: 8.59k, False: 559k]
  ------------------
  887|  8.59k|        in->wakeup_dispatch_queue = dispatch;
  888|  8.59k|        in->wakeup_dispatch_cb = cb;
  889|  8.59k|        in->wakeup_dispatch_cb_ctx = cb_ctx;
  890|  8.59k|        m_config_cache_set_wakeup_cb(cache, dispatch_notify, in);
  891|  8.59k|    }
  892|   567k|}
mp_get_config_group:
  896|   295k|{
  897|   295k|    struct m_config_cache *cache = m_config_cache_alloc(NULL, global, group);
  898|       |    // Make talloc_free(cache->opts) free the entire cache.
  899|   295k|    ta_set_parent(cache->opts, ta_parent);
  900|   295k|    ta_set_parent(cache, cache->opts);
  901|   295k|    return cache->opts;
  902|   295k|}
m_config_group_from_desc:
  919|  4.13k|{
  920|  4.13k|    const struct m_config_group *group = find_group(global, desc->options);
  921|  4.13k|    if (group) {
  ------------------
  |  Branch (921:9): [True: 4.13k, False: 0]
  ------------------
  922|  4.13k|        return mp_get_config_group(ta_parent, global, group->group);
  923|  4.13k|    } else {
  924|      0|        void *d = talloc_zero_size(ta_parent, desc->priv_size);
  ------------------
  |  |   44|      0|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|      0|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|      0|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  925|      0|        if (desc->priv_defaults)
  ------------------
  |  Branch (925:13): [True: 0, False: 0]
  ------------------
  926|      0|            memcpy(d, desc->priv_defaults, desc->priv_size);
  927|      0|        return d;
  928|      0|    }
  929|  4.13k|}
m_config_core.c:iter_next:
  154|  4.34M|{
  155|  4.34M|    int32_t id = *p_id;
  156|  4.34M|    int group_index = id == -1 ? group_start : id >> 16;
  ------------------
  |  Branch (156:23): [True: 5.81k, False: 4.33M]
  ------------------
  157|  4.34M|    int opt_index = id == -1 ? -1 : id & 0xFFFF;
  ------------------
  |  Branch (157:21): [True: 5.81k, False: 4.33M]
  ------------------
  158|       |
  159|  4.34M|    mp_assert(group_index >= group_start && group_index <= group_end);
  ------------------
  |  |   41|  4.34M|#define mp_assert assert
  ------------------
  160|       |
  161|  4.85M|    while (1) {
  ------------------
  |  Branch (161:12): [Folded - Ignored]
  ------------------
  162|  4.85M|        if (group_index >= group_end)
  ------------------
  |  Branch (162:13): [True: 5.81k, False: 4.85M]
  ------------------
  163|  5.81k|            return false;
  164|       |
  165|  4.85M|        struct m_config_group *g = &shadow->groups[group_index];
  166|  4.85M|        const struct m_option *opts = g->group->opts;
  167|       |
  168|  4.85M|        mp_assert(opt_index >= -1 && opt_index < g->opt_count);
  ------------------
  |  |   41|  4.85M|#define mp_assert assert
  ------------------
  169|       |
  170|  4.85M|        opt_index += 1;
  171|       |
  172|  4.85M|        if (!opts || !opts[opt_index].name) {
  ------------------
  |  Branch (172:13): [True: 0, False: 4.85M]
  |  Branch (172:22): [True: 278k, False: 4.57M]
  ------------------
  173|   278k|            group_index += 1;
  174|   278k|            opt_index = -1;
  175|   278k|            continue;
  176|   278k|        }
  177|       |
  178|  4.57M|        if (opts[opt_index].type == &m_option_type_subconfig)
  ------------------
  |  Branch (178:13): [True: 238k, False: 4.33M]
  ------------------
  179|   238k|            continue;
  180|       |
  181|  4.33M|        *p_id = (group_index << 16) | opt_index;
  182|  4.33M|        return true;
  183|  4.57M|    }
  184|  4.34M|}
m_config_core.c:get_opt_from_id:
  199|  13.3M|{
  200|  13.3M|    int group_index = id >> 16;
  201|  13.3M|    int opt_index = id & 0xFFFF;
  202|       |
  203|  13.3M|    mp_assert(group_index >= 0 && group_index < shadow->num_groups);
  ------------------
  |  |   41|  13.3M|#define mp_assert assert
  ------------------
  204|  13.3M|    mp_assert(opt_index >= 0 && opt_index < shadow->groups[group_index].opt_count);
  ------------------
  |  |   41|  13.3M|#define mp_assert assert
  ------------------
  205|       |
  206|  13.3M|    *out_group_index = group_index;
  207|  13.3M|    *out_opt_index = opt_index;
  208|  13.3M|}
m_config_core.c:concat_name_buf:
  132|  4.64M|{
  133|  4.64M|    mp_assert(a);
  ------------------
  |  |   41|  4.64M|#define mp_assert assert
  ------------------
  134|  4.64M|    mp_assert(b);
  ------------------
  |  |   41|  4.64M|#define mp_assert assert
  ------------------
  135|  4.64M|    if (!a[0])
  ------------------
  |  Branch (135:9): [True: 3.59M, False: 1.05M]
  ------------------
  136|  3.59M|        return b;
  137|  1.05M|    if (!b[0])
  ------------------
  |  Branch (137:9): [True: 0, False: 1.05M]
  ------------------
  138|      0|        return a;
  139|  1.05M|    snprintf(buf, buf_size, "%s-%s", a, b);
  140|  1.05M|    return buf;
  141|  1.05M|}
m_config_core.c:m_config_gdata:
  120|  10.7M|{
  121|  10.7M|    if (group_index < data->group_index ||
  ------------------
  |  Branch (121:9): [True: 0, False: 10.7M]
  ------------------
  122|  10.7M|        group_index >= data->group_index + data->num_gdata)
  ------------------
  |  Branch (122:9): [True: 0, False: 10.7M]
  ------------------
  123|      0|        return NULL;
  124|       |
  125|  10.7M|    return &data->gdata[group_index - data->group_index];
  126|  10.7M|}
m_config_core.c:get_opt_change_mask:
  281|   104k|{
  282|   104k|    uint64_t changed = opt->flags & UPDATE_OPTS_MASK;
  ------------------
  |  |  453|   104k|#define UPDATE_OPTS_MASK        ((UPDATE_OPT_LAST << 1) - 1)
  |  |  ------------------
  |  |  |  |  450|   104k|#define UPDATE_OPT_LAST         (UINT64_C(1) << 20)
  |  |  ------------------
  ------------------
  283|   151k|    while (group_index != group_root) {
  ------------------
  |  Branch (283:12): [True: 46.4k, False: 104k]
  ------------------
  284|  46.4k|        struct m_config_group *g = &shadow->groups[group_index];
  285|  46.4k|        changed |= g->group->change_flags;
  286|  46.4k|        group_index = g->parent_group;
  287|  46.4k|    }
  288|   104k|    return changed;
  289|   104k|}
m_config_core.c:shadow_destroy:
  432|  5.81k|{
  433|  5.81k|    struct m_config_shadow *shadow = p;
  434|       |
  435|       |    // must all have been unregistered
  436|  5.81k|    mp_assert(shadow->num_listeners == 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  437|       |
  438|  5.81k|    talloc_free(shadow->data);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  439|  5.81k|    mp_mutex_destroy(&shadow->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  440|  5.81k|}
m_config_core.c:allocate_option_data:
  414|   564k|{
  415|   564k|    mp_assert(group_index >= 0 && group_index < shadow->num_groups);
  ------------------
  |  |   41|   564k|#define mp_assert assert
  ------------------
  416|   564k|    struct m_config_data *data = talloc_zero(ta_parent, struct m_config_data);
  ------------------
  |  |   27|   564k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|   564k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   564k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  417|   564k|    talloc_set_destructor(data, free_option_data);
  ------------------
  |  |   41|   564k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  418|       |
  419|   564k|    data->shadow = shadow;
  420|   564k|    data->group_index = group_index;
  421|       |
  422|   564k|    struct m_config_group *root_group = &shadow->groups[group_index];
  423|   564k|    mp_assert(root_group->group_count > 0);
  ------------------
  |  |   41|   564k|#define mp_assert assert
  ------------------
  424|       |
  425|  3.49M|    for (int n = group_index; n < group_index + root_group->group_count; n++)
  ------------------
  |  Branch (425:31): [True: 2.92M, False: 564k]
  ------------------
  426|  2.92M|        alloc_group(data, n, copy);
  427|       |
  428|   564k|    return data;
  429|   564k|}
m_config_core.c:free_option_data:
  388|   564k|{
  389|   564k|    struct m_config_data *data = p;
  390|       |
  391|  3.49M|    for (int i = 0; i < data->num_gdata; i++) {
  ------------------
  |  Branch (391:21): [True: 2.92M, False: 564k]
  ------------------
  392|  2.92M|        struct m_group_data *gdata = &data->gdata[i];
  393|  2.92M|        struct m_config_group *group =
  394|  2.92M|            &data->shadow->groups[data->group_index + i];
  395|  2.92M|        const struct m_option *opts = group->group->opts;
  396|       |
  397|  50.6M|        for (int n = 0; opts && opts[n].name; n++) {
  ------------------
  |  Branch (397:25): [True: 50.6M, False: 101]
  |  Branch (397:33): [True: 47.7M, False: 2.92M]
  ------------------
  398|  47.7M|            const struct m_option *opt = &opts[n];
  399|       |
  400|  47.7M|            if (opt->offset >= 0 && opt->type->size > 0)
  ------------------
  |  Branch (400:17): [True: 45.1M, False: 2.52M]
  |  Branch (400:37): [True: 43.1M, False: 2.04M]
  ------------------
  401|  43.1M|                m_option_free(opt, gdata->udata + opt->offset);
  402|  47.7M|        }
  403|  2.92M|    }
  404|   564k|}
m_config_core.c:alloc_group:
  341|  2.92M|{
  342|  2.92M|    mp_assert(group_index == data->group_index + data->num_gdata);
  ------------------
  |  |   41|  2.92M|#define mp_assert assert
  ------------------
  343|  2.92M|    mp_assert(group_index < data->shadow->num_groups);
  ------------------
  |  |   41|  2.92M|#define mp_assert assert
  ------------------
  344|  2.92M|    struct m_config_group *group = &data->shadow->groups[group_index];
  345|  2.92M|    const struct m_sub_options *opts = group->group;
  346|       |
  347|  2.92M|    MP_TARRAY_GROW(data, data->gdata, data->num_gdata);
  ------------------
  |  |   96|  2.92M|    do {                                            \
  |  |   97|  2.92M|        size_t nextidx_ = (nextidx);                \
  |  |   98|  2.92M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  2.92M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  2.92M|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 782k, False: 2.14M]
  |  |  ------------------
  |  |   99|  2.92M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|   782k|    do {                                                        \
  |  |  |  |   89|   782k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|   782k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|   782k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|   782k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|   782k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|   782k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|   782k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  2.92M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  348|  2.92M|    struct m_group_data *gdata = &data->gdata[data->num_gdata++];
  349|       |
  350|  2.92M|    struct m_group_data *copy_gdata =
  351|  2.92M|        copy ? m_config_gdata(copy, group_index) : NULL;
  ------------------
  |  Branch (351:9): [True: 2.64M, False: 278k]
  ------------------
  352|       |
  353|  2.92M|    *gdata = (struct m_group_data){
  354|  2.92M|        .udata = talloc_zero_size(data, opts->size),
  ------------------
  |  |   44|  2.92M|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|  2.92M|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|  2.92M|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  2.92M|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  2.92M|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.92M|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  355|  2.92M|        .ts = copy_gdata ? copy_gdata->ts : 0,
  ------------------
  |  Branch (355:15): [True: 2.64M, False: 278k]
  ------------------
  356|  2.92M|    };
  357|       |
  358|  2.92M|    if (opts->defaults)
  ------------------
  |  Branch (358:9): [True: 2.66M, False: 261k]
  ------------------
  359|  2.66M|        memcpy(gdata->udata, opts->defaults, opts->size);
  360|       |
  361|  2.92M|    char *copy_src = copy_gdata ? copy_gdata->udata : NULL;
  ------------------
  |  Branch (361:22): [True: 2.64M, False: 278k]
  ------------------
  362|       |
  363|  50.6M|    for (int n = 0; opts->opts && opts->opts[n].name; n++) {
  ------------------
  |  Branch (363:21): [True: 50.6M, False: 0]
  |  Branch (363:35): [True: 47.7M, False: 2.92M]
  ------------------
  364|  47.7M|        const struct m_option *opt = &opts->opts[n];
  365|       |
  366|  47.7M|        if (opt->offset < 0 || opt->type->size == 0)
  ------------------
  |  Branch (366:13): [True: 2.52M, False: 45.1M]
  |  Branch (366:32): [True: 2.04M, False: 43.1M]
  ------------------
  367|  4.56M|            continue;
  368|       |
  369|  43.1M|        void *dst = gdata->udata + opt->offset;
  370|  43.1M|        const void *defptr = opt->defval ? opt->defval : dst;
  ------------------
  |  Branch (370:30): [True: 73.4k, False: 43.0M]
  ------------------
  371|  43.1M|        if (copy_src)
  ------------------
  |  Branch (371:13): [True: 39.1M, False: 4.04M]
  ------------------
  372|  39.1M|            defptr = copy_src + opt->offset;
  373|       |
  374|  43.1M|        init_opt_inplace(opt, dst, defptr);
  375|  43.1M|    }
  376|       |
  377|       |    // If there's a parent, update its pointer to the new struct.
  378|  2.92M|    if (group->parent_group >= data->group_index && group->parent_ptr >= 0) {
  ------------------
  |  Branch (378:9): [True: 2.36M, False: 564k]
  |  Branch (378:53): [True: 2.04M, False: 321k]
  ------------------
  379|  2.04M|        struct m_group_data *parent_gdata =
  380|  2.04M|            m_config_gdata(data, group->parent_group);
  381|  2.04M|        mp_assert(parent_gdata);
  ------------------
  |  |   41|  2.04M|#define mp_assert assert
  ------------------
  382|       |
  383|  2.04M|        substruct_write_ptr(parent_gdata->udata + group->parent_ptr, gdata->udata);
  384|  2.04M|    }
  385|  2.92M|}
m_config_core.c:init_opt_inplace:
  327|  43.1M|{
  328|       |    // The option will use dynamic memory allocation iff it has a free callback.
  329|  43.1M|    if (opt->type->free) {
  ------------------
  |  Branch (329:9): [True: 7.71M, False: 35.4M]
  ------------------
  330|  7.71M|        union m_option_value temp;
  331|  7.71M|        memcpy(&temp, src, opt->type->size);
  332|  7.71M|        memset(dst, 0, opt->type->size);
  333|  7.71M|        m_option_copy(opt, dst, &temp);
  334|  35.4M|    } else if (src != dst) {
  ------------------
  |  Branch (334:16): [True: 32.1M, False: 3.26M]
  ------------------
  335|  32.1M|        memcpy(dst, src, opt->type->size);
  336|  32.1M|    }
  337|  43.1M|}
m_config_core.c:substruct_write_ptr:
  318|  2.04M|{
  319|  2.04M|    struct mp_dummy_ *src = val;
  320|  2.04M|    memcpy(ptr, &src, sizeof(src));
  321|  2.04M|}
m_config_core.c:add_sub_group:
  486|   278k|{
  487|       |    // Can't be used multiple times.
  488|  6.83M|    for (int n = 0; n < shadow->num_groups; n++)
  ------------------
  |  Branch (488:21): [True: 6.55M, False: 278k]
  ------------------
  489|  6.55M|        mp_assert(shadow->groups[n].group != subopts);
  ------------------
  |  |   41|   278k|#define mp_assert assert
  ------------------
  490|       |
  491|   278k|    if (!name_prefix)
  ------------------
  |  Branch (491:9): [True: 40.6k, False: 238k]
  ------------------
  492|  40.6k|        name_prefix = "";
  493|   278k|    if (subopts->prefix && subopts->prefix[0]) {
  ------------------
  |  Branch (493:9): [True: 29.0k, False: 249k]
  |  Branch (493:28): [True: 29.0k, False: 0]
  ------------------
  494|  29.0k|        mp_assert(!name_prefix[0]);
  ------------------
  |  |   41|  29.0k|#define mp_assert assert
  ------------------
  495|  29.0k|        name_prefix = subopts->prefix;
  496|  29.0k|    }
  497|       |
  498|       |    // You can only use UPDATE_ flags here.
  499|   278k|    mp_assert(!(subopts->change_flags & ~UPDATE_OPTS_MASK));
  ------------------
  |  |   41|   278k|#define mp_assert assert
  ------------------
  500|       |
  501|   278k|    mp_assert(parent_group_index >= -1 && parent_group_index < shadow->num_groups);
  ------------------
  |  |   41|   278k|#define mp_assert assert
  ------------------
  502|       |
  503|   278k|    int group_index = shadow->num_groups++;
  504|   278k|    MP_TARRAY_GROW(shadow, shadow->groups, group_index);
  ------------------
  |  |   96|   278k|    do {                                            \
  |  |   97|   278k|        size_t nextidx_ = (nextidx);                \
  |  |   98|   278k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|   278k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|   278k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 29.0k, False: 249k]
  |  |  ------------------
  |  |   99|   278k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  29.0k|    do {                                                        \
  |  |  |  |   89|  29.0k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  29.0k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  29.0k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  29.0k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  29.0k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  29.0k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  29.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|   278k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  505|   278k|    shadow->groups[group_index] = (struct m_config_group){
  506|   278k|        .group = subopts,
  507|   278k|        .parent_group = parent_group_index,
  508|   278k|        .parent_ptr = parent_ptr,
  509|   278k|        .prefix = name_prefix,
  510|   278k|    };
  511|       |
  512|  4.85M|    for (int i = 0; subopts->opts && subopts->opts[i].name; i++) {
  ------------------
  |  Branch (512:21): [True: 4.85M, False: 0]
  |  Branch (512:38): [True: 4.57M, False: 278k]
  ------------------
  513|  4.57M|        const struct m_option *opt = &subopts->opts[i];
  514|       |
  515|  4.57M|        if (opt->type == &m_option_type_subconfig) {
  ------------------
  |  Branch (515:13): [True: 238k, False: 4.33M]
  ------------------
  516|   238k|            const struct m_sub_options *new_subopts = opt->priv;
  517|       |
  518|       |            // Providing default structs in-place is not allowed.
  519|   238k|            if (opt->offset >= 0 && subopts->defaults) {
  ------------------
  |  Branch (519:17): [True: 238k, False: 0]
  |  Branch (519:37): [True: 232k, False: 5.81k]
  ------------------
  520|   232k|                void *ptr = (char *)subopts->defaults + opt->offset;
  521|   232k|                mp_assert(!substruct_read_ptr(ptr));
  ------------------
  |  |   41|   232k|#define mp_assert assert
  ------------------
  522|   232k|            }
  523|       |
  524|   238k|            const char *prefix = concat_name(shadow, name_prefix, opt->name);
  525|   238k|            add_sub_group(shadow, prefix, group_index, opt->offset, new_subopts);
  526|       |
  527|  4.33M|        } else if (opt->type == &m_option_type_obj_settings_list) {
  ------------------
  |  Branch (527:20): [True: 40.6k, False: 4.29M]
  ------------------
  528|  40.6k|            const struct m_obj_list *objlist = opt->priv;
  529|  40.6k|            init_obj_settings_list(shadow, group_index, objlist);
  530|  40.6k|        }
  531|       |
  532|  4.57M|        shadow->groups[group_index].opt_count = i + 1;
  533|  4.57M|    }
  534|       |
  535|   278k|    if (subopts->get_sub_options) {
  ------------------
  |  Branch (535:9): [True: 5.81k, False: 273k]
  ------------------
  536|  75.5k|        for (int i = 0; ; i++) {
  537|  75.5k|            const struct m_sub_options *sub = NULL;
  538|  75.5k|            if (!subopts->get_sub_options(i, &sub))
  ------------------
  |  Branch (538:17): [True: 5.81k, False: 69.7k]
  ------------------
  539|  5.81k|                break;
  540|  69.7k|            if (sub)
  ------------------
  |  Branch (540:17): [True: 0, False: 69.7k]
  ------------------
  541|      0|                add_sub_group(shadow, NULL, group_index, -1, sub);
  542|  69.7k|        }
  543|  5.81k|    }
  544|       |
  545|   278k|    shadow->groups[group_index].group_count = shadow->num_groups - group_index;
  546|   278k|}
m_config_core.c:substruct_read_ptr:
  312|   232k|{
  313|   232k|    struct mp_dummy_ *res;
  314|   232k|    memcpy(&res, ptr, sizeof(res));
  315|   232k|    return res;
  316|   232k|}
m_config_core.c:concat_name:
  146|   238k|{
  147|   238k|    char buf[M_CONFIG_MAX_OPT_NAME_LEN];
  148|   238k|    const char *r = concat_name_buf(buf, sizeof(buf), a, b);
  149|   238k|    return r == buf ? talloc_strdup(ta_parent, r) : r;
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (149:12): [True: 0, False: 238k]
  ------------------
  150|   238k|}
m_config_core.c:init_obj_settings_list:
  461|  40.6k|{
  462|  40.6k|    struct m_obj_desc desc;
  463|   185k|    for (int n = 0; ; n++) {
  464|   185k|        if (!list->get_desc(&desc, n))
  ------------------
  |  Branch (464:13): [True: 40.6k, False: 145k]
  ------------------
  465|  40.6k|            break;
  466|   145k|        if (desc.global_opts) {
  ------------------
  |  Branch (466:13): [True: 5.81k, False: 139k]
  ------------------
  467|  5.81k|            add_sub_group(shadow, NULL, parent_group_index, -1,
  468|  5.81k|                          desc.global_opts);
  469|  5.81k|        }
  470|   145k|        if (list->use_global_options && desc.options) {
  ------------------
  |  Branch (470:13): [True: 81.3k, False: 63.9k]
  |  Branch (470:41): [True: 29.0k, False: 52.2k]
  ------------------
  471|  29.0k|            struct m_sub_options *conf = talloc_ptrtype(shadow, conf);
  ------------------
  |  |   34|  29.0k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  29.0k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  29.0k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  472|  29.0k|            *conf = (struct m_sub_options){
  473|  29.0k|                .prefix = desc.options_prefix,
  474|  29.0k|                .opts = desc.options,
  475|  29.0k|                .defaults = desc.priv_defaults,
  476|  29.0k|                .size = desc.priv_size,
  477|  29.0k|            };
  478|  29.0k|            add_sub_group(shadow, NULL, parent_group_index, -1, conf);
  479|  29.0k|        }
  480|   145k|    }
  481|  40.6k|}
m_config_core.c:cache_destroy:
  549|   559k|{
  550|   559k|    struct m_config_cache *cache = p;
  551|       |
  552|       |    // (technically speaking, being able to call them both without anything
  553|       |    // breaking is a feature provided by these functions)
  554|   559k|    m_config_cache_set_wakeup_cb(cache, NULL, NULL);
  555|   559k|    m_config_cache_set_dispatch_change_cb(cache, NULL, NULL, NULL);
  556|   559k|}
m_config_core.c:cache_check_update:
  703|  6.25M|{
  704|  6.25M|    struct config_cache *in = cache->internal;
  705|  6.25M|    struct m_config_shadow *shadow = in->shadow;
  706|       |
  707|       |    // Using atomics and checking outside of the lock - it's unknown whether
  708|       |    // this makes it faster or slower. Just cargo culting it.
  709|  6.25M|    uint64_t new_ts = atomic_load(&shadow->ts);
  710|  6.25M|    if (in->ts >= new_ts)
  ------------------
  |  Branch (710:9): [True: 6.20M, False: 51.1k]
  ------------------
  711|  6.20M|        return false;
  712|       |
  713|  51.1k|    in->ts = new_ts;
  714|  51.1k|    in->upd_group = in->data->group_index;
  715|  51.1k|    in->upd_opt = 0;
  716|  51.1k|    return true;
  717|  6.25M|}
m_config_core.c:update_next_option:
  639|  68.6k|{
  640|  68.6k|    struct config_cache *in = cache->internal;
  641|  68.6k|    struct m_config_data *dst = in->data;
  642|  68.6k|    struct m_config_data *src = in->src;
  643|       |
  644|  68.6k|    mp_assert(src->group_index == 0); // must be the option root currently
  ------------------
  |  |   41|  68.6k|#define mp_assert assert
  ------------------
  645|       |
  646|  68.6k|    *p_opt = NULL;
  647|       |
  648|   153k|    while (in->upd_group < dst->group_index + dst->num_gdata) {
  ------------------
  |  Branch (648:12): [True: 101k, False: 51.2k]
  ------------------
  649|   101k|        struct m_group_data *gsrc = m_config_gdata(src, in->upd_group);
  650|   101k|        struct m_group_data *gdst = m_config_gdata(dst, in->upd_group);
  651|   101k|        mp_assert(gsrc && gdst);
  ------------------
  |  |   41|   101k|#define mp_assert assert
  ------------------
  652|       |
  653|   101k|        if (gdst->ts < gsrc->ts) {
  ------------------
  |  Branch (653:13): [True: 23.2k, False: 78.6k]
  ------------------
  654|  23.2k|            struct m_config_group *g = &dst->shadow->groups[in->upd_group];
  655|  23.2k|            const struct m_option *opts = g->group->opts;
  656|       |
  657|   116k|            while (opts && opts[in->upd_opt].name) {
  ------------------
  |  Branch (657:20): [True: 116k, False: 0]
  |  Branch (657:28): [True: 110k, False: 5.81k]
  ------------------
  658|   110k|                const struct m_option *opt = &opts[in->upd_opt];
  659|   110k|                void *dsrc = gsrc->udata + opt->offset;
  660|   110k|                void *ddst = gdst->udata + opt->offset;
  661|       |
  662|   110k|                if (opt->offset >= 0 && opt->type->size) {
  ------------------
  |  Branch (662:21): [True: 98.7k, False: 11.6k]
  |  Branch (662:41): [True: 98.7k, False: 0]
  ------------------
  663|  98.7k|                    bool opt_equal = m_option_equal(opt, ddst, dsrc);
  664|  98.7k|                    bool force_update = opt->force_update &&
  ------------------
  |  Branch (664:41): [True: 0, False: 98.7k]
  ------------------
  665|  98.7k|                                        check_force_update(gsrc, opt->name, in->ts);
  ------------------
  |  Branch (665:41): [True: 0, False: 0]
  ------------------
  666|  98.7k|                    if (!opt_equal || force_update) {
  ------------------
  |  Branch (666:25): [True: 17.4k, False: 81.3k]
  |  Branch (666:39): [True: 0, False: 81.3k]
  ------------------
  667|  17.4k|                        uint64_t ch = get_opt_change_mask(dst->shadow,
  668|  17.4k|                                        in->upd_group, dst->group_index, opt);
  669|       |
  670|  17.4k|                        if (cache->debug && !opt_equal) {
  ------------------
  |  Branch (670:29): [True: 0, False: 17.4k]
  |  Branch (670:45): [True: 0, False: 0]
  ------------------
  671|      0|                            char *vdst = m_option_print(opt, ddst);
  672|      0|                            char *vsrc = m_option_print(opt, dsrc);
  673|      0|                            mp_warn(cache->debug, "Option '%s' changed from "
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
  674|      0|                                    "'%s' to' %s' (flags = 0x%"PRIx64")\n",
  675|      0|                                    opt->name, vdst, vsrc, ch);
  676|      0|                            talloc_free(vdst);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  677|      0|                            talloc_free(vsrc);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  678|      0|                        }
  679|       |
  680|  17.4k|                        m_option_copy(opt, ddst, dsrc);
  681|  17.4k|                        cache->change_flags |= ch;
  682|       |
  683|  17.4k|                        in->upd_opt++; // skip this next time
  684|  17.4k|                        *p_opt = ddst;
  685|  17.4k|                        return;
  686|  17.4k|                    }
  687|  98.7k|                }
  688|       |
  689|  92.9k|                in->upd_opt++;
  690|  92.9k|            }
  691|       |
  692|  5.81k|            gdst->ts = gsrc->ts;
  693|  5.81k|        }
  694|       |
  695|  84.4k|        in->upd_group++;
  696|  84.4k|        in->upd_opt = 0;
  697|  84.4k|    }
  698|       |
  699|  51.2k|    in->upd_group = -1;
  700|  51.2k|}
m_config_core.c:find_opt:
  757|   185k|{
  758|   185k|    *group_idx = -1;
  759|   185k|    *opt_idx = -1;
  760|       |
  761|  1.12M|    for (int n = data->group_index; n < data->group_index + data->num_gdata; n++)
  ------------------
  |  Branch (761:37): [True: 1.12M, False: 0]
  ------------------
  762|  1.12M|    {
  763|  1.12M|        struct m_group_data *gd = m_config_gdata(data, n);
  764|  1.12M|        struct m_config_group *g = &shadow->groups[n];
  765|  1.12M|        const struct m_option *opts = g->group->opts;
  766|       |
  767|  28.2M|        for (int i = 0; opts && opts[i].name; i++) {
  ------------------
  |  Branch (767:25): [True: 28.2M, False: 0]
  |  Branch (767:33): [True: 27.3M, False: 935k]
  ------------------
  768|  27.3M|            const struct m_option *opt = &opts[i];
  769|       |
  770|  27.3M|            if (opt->offset >= 0 && opt->type->size &&
  ------------------
  |  Branch (770:17): [True: 23.6M, False: 3.67M]
  |  Branch (770:37): [True: 21.7M, False: 1.93M]
  ------------------
  771|  27.3M|                ptr == gd->udata + opt->offset)
  ------------------
  |  Branch (771:17): [True: 185k, False: 21.5M]
  ------------------
  772|   185k|            {
  773|   185k|                *group_idx = n;
  774|   185k|                *opt_idx = i;
  775|   185k|                return;
  776|   185k|            }
  777|  27.3M|        }
  778|  1.12M|    }
  779|   185k|}
m_config_core.c:find_group:
  906|  4.13k|{
  907|  4.13k|    struct m_config_shadow *shadow = global->config;
  908|       |
  909|   121k|    for (int n = 0; n < shadow->num_groups; n++) {
  ------------------
  |  Branch (909:21): [True: 121k, False: 0]
  ------------------
  910|   121k|        if (shadow->groups[n].group->opts == cfg)
  ------------------
  |  Branch (910:13): [True: 4.13k, False: 117k]
  ------------------
  911|  4.13k|            return &shadow->groups[n];
  912|   121k|    }
  913|       |
  914|      0|    return NULL;
  915|  4.13k|}

m_config_restore_backups:
  229|   100k|{
  230|   100k|    restore_backups(&config->backup_opts, config);
  231|   100k|}
m_config_backup_watch_later_opts:
  270|  5.81k|{
  271|  4.34M|    for (int n = 0; n < config->num_opts; n++)
  ------------------
  |  Branch (271:21): [True: 4.33M, False: 5.81k]
  ------------------
  272|  4.33M|        ensure_backup(&config->watch_later_backup_opts, 0, &config->opts[n]);
  273|  5.81k|}
m_config_get_co_raw:
  277|   615k|{
  278|   615k|    if (!name.len)
  ------------------
  |  Branch (278:9): [True: 0, False: 615k]
  ------------------
  279|      0|        return NULL;
  280|       |
  281|   202M|    for (int n = 0; n < config->num_opts; n++) {
  ------------------
  |  Branch (281:21): [True: 202M, False: 58.1k]
  ------------------
  282|   202M|        struct m_config_option *co = &config->opts[n];
  283|   202M|        struct bstr coname = bstr0(co->name);
  284|   202M|        if (bstrcmp(coname, name) == 0)
  ------------------
  |  Branch (284:13): [True: 557k, False: 201M]
  ------------------
  285|   557k|            return co;
  286|   202M|    }
  287|       |
  288|  58.1k|    return NULL;
  289|   615k|}
m_config_get_co:
  343|   435k|{
  344|   435k|    struct m_config_option *co = m_config_get_co_any(config, name);
  345|       |    // CLI aliases should not be real options, and are explicitly handled by
  346|       |    // m_config_set_option_cli(). So pretend it does not exist.
  347|   435k|    if (co && co->opt->type == &m_option_type_cli_alias)
  ------------------
  |  Branch (347:9): [True: 406k, False: 29.0k]
  |  Branch (347:15): [True: 17.4k, False: 389k]
  ------------------
  348|  17.4k|        co = NULL;
  349|   435k|    return co;
  350|   435k|}
m_config_get_co_count:
  353|  5.81k|{
  354|  5.81k|    return config->num_opts;
  355|  5.81k|}
m_config_get_co_index:
  358|  4.33M|{
  359|  4.33M|    return &config->opts[index];
  360|  4.33M|}
m_config_mark_co_flags:
  415|  87.1k|{
  416|  87.1k|    if (flags & M_SETOPT_FROM_CMDLINE)
  ------------------
  |  Branch (416:9): [True: 0, False: 87.1k]
  ------------------
  417|      0|        co->is_set_from_cmdline = true;
  418|       |
  419|  87.1k|    if (flags & M_SETOPT_FROM_CONFIG_FILE)
  ------------------
  |  Branch (419:9): [True: 46.4k, False: 40.6k]
  ------------------
  420|  46.4k|        co->is_set_from_config = true;
  421|  87.1k|}
m_config_set_update_dispatch_queue:
  514|  5.81k|{
  515|  5.81k|    m_config_cache_set_dispatch_change_cb(config->cache, dispatch,
  516|  5.81k|                                          async_change_cb, config);
  517|  5.81k|}
m_config_new:
  538|  5.81k|{
  539|  5.81k|    struct m_config *config = talloc(talloc_ctx, struct m_config);
  ------------------
  |  |   26|  5.81k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  540|  5.81k|    talloc_set_destructor(config, config_destroy);
  ------------------
  |  |   41|  5.81k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  541|  5.81k|    *config = (struct m_config){.log = log,};
  542|       |
  543|  5.81k|    config->shadow = m_config_shadow_new(root);
  544|       |
  545|  5.81k|    if (root->size) {
  ------------------
  |  Branch (545:9): [True: 5.81k, False: 0]
  ------------------
  546|  5.81k|        config->cache = m_config_cache_from_shadow(config, config->shadow, root);
  547|  5.81k|        config->optstruct = config->cache->opts;
  548|  5.81k|    }
  549|       |
  550|  5.81k|    int32_t optid = -1;
  551|  4.34M|    while (m_config_shadow_get_next_opt(config->shadow, &optid)) {
  ------------------
  |  Branch (551:12): [True: 4.33M, False: 5.81k]
  ------------------
  552|  4.33M|        char buf[M_CONFIG_MAX_OPT_NAME_LEN];
  553|  4.33M|        const char *opt_name =
  554|  4.33M|            m_config_shadow_get_opt_name(config->shadow, optid, buf, sizeof(buf));
  555|       |
  556|  4.33M|        struct m_config_option co = {
  557|  4.33M|            .name = talloc_strdup(config, opt_name),
  ------------------
  |  |   50|  4.33M|#define talloc_strdup                   ta_xstrdup
  ------------------
  558|  4.33M|            .opt = m_config_shadow_get_opt(config->shadow, optid),
  559|  4.33M|            .opt_id = optid,
  560|  4.33M|        };
  561|       |
  562|  4.33M|        if (config->cache)
  ------------------
  |  Branch (562:13): [True: 4.33M, False: 0]
  ------------------
  563|  4.33M|            co.data = m_config_cache_get_opt_data(config->cache, optid);
  564|       |
  565|  4.33M|        MP_TARRAY_APPEND(config, config->opts, config->num_opts, co);
  ------------------
  |  |  105|  4.33M|    do {                                            \
  |  |  106|  4.33M|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.33M|    do {                                            \
  |  |  |  |   97|  4.33M|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.33M|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.33M|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.33M|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 52.2k, False: 4.28M]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.33M|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  52.2k|    do {                                                        \
  |  |  |  |  |  |   89|  52.2k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  52.2k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  52.2k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  52.2k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  52.2k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  52.2k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  52.2k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.33M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.33M|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.33M|        (idxvar)++;                                 \
  |  |  109|  4.33M|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  566|  4.33M|    }
  567|       |
  568|  5.81k|    return config;
  569|  5.81k|}
m_config_notify_change_opt_ptr:
  602|  98.7k|{
  603|  98.7k|    notify_opt(config, ptr, true);
  604|  98.7k|}
m_config_set_option_raw:
  616|   412k|{
  617|   412k|    if (!co)
  ------------------
  |  Branch (617:9): [True: 0, False: 412k]
  ------------------
  618|      0|        return M_OPT_UNKNOWN;
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  619|       |
  620|   412k|    int r = handle_set_opt_flags(config, co, flags);
  621|   412k|    if (r <= 1)
  ------------------
  |  Branch (621:9): [True: 325k, False: 87.1k]
  ------------------
  622|   325k|        return r;
  623|       |
  624|  87.1k|    r = m_config_handle_special_options(config, co, data, flags);
  625|  87.1k|    if (r != M_OPT_UNKNOWN)
  ------------------
  |  |  517|  87.1k|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (625:9): [True: 0, False: 87.1k]
  ------------------
  626|      0|        return r;
  627|       |
  628|       |    // This affects some special options like "playlist", "v". Maybe these
  629|       |    // should work, or maybe not. For now they would require special code.
  630|  87.1k|    if (!co->data)
  ------------------
  |  Branch (630:9): [True: 0, False: 87.1k]
  ------------------
  631|      0|        return flags & M_SETOPT_FROM_CMDLINE ? 0 : M_OPT_UNKNOWN;
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (631:16): [True: 0, False: 0]
  ------------------
  632|       |
  633|  87.1k|    if (config->profile_backup_tmp)
  ------------------
  |  Branch (633:9): [True: 0, False: 87.1k]
  ------------------
  634|      0|        ensure_backup(config->profile_backup_tmp, config->profile_backup_flags, co);
  635|       |
  636|  87.1k|    m_config_mark_co_flags(co, flags);
  637|       |
  638|  87.1k|    m_option_copy(co->opt, co->data, data);
  639|  87.1k|    if (m_config_cache_write_opt(config->cache, co->data))
  ------------------
  |  Branch (639:9): [True: 87.1k, False: 0]
  ------------------
  640|  87.1k|        force_self_notify_change_opt(config, co, false);
  641|       |
  642|  87.1k|    return 0;
  643|  87.1k|}
m_config_set_option_cli:
  718|   395k|{
  719|   395k|    int r;
  720|   395k|    mp_assert(config != NULL);
  ------------------
  |  |   41|   395k|#define mp_assert assert
  ------------------
  721|       |
  722|   395k|    bool negate;
  723|   395k|    struct m_config_option *co =
  724|   395k|        m_config_mogrify_cli_opt(config, &name, &negate, &(int){0});
  725|       |
  726|   395k|    if (!co) {
  ------------------
  |  Branch (726:9): [True: 23.2k, False: 371k]
  ------------------
  727|  23.2k|        r = M_OPT_UNKNOWN;
  ------------------
  |  |  517|  23.2k|#define M_OPT_UNKNOWN           -1
  ------------------
  728|  23.2k|        goto done;
  729|  23.2k|    }
  730|       |
  731|   371k|    if (negate) {
  ------------------
  |  Branch (731:9): [True: 0, False: 371k]
  ------------------
  732|      0|        if (param.len) {
  ------------------
  |  Branch (732:13): [True: 0, False: 0]
  ------------------
  733|      0|            r = M_OPT_DISALLOW_PARAM;
  ------------------
  |  |  530|      0|#define M_OPT_DISALLOW_PARAM    -5
  ------------------
  734|      0|            goto done;
  735|      0|        }
  736|       |
  737|      0|        param = bstr0("no");
  738|      0|    }
  739|       |
  740|   371k|    if (flags & M_SETOPT_FROM_CONFIG_FILE)
  ------------------
  |  Branch (740:9): [True: 371k, False: 0]
  ------------------
  741|   371k|        co->coalesce = true;
  742|       |
  743|       |    // This is the only mandatory function
  744|   371k|    mp_assert(co->opt->type->parse);
  ------------------
  |  |   41|   371k|#define mp_assert assert
  ------------------
  745|       |
  746|   371k|    r = handle_set_opt_flags(config, co, flags);
  747|   371k|    if (r <= 0)
  ------------------
  |  Branch (747:9): [True: 0, False: 371k]
  ------------------
  748|      0|        goto done;
  749|       |
  750|   371k|    if (r == 2) {
  ------------------
  |  Branch (750:9): [True: 46.4k, False: 325k]
  ------------------
  751|  46.4k|        MP_VERBOSE(config, "Setting option '%.*s' = '%.*s' (flags = %d)\n",
  ------------------
  |  |   88|  46.4k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   185k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 46.4k, False: 0]
  |  |  |  |  |  Branch (82:57): [True: 46.4k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  752|  46.4k|                   BSTR_P(name), BSTR_P(param), flags);
  753|  46.4k|    }
  754|       |
  755|   371k|    union m_option_value val = m_option_value_default;
  756|       |
  757|       |    // Some option types are "impure" and work on the existing data.
  758|       |    // (Prime examples: --vf-add, --sub-file)
  759|   371k|    if (co->data)
  ------------------
  |  Branch (759:9): [True: 354k, False: 17.4k]
  ------------------
  760|   354k|        m_option_copy(co->opt, &val, co->data);
  761|       |
  762|   371k|    r = m_option_parse(config->log, co->opt, name, param, &val);
  763|       |
  764|   371k|    if (r >= 0)
  ------------------
  |  Branch (764:9): [True: 371k, False: 0]
  ------------------
  765|   371k|        r = m_config_set_option_raw(config, co, &val, flags);
  766|       |
  767|   371k|    m_option_free(co->opt, &val);
  768|       |
  769|   395k|done:
  770|   395k|    if (r < 0 && r != M_OPT_EXIT) {
  ------------------
  |  |  533|  23.2k|#define M_OPT_EXIT              -6
  ------------------
  |  Branch (770:9): [True: 23.2k, False: 371k]
  |  Branch (770:18): [True: 23.2k, False: 0]
  ------------------
  771|  23.2k|        MP_ERR(config, "Error parsing option %.*s (%s)\n",
  ------------------
  |  |   85|  23.2k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  46.4k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 23.2k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  772|  23.2k|               BSTR_P(name), m_option_strerror(r));
  773|  23.2k|        r = M_OPT_INVALID;
  ------------------
  |  |  523|  23.2k|#define M_OPT_INVALID           -3
  ------------------
  774|  23.2k|    }
  775|   395k|    return r;
  776|   371k|}
m_config_set_option_node:
  780|  40.6k|{
  781|  40.6k|    int r;
  782|       |
  783|  40.6k|    struct m_config_option *co = m_config_get_co(config, name);
  784|  40.6k|    if (!co)
  ------------------
  |  Branch (784:9): [True: 0, False: 40.6k]
  ------------------
  785|      0|        return M_OPT_UNKNOWN;
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  786|       |
  787|       |    // Do this on an "empty" type to make setting the option strictly overwrite
  788|       |    // the old value, as opposed to e.g. appending to lists.
  789|  40.6k|    union m_option_value val = m_option_value_default;
  790|       |
  791|  40.6k|    if (data->format == MPV_FORMAT_STRING) {
  ------------------
  |  Branch (791:9): [True: 40.6k, False: 0]
  ------------------
  792|  40.6k|        bstr param = bstr0(data->u.string);
  793|  40.6k|        r = m_option_parse(mp_null_log, co->opt, name, param, &val);
  794|  40.6k|    } else {
  795|      0|        r = m_option_set_node(co->opt, &val, data);
  796|      0|    }
  797|       |
  798|  40.6k|    if (r >= 0)
  ------------------
  |  Branch (798:9): [True: 40.6k, False: 0]
  ------------------
  799|  40.6k|        r = m_config_set_option_raw(config, co, &val, flags);
  800|       |
  801|  40.6k|    if (mp_msg_test(config->log, MSGL_V)) {
  ------------------
  |  Branch (801:9): [True: 0, False: 40.6k]
  ------------------
  802|      0|        char *s = m_option_type_node.print(NULL, data);
  803|      0|        MP_DBG(config, "Setting option '%.*s' = %s (flags = %d) -> %d\n",
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  804|      0|               BSTR_P(name), s ? s : "?", flags, r);
  805|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  806|      0|    }
  807|       |
  808|  40.6k|    m_option_free(co->opt, &val);
  809|  40.6k|    return r;
  810|  40.6k|}
m_config_get_profile:
  924|   101k|{
  925|   856k|    for (struct m_profile *p = config->profiles; p; p = p->next) {
  ------------------
  |  Branch (925:50): [True: 772k, False: 84.0k]
  ------------------
  926|   772k|        if (bstr_equals0(name, p->name))
  ------------------
  |  Branch (926:13): [True: 17.4k, False: 755k]
  ------------------
  927|  17.4k|            return p;
  928|   772k|    }
  929|  84.0k|    return NULL;
  930|   101k|}
m_config_get_profile0:
  934|   101k|{
  935|   101k|    return m_config_get_profile(config, bstr0(name));
  936|   101k|}
m_config_add_profile:
  939|  81.3k|{
  940|  81.3k|    if (!name || !name[0])
  ------------------
  |  Branch (940:9): [True: 11.6k, False: 69.7k]
  |  Branch (940:18): [True: 0, False: 69.7k]
  ------------------
  941|  11.6k|        name = "default";
  942|  81.3k|    struct m_profile *p = m_config_get_profile0(config, name);
  943|  81.3k|    if (p)
  ------------------
  |  Branch (943:9): [True: 5.81k, False: 75.5k]
  ------------------
  944|  5.81k|        return p;
  945|  75.5k|    p = talloc_zero(config, struct m_profile);
  ------------------
  |  |   27|  75.5k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  75.5k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  75.5k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  946|  75.5k|    p->name = talloc_strdup(p, name);
  ------------------
  |  |   50|  75.5k|#define talloc_strdup                   ta_xstrdup
  ------------------
  947|  75.5k|    p->next = config->profiles;
  948|  75.5k|    config->profiles = p;
  949|  75.5k|    return p;
  950|  81.3k|}
m_config_set_profile_option:
  954|   348k|{
  955|   348k|    if (bstr_equals0(name, "profile-desc")) {
  ------------------
  |  Branch (955:9): [True: 0, False: 348k]
  ------------------
  956|      0|        talloc_free(p->desc);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  957|      0|        p->desc = bstrto0(p, val);
  958|      0|        return 0;
  959|      0|    }
  960|   348k|    if (bstr_equals0(name, "profile-cond")) {
  ------------------
  |  Branch (960:9): [True: 0, False: 348k]
  ------------------
  961|      0|        TA_FREEP(&p->cond);
  ------------------
  |  |   81|      0|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|      0|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  962|      0|        val = bstr_strip(val);
  963|      0|        if (val.len)
  ------------------
  |  Branch (963:13): [True: 0, False: 0]
  ------------------
  964|      0|            p->cond = bstrto0(p, val);
  965|      0|        return 0;
  966|      0|    }
  967|   348k|    if (bstr_equals0(name, profile_restore_mode_opt.name)) {
  ------------------
  |  Branch (967:9): [True: 0, False: 348k]
  ------------------
  968|      0|        return m_option_parse(config->log, &profile_restore_mode_opt, name, val,
  969|      0|                              &p->restore_mode);
  970|      0|    }
  971|       |
  972|   348k|    int i = m_config_set_option_cli(config, name, val,
  973|   348k|                                    M_SETOPT_CHECK_ONLY |
  974|   348k|                                    M_SETOPT_FROM_CONFIG_FILE);
  975|   348k|    if (i < 0)
  ------------------
  |  Branch (975:9): [True: 23.2k, False: 325k]
  ------------------
  976|  23.2k|        return i;
  977|   325k|    p->opts = talloc_realloc(p, p->opts, char *, 2 * (p->num_opts + 2));
  ------------------
  |  |   33|   325k|#define talloc_realloc                  ta_xrealloc
  |  |  ------------------
  |  |  |  |  144|   325k|    (type *)ta_xrealloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count))
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|   325k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|   325k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|   325k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|   325k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  978|   325k|    p->opts[p->num_opts * 2] = bstrto0(p, name);
  979|   325k|    p->opts[p->num_opts * 2 + 1] = bstrto0(p, val);
  980|   325k|    p->num_opts++;
  981|   325k|    p->opts[p->num_opts * 2] = p->opts[p->num_opts * 2 + 1] = NULL;
  982|   325k|    return 1;
  983|   348k|}
m_config_set_profile:
 1006|  11.6k|{
 1007|  11.6k|    MP_VERBOSE(config, "Applying profile '%s'...\n", name);
  ------------------
  |  |   88|  11.6k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  11.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1008|  11.6k|    struct m_profile *p = find_check_profile(config, name);
 1009|  11.6k|    if (!p)
  ------------------
  |  Branch (1009:9): [True: 0, False: 11.6k]
  ------------------
 1010|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1011|       |
 1012|  11.6k|    if (!config->profile_backup_tmp && p->restore_mode) {
  ------------------
  |  Branch (1012:9): [True: 11.6k, False: 0]
  |  Branch (1012:40): [True: 0, False: 11.6k]
  ------------------
 1013|      0|        config->profile_backup_tmp = &p->backups;
 1014|      0|        config->profile_backup_flags = p->restore_mode == 2 ? BACKUP_NVAL : 0;
  ------------------
  |  |  187|      0|#define BACKUP_NVAL 2
  ------------------
  |  Branch (1014:40): [True: 0, False: 0]
  ------------------
 1015|      0|    }
 1016|       |
 1017|  11.6k|    char *profile_name = talloc_strdup(NULL, name);
  ------------------
  |  |   50|  11.6k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1018|       |    // Note that we don't check if profile applied correctly, it doesn't matter.
 1019|  11.6k|    MP_TARRAY_APPEND(config, config->profile_stack, config->profile_stack_depth, profile_name);
  ------------------
  |  |  105|  11.6k|    do {                                            \
  |  |  106|  11.6k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  11.6k|    do {                                            \
  |  |  |  |   97|  11.6k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  11.6k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  11.6k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  11.6k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 5.81k]
  |  |  |  |  ------------------
  |  |  |  |   99|  11.6k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  11.6k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  11.6k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  11.6k|        (idxvar)++;                                 \
  |  |  109|  11.6k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1020|  11.6k|    talloc_steal(config->profile_stack, profile_name);
  ------------------
  |  |   38|  11.6k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  11.6k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 1021|  58.1k|    for (int i = 0; i < p->num_opts; i++) {
  ------------------
  |  Branch (1021:21): [True: 46.4k, False: 11.6k]
  ------------------
 1022|  46.4k|        m_config_set_option_cli(config,
 1023|  46.4k|                                bstr0(p->opts[2 * i]),
 1024|  46.4k|                                bstr0(p->opts[2 * i + 1]),
 1025|  46.4k|                                flags | M_SETOPT_FROM_CONFIG_FILE);
 1026|  46.4k|    }
 1027|  11.6k|    if (MP_TARRAY_POP(config->profile_stack, config->profile_stack_depth, &profile_name))
  ------------------
  |  |  153|  11.6k|    ((idxvar) > 0                                   \
  |  |  ------------------
  |  |  |  Branch (153:5): [True: 11.6k, False: 0]
  |  |  |  Branch (153:6): [True: 11.6k, False: 0]
  |  |  ------------------
  |  |  154|  11.6k|        ? (*(out) = (p)[--(idxvar)], true)          \
  |  |  155|  11.6k|        : false                                     \
  |  |  156|  11.6k|    )
  ------------------
 1028|  11.6k|        talloc_free(profile_name);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
 1029|       |
 1030|  11.6k|    if (config->profile_backup_tmp == &p->backups) {
  ------------------
  |  Branch (1030:9): [True: 0, False: 11.6k]
  ------------------
 1031|      0|        config->profile_backup_tmp = NULL;
 1032|       |
 1033|      0|        for (struct m_opt_backup *bc = p->backups; bc; bc = bc->next) {
  ------------------
  |  Branch (1033:52): [True: 0, False: 0]
  ------------------
 1034|      0|            if (bc && bc->nval)
  ------------------
  |  Branch (1034:17): [True: 0, False: 0]
  |  Branch (1034:23): [True: 0, False: 0]
  ------------------
 1035|      0|                m_option_copy(bc->co->opt, bc->nval, bc->co->data);
 1036|      0|            talloc_steal(p, bc);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 1037|      0|        }
 1038|      0|    }
 1039|       |
 1040|  11.6k|    return 0;
 1041|  11.6k|}
m_config_finish_default_profile:
 1059|  5.81k|{
 1060|  5.81k|    struct m_profile *p = m_config_add_profile(config, NULL);
 1061|  5.81k|    m_config_set_profile(config, p->name, flags & ~M_SETOPT_FROM_CONFIG_FILE);
 1062|  5.81k|    p->num_opts = 0;
 1063|  5.81k|}
m_config_frontend.c:restore_backups:
  214|   100k|{
  215|   100k|    while (*list) {
  ------------------
  |  Branch (215:12): [True: 0, False: 100k]
  ------------------
  216|      0|        struct m_opt_backup *bc = *list;
  217|      0|        *list = bc->next;
  218|       |
  219|      0|        if (!bc->nval || m_option_equal(bc->co->opt, bc->co->data, bc->nval))
  ------------------
  |  Branch (219:13): [True: 0, False: 0]
  |  Branch (219:26): [True: 0, False: 0]
  ------------------
  220|      0|            m_config_set_option_raw(config, bc->co, bc->backup, 0);
  221|       |
  222|      0|        if (bc->flags & BACKUP_LOCAL)
  ------------------
  |  |  186|      0|#define BACKUP_LOCAL 1
  ------------------
  |  Branch (222:13): [True: 0, False: 0]
  ------------------
  223|      0|            bc->co->is_set_locally = false;
  224|      0|        talloc_free(bc);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  225|      0|    }
  226|   100k|}
m_config_frontend.c:ensure_backup:
  190|  4.33M|{
  191|  4.33M|    if (!co->data)
  ------------------
  |  Branch (191:9): [True: 290k, False: 4.04M]
  ------------------
  192|   290k|        return;
  193|  1.40G|    for (struct m_opt_backup *cur = *list; cur; cur = cur->next) {
  ------------------
  |  Branch (193:44): [True: 1.40G, False: 4.04M]
  ------------------
  194|  1.40G|        if (cur->co->data == co->data) // comparing data ptr catches aliases
  ------------------
  |  Branch (194:13): [True: 0, False: 1.40G]
  ------------------
  195|      0|            return;
  196|  1.40G|    }
  197|  4.04M|    struct m_opt_backup *bc = talloc_ptrtype(NULL, bc);
  ------------------
  |  |   34|  4.04M|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  4.04M|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  4.04M|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  198|  4.04M|    talloc_set_destructor(bc, backup_dtor);
  ------------------
  |  |   41|  4.04M|#define talloc_set_destructor           ta_set_destructor
  ------------------
  199|  4.04M|    *bc = (struct m_opt_backup) {
  200|  4.04M|        .co = co,
  201|  4.04M|        .backup = talloc_zero_size(bc, co->opt->type->size),
  ------------------
  |  |   44|  4.04M|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|  4.04M|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|  4.04M|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  4.04M|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  4.04M|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.04M|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  202|  4.04M|        .nval = flags & BACKUP_NVAL
  ------------------
  |  |  187|  4.04M|#define BACKUP_NVAL 2
  ------------------
  |  Branch (202:17): [True: 0, False: 4.04M]
  ------------------
  203|  4.04M|            ? talloc_zero_size(bc, co->opt->type->size) : NULL,
  ------------------
  |  |   44|      0|#define talloc_zero_size                ta_xzalloc_size
  |  |  ------------------
  |  |  |  |  121|      0|#define ta_xzalloc_size(...)            ta_oom_p(ta_zalloc_size(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  154|      0|#define ta_zalloc_size(...)     ta_dbg_set_loc(ta_zalloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  204|  4.04M|        .flags = flags,
  205|  4.04M|    };
  206|  4.04M|    m_option_copy(co->opt, bc->backup, co->data);
  207|  4.04M|    bc->next = *list;
  208|  4.04M|    *list = bc;
  209|  4.04M|    if (bc->flags & BACKUP_LOCAL)
  ------------------
  |  |  186|  4.04M|#define BACKUP_LOCAL 1
  ------------------
  |  Branch (209:9): [True: 0, False: 4.04M]
  ------------------
  210|      0|        co->is_set_locally = true;
  211|  4.04M|}
m_config_frontend.c:backup_dtor:
  179|  4.04M|{
  180|  4.04M|    struct m_opt_backup *bc = p;
  181|  4.04M|    m_option_free(bc->co->opt, bc->backup);
  182|  4.04M|    if (bc->nval)
  ------------------
  |  Branch (182:9): [True: 0, False: 4.04M]
  ------------------
  183|      0|        m_option_free(bc->co->opt, bc->nval);
  184|  4.04M|}
m_config_frontend.c:m_config_get_co_any:
  294|   482k|{
  295|   482k|    struct m_config_option *co = m_config_get_co_raw(config, name);
  296|   482k|    if (!co)
  ------------------
  |  Branch (296:9): [True: 58.1k, False: 424k]
  ------------------
  297|  58.1k|        return NULL;
  298|       |
  299|   424k|    const char *prefix = config->is_toplevel ? "--" : "";
  ------------------
  |  Branch (299:26): [True: 424k, False: 0]
  ------------------
  300|   424k|    if (co->opt->type == &m_option_type_alias) {
  ------------------
  |  Branch (300:9): [True: 0, False: 424k]
  ------------------
  301|      0|        char buf[M_CONFIG_MAX_OPT_NAME_LEN];
  302|      0|        const char *alias = m_config_shadow_get_alias_from_opt(config->shadow, co->opt_id,
  303|      0|                                                               buf, sizeof(buf));
  304|      0|        if (co->opt->deprecation_message && !co->warning_was_printed) {
  ------------------
  |  Branch (304:13): [True: 0, False: 0]
  |  Branch (304:45): [True: 0, False: 0]
  ------------------
  305|      0|            if (co->opt->deprecation_message[0]) {
  ------------------
  |  Branch (305:17): [True: 0, False: 0]
  ------------------
  306|      0|                MP_WARN(config, "Warning: option %s%s was replaced with "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  307|      0|                        "%s%s: %s\n", prefix, co->name, prefix, alias,
  308|      0|                        co->opt->deprecation_message);
  309|      0|            } else {
  310|      0|                MP_WARN(config, "Warning: option %s%s was replaced with "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  311|      0|                        "%s%s and might be removed in the future.\n",
  312|      0|                        prefix, co->name, prefix, alias);
  313|      0|            }
  314|      0|            co->warning_was_printed = true;
  315|      0|        }
  316|      0|        return m_config_get_co_any(config, bstr0(alias));
  317|   424k|    } else if (co->opt->type == &m_option_type_removed) {
  ------------------
  |  Branch (317:16): [True: 0, False: 424k]
  ------------------
  318|      0|        if (!co->warning_was_printed) {
  ------------------
  |  Branch (318:13): [True: 0, False: 0]
  ------------------
  319|      0|            char *msg = co->opt->priv;
  320|      0|            if (msg) {
  ------------------
  |  Branch (320:17): [True: 0, False: 0]
  ------------------
  321|      0|                MP_FATAL(config, "Option %s%s was removed: %s\n",
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  322|      0|                         prefix, co->name, msg);
  323|      0|            } else {
  324|      0|                MP_FATAL(config, "Option %s%s was removed.\n",
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  325|      0|                         prefix, co->name);
  326|      0|            }
  327|      0|            co->warning_was_printed = true;
  328|      0|        }
  329|      0|        return NULL;
  330|   424k|    } else if (co->opt->deprecation_message) {
  ------------------
  |  Branch (330:16): [True: 0, False: 424k]
  ------------------
  331|      0|        if (!co->warning_was_printed) {
  ------------------
  |  Branch (331:13): [True: 0, False: 0]
  ------------------
  332|      0|            MP_WARN(config, "Warning: option %s%s is deprecated "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  333|      0|                    "and might be removed in the future (%s).\n",
  334|      0|                    prefix, co->name, co->opt->deprecation_message);
  335|      0|            co->warning_was_printed = true;
  336|      0|        }
  337|      0|    }
  338|   424k|    return co;
  339|   424k|}
m_config_frontend.c:config_destroy:
  520|  5.81k|{
  521|  5.81k|    struct m_config *config = p;
  522|  5.81k|    config->option_change_callback = NULL;
  523|  5.81k|    m_config_restore_backups(config);
  524|       |
  525|  5.81k|    struct m_opt_backup **list = &config->watch_later_backup_opts;
  526|  4.05M|    while (*list) {
  ------------------
  |  Branch (526:12): [True: 4.04M, False: 5.81k]
  ------------------
  527|  4.04M|        struct m_opt_backup *bc = *list;
  528|  4.04M|        *list = bc->next;
  529|  4.04M|        talloc_free(bc);
  ------------------
  |  |   47|  4.04M|#define talloc_free                     ta_free
  ------------------
  530|  4.04M|    }
  531|       |
  532|  5.81k|    talloc_free(config->cache);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  533|  5.81k|    talloc_free(config->shadow);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  534|  5.81k|}
m_config_frontend.c:notify_opt:
  587|  98.7k|{
  588|  4.25M|    for (int n = 0; n < config->num_opts; n++) {
  ------------------
  |  Branch (588:21): [True: 4.25M, False: 0]
  ------------------
  589|  4.25M|        struct m_config_option *co = &config->opts[n];
  590|  4.25M|        if (co->data == ptr) {
  ------------------
  |  Branch (590:13): [True: 98.7k, False: 4.15M]
  ------------------
  591|  98.7k|            if (m_config_cache_write_opt(config->cache, co->data))
  ------------------
  |  Branch (591:17): [True: 0, False: 98.7k]
  ------------------
  592|      0|                force_self_notify_change_opt(config, co, self_notification);
  593|  98.7k|            return;
  594|  98.7k|        }
  595|  4.25M|    }
  596|       |    // ptr doesn't point to any config->optstruct field declared in the
  597|       |    // option list?
  598|      0|    mp_assert(false);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  599|      0|}
m_config_frontend.c:handle_set_opt_flags:
  385|   784k|{
  386|   784k|    uint64_t optflags = co->opt->flags;
  387|   784k|    bool set = !(flags & M_SETOPT_CHECK_ONLY);
  388|       |
  389|   784k|    if ((flags & M_SETOPT_PRE_PARSE_ONLY) && !(optflags & M_OPT_PRE_PARSE))
  ------------------
  |  |  459|      0|#define M_OPT_PRE_PARSE         (UINT64_C(1) << 62)
  ------------------
  |  Branch (389:9): [True: 0, False: 784k]
  |  Branch (389:46): [True: 0, False: 0]
  ------------------
  390|      0|        return 0;
  391|       |
  392|   784k|    if ((flags & M_SETOPT_PRESERVE_CMDLINE) && co->is_set_from_cmdline)
  ------------------
  |  Branch (392:9): [True: 0, False: 784k]
  |  Branch (392:48): [True: 0, False: 0]
  ------------------
  393|      0|        set = false;
  394|       |
  395|   784k|    if ((flags & M_SETOPT_NO_OVERWRITE) &&
  ------------------
  |  Branch (395:9): [True: 0, False: 784k]
  ------------------
  396|   784k|        (co->is_set_from_cmdline || co->is_set_from_config))
  ------------------
  |  Branch (396:10): [True: 0, False: 0]
  |  Branch (396:37): [True: 0, False: 0]
  ------------------
  397|      0|        set = false;
  398|       |
  399|   784k|    if ((flags & M_SETOPT_NO_PRE_PARSE) && (optflags & M_OPT_PRE_PARSE))
  ------------------
  |  |  459|      0|#define M_OPT_PRE_PARSE         (UINT64_C(1) << 62)
  ------------------
  |  Branch (399:9): [True: 0, False: 784k]
  |  Branch (399:44): [True: 0, False: 0]
  ------------------
  400|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  401|       |
  402|       |    // Check if this option isn't forbidden in the current mode
  403|   784k|    if ((flags & M_SETOPT_FROM_CONFIG_FILE) && (optflags & M_OPT_NOCFG)) {
  ------------------
  |  |  456|   743k|#define M_OPT_NOCFG             (UINT64_C(1) << 63)
  ------------------
  |  Branch (403:9): [True: 743k, False: 40.6k]
  |  Branch (403:48): [True: 0, False: 743k]
  ------------------
  404|      0|        MP_ERR(config, "The %s option can't be used in a config file.\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  405|      0|               co->name);
  406|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  407|      0|    }
  408|   784k|    if ((flags & M_SETOPT_BACKUP) && set)
  ------------------
  |  Branch (408:9): [True: 0, False: 784k]
  |  Branch (408:38): [True: 0, False: 0]
  ------------------
  409|      0|        ensure_backup(&config->backup_opts, BACKUP_LOCAL, co);
  ------------------
  |  |  186|      0|#define BACKUP_LOCAL 1
  ------------------
  410|       |
  411|   784k|    return set ? 2 : 1;
  ------------------
  |  Branch (411:12): [True: 133k, False: 650k]
  ------------------
  412|   784k|}
m_config_frontend.c:m_config_handle_special_options:
  430|  87.1k|{
  431|  87.1k|    if (config->use_profiles && strcmp(co->name, "profile") == 0) {
  ------------------
  |  Branch (431:9): [True: 87.1k, False: 0]
  |  Branch (431:33): [True: 0, False: 87.1k]
  ------------------
  432|      0|        char **list = *(char ***)data;
  433|       |
  434|      0|        if (list && list[0] && !list[1] && strcmp(list[0], "help") == 0) {
  ------------------
  |  Branch (434:13): [True: 0, False: 0]
  |  Branch (434:21): [True: 0, False: 0]
  |  Branch (434:32): [True: 0, False: 0]
  |  Branch (434:44): [True: 0, False: 0]
  ------------------
  435|      0|            if (!config->profiles) {
  ------------------
  |  Branch (435:17): [True: 0, False: 0]
  ------------------
  436|      0|                MP_INFO(config, "No profiles have been defined.\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  437|      0|                return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  438|      0|            }
  439|      0|            list_profiles(config);
  440|      0|            return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  441|      0|        }
  442|       |
  443|      0|        for (int n = 0; list && list[n]; n++) {
  ------------------
  |  Branch (443:25): [True: 0, False: 0]
  |  Branch (443:33): [True: 0, False: 0]
  ------------------
  444|      0|            int r = m_config_set_profile(config, list[n], flags);
  445|      0|            if (r < 0)
  ------------------
  |  Branch (445:17): [True: 0, False: 0]
  ------------------
  446|      0|                return r;
  447|      0|        }
  448|      0|        return 0;
  449|      0|    }
  450|       |
  451|  87.1k|    if (config->includefunc && strcmp(co->name, "include") == 0) {
  ------------------
  |  Branch (451:9): [True: 87.1k, False: 0]
  |  Branch (451:32): [True: 0, False: 87.1k]
  ------------------
  452|      0|        char *param = *(char **)data;
  453|      0|        if (!param || !param[0])
  ------------------
  |  Branch (453:13): [True: 0, False: 0]
  |  Branch (453:23): [True: 0, False: 0]
  ------------------
  454|      0|            return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  455|      0|        if (config->recursion_depth >= MAX_RECURSION_DEPTH) {
  ------------------
  |  |   45|      0|#define MAX_RECURSION_DEPTH 8
  ------------------
  |  Branch (455:13): [True: 0, False: 0]
  ------------------
  456|      0|            MP_ERR(config, "Maximum 'include' nesting depth exceeded.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  457|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  458|      0|        }
  459|      0|        config->recursion_depth += 1;
  460|      0|        config->includefunc(config->includefunc_ctx, param, flags);
  461|      0|        config->recursion_depth -= 1;
  462|      0|        if (config->recursion_depth == 0 && config->profile_stack_depth == 0)
  ------------------
  |  Branch (462:13): [True: 0, False: 0]
  |  Branch (462:45): [True: 0, False: 0]
  ------------------
  463|      0|            m_config_finish_default_profile(config, flags);
  464|      0|        return 1;
  465|      0|    }
  466|       |
  467|  87.1k|    if (config->use_profiles && strcmp(co->name, "show-profile") == 0)
  ------------------
  |  Branch (467:9): [True: 87.1k, False: 0]
  |  Branch (467:33): [True: 0, False: 87.1k]
  ------------------
  468|      0|        return show_profile(config, bstr0(*(char **)data), 0);
  469|       |
  470|  87.1k|    if (config->is_toplevel && (strcmp(co->name, "h") == 0 ||
  ------------------
  |  Branch (470:9): [True: 87.1k, False: 0]
  |  Branch (470:33): [True: 0, False: 87.1k]
  ------------------
  471|  87.1k|                                strcmp(co->name, "help") == 0))
  ------------------
  |  Branch (471:33): [True: 0, False: 87.1k]
  ------------------
  472|      0|    {
  473|      0|        char *h = *(char **)data;
  474|      0|        mp_info(config->log, "%s", mp_help_text);
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  475|      0|        if (h && h[0])
  ------------------
  |  Branch (475:13): [True: 0, False: 0]
  |  Branch (475:18): [True: 0, False: 0]
  ------------------
  476|      0|            m_config_print_option_list(config, h);
  477|      0|        return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  478|      0|    }
  479|       |
  480|  87.1k|    if (strcmp(co->name, "list-options") == 0) {
  ------------------
  |  Branch (480:9): [True: 0, False: 87.1k]
  ------------------
  481|      0|        m_config_print_option_list(config, "*");
  482|      0|        return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  483|      0|    }
  484|       |
  485|  87.1k|    return M_OPT_UNKNOWN;
  ------------------
  |  |  517|  87.1k|#define M_OPT_UNKNOWN           -1
  ------------------
  486|  87.1k|}
m_config_frontend.c:force_self_notify_change_opt:
  576|  87.1k|{
  577|  87.1k|    int changed =
  578|  87.1k|        m_config_cache_get_option_change_mask(config->cache, co->opt_id);
  579|       |
  580|  87.1k|    if (config->option_change_callback) {
  ------------------
  |  Branch (580:9): [True: 0, False: 87.1k]
  ------------------
  581|      0|        config->option_change_callback(config->option_change_callback_ctx, co,
  582|      0|                                       changed, self_notification);
  583|      0|    }
  584|  87.1k|}
m_config_frontend.c:m_config_mogrify_cli_opt:
  652|   395k|{
  653|   395k|    *out_negate = false;
  654|   395k|    *out_add_flags = 0;
  655|       |
  656|   395k|    struct m_config_option *co = m_config_get_co(config, *name);
  657|   395k|    if (co)
  ------------------
  |  Branch (657:9): [True: 348k, False: 46.4k]
  ------------------
  658|   348k|        return co;
  659|       |
  660|       |    // Turn "--no-foo" into "foo" + set *out_negate.
  661|  46.4k|    bstr no_name = *name;
  662|  46.4k|    if (!co && bstr_eatstart0(&no_name, "no-")) {
  ------------------
  |  Branch (662:9): [True: 46.4k, False: 0]
  |  Branch (662:16): [True: 0, False: 46.4k]
  ------------------
  663|      0|        co = m_config_get_co(config, no_name);
  664|      0|        if (!co)
  ------------------
  |  Branch (664:13): [True: 0, False: 0]
  ------------------
  665|      0|            return NULL;
  666|       |
  667|       |        // Not all choice types have this value - if they don't, then parsing
  668|       |        // them will simply result in an error. Good enough.
  669|      0|        if (!(co->opt->type->flags & M_OPT_TYPE_CHOICE) &&
  ------------------
  |  |  500|      0|#define M_OPT_TYPE_CHOICE               (1 << 1)
  ------------------
  |  Branch (669:13): [True: 0, False: 0]
  ------------------
  670|      0|            !(co->opt->flags & M_OPT_ALLOW_NO))
  ------------------
  |  |  476|      0|#define M_OPT_ALLOW_NO          (UINT64_C(1) << 57)
  ------------------
  |  Branch (670:13): [True: 0, False: 0]
  ------------------
  671|      0|            return NULL;
  672|       |
  673|      0|        *name = no_name;
  674|      0|        *out_negate = true;
  675|      0|        return co;
  676|      0|    }
  677|       |
  678|       |    // Resolve CLI alias. (We don't allow you to combine them with "--no-".)
  679|  46.4k|    co = m_config_get_co_any(config, *name);
  680|  46.4k|    if (co && co->opt->type == &m_option_type_cli_alias)
  ------------------
  |  Branch (680:9): [True: 17.4k, False: 29.0k]
  |  Branch (680:15): [True: 17.4k, False: 0]
  ------------------
  681|  17.4k|        *name = bstr0((char *)co->opt->priv);
  682|       |
  683|       |    // Might be a suffix "action", like "--vf-add". Expensively check for
  684|       |    // matches. (We don't allow you to combine them with "--no-".)
  685|  19.3M|    for (int n = 0; n < config->num_opts; n++) {
  ------------------
  |  Branch (685:21): [True: 19.3M, False: 23.2k]
  ------------------
  686|  19.3M|        co = &config->opts[n];
  687|  19.3M|        struct bstr basename = bstr0(co->name);
  688|       |
  689|  19.3M|        if (!bstr_startswith(*name, basename))
  ------------------
  |  Branch (689:13): [True: 19.3M, False: 58.1k]
  ------------------
  690|  19.3M|            continue;
  691|       |
  692|       |        // Aliased option + a suffix action, e.g. --opengl-shaders-append
  693|  58.1k|        if (co->opt->type == &m_option_type_alias)
  ------------------
  |  Branch (693:13): [True: 0, False: 58.1k]
  ------------------
  694|      0|            co = m_config_get_co_any(config, basename);
  695|  58.1k|        if (!co)
  ------------------
  |  Branch (695:13): [True: 0, False: 58.1k]
  ------------------
  696|      0|            continue;
  697|       |
  698|  58.1k|        const struct m_option_type *type = co->opt->type;
  699|  75.5k|        for (int i = 0; type->actions && type->actions[i].name; i++) {
  ------------------
  |  Branch (699:25): [True: 40.6k, False: 34.8k]
  |  Branch (699:42): [True: 40.6k, False: 0]
  ------------------
  700|  40.6k|            const struct m_option_action *action = &type->actions[i];
  701|  40.6k|            bstr suffix = bstr0(action->name);
  702|       |
  703|  40.6k|            if (bstr_endswith(*name, suffix) &&
  ------------------
  |  Branch (703:17): [True: 23.2k, False: 17.4k]
  ------------------
  704|  40.6k|                (name->len == basename.len + 1 + suffix.len) &&
  ------------------
  |  Branch (704:17): [True: 23.2k, False: 0]
  ------------------
  705|  40.6k|                name->start[basename.len] == '-')
  ------------------
  |  Branch (705:17): [True: 23.2k, False: 0]
  ------------------
  706|  23.2k|            {
  707|  23.2k|                *out_add_flags = action->flags;
  708|  23.2k|                return co;
  709|  23.2k|            }
  710|  40.6k|        }
  711|  58.1k|    }
  712|       |
  713|  23.2k|    return NULL;
  714|  46.4k|}
m_config_frontend.c:find_check_profile:
  986|  11.6k|{
  987|  11.6k|    struct m_profile *p = m_config_get_profile0(config, name);
  988|  11.6k|    if (!p) {
  ------------------
  |  Branch (988:9): [True: 0, False: 11.6k]
  ------------------
  989|      0|        MP_WARN(config, "Unknown profile '%s'.\n", name);
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  990|      0|        return NULL;
  991|      0|    }
  992|  11.6k|    for (size_t i = 0; i < config->profile_stack_depth; ++i) {
  ------------------
  |  Branch (992:24): [True: 0, False: 11.6k]
  ------------------
  993|      0|        if (strcmp(config->profile_stack[i], name))
  ------------------
  |  Branch (993:13): [True: 0, False: 0]
  ------------------
  994|      0|            continue;
  995|      0|        MP_WARN(config, "Profile '%s' has already been applied.\n", name);
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  996|      0|        return NULL;
  997|      0|    }
  998|  11.6k|    if (config->profile_stack_depth > MAX_PROFILE_DEPTH) {
  ------------------
  |  |   43|  11.6k|#define MAX_PROFILE_DEPTH 20
  ------------------
  |  Branch (998:9): [True: 0, False: 11.6k]
  ------------------
  999|      0|        MP_WARN(config, "Profile inclusion too deep.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1000|      0|        return NULL;
 1001|      0|    }
 1002|  11.6k|    return p;
 1003|  11.6k|}

m_option_parse:
   65|  2.24M|{
   66|  2.24M|    int r = M_OPT_INVALID;
  ------------------
  |  |  523|  2.24M|#define M_OPT_INVALID           -3
  ------------------
   67|  2.24M|    if (bstr_equals0(param, "help") && opt->help) {
  ------------------
  |  Branch (67:9): [True: 0, False: 2.24M]
  |  Branch (67:40): [True: 0, False: 0]
  ------------------
   68|      0|        r = opt->help(log, opt, name);
   69|      0|        if (r < 0)
  ------------------
  |  Branch (69:13): [True: 0, False: 0]
  ------------------
   70|      0|            return r;
   71|      0|    }
   72|       |
   73|  2.24M|    r = opt->type->parse(log, opt, name, param, dst);
   74|  2.24M|    if (r < 0)
  ------------------
  |  Branch (74:9): [True: 0, False: 2.24M]
  ------------------
   75|      0|        return r;
   76|       |
   77|  2.24M|    if (opt->validate) {
  ------------------
  |  Branch (77:9): [True: 0, False: 2.24M]
  ------------------
   78|      0|        r = opt->validate(log, opt, name, dst);
   79|      0|        if (r < 0) {
  ------------------
  |  Branch (79:13): [True: 0, False: 0]
  ------------------
   80|      0|            if (opt->type->free)
  ------------------
  |  Branch (80:17): [True: 0, False: 0]
  ------------------
   81|      0|                opt->type->free(dst);
   82|      0|            return r;
   83|      0|        }
   84|      0|    }
   85|  2.24M|    return 1;
   86|  2.24M|}
m_option_strerror:
   89|  23.2k|{
   90|  23.2k|    switch (code) {
   91|  23.2k|    case M_OPT_UNKNOWN:
  ------------------
  |  |  517|  23.2k|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (91:5): [True: 23.2k, False: 0]
  ------------------
   92|  23.2k|        return "option not found";
   93|      0|    case M_OPT_MISSING_PARAM:
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  |  Branch (93:5): [True: 0, False: 23.2k]
  ------------------
   94|      0|        return "option requires parameter";
   95|      0|    case M_OPT_INVALID:
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  |  Branch (95:5): [True: 0, False: 23.2k]
  ------------------
   96|      0|        return "option parameter could not be parsed";
   97|      0|    case M_OPT_OUT_OF_RANGE:
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  |  Branch (97:5): [True: 0, False: 23.2k]
  ------------------
   98|      0|        return "parameter is outside values allowed for option";
   99|      0|    case M_OPT_DISALLOW_PARAM:
  ------------------
  |  |  530|      0|#define M_OPT_DISALLOW_PARAM    -5
  ------------------
  |  Branch (99:5): [True: 0, False: 23.2k]
  ------------------
  100|      0|        return "option doesn't take a parameter";
  101|      0|    default:
  ------------------
  |  Branch (101:5): [True: 0, False: 23.2k]
  ------------------
  102|      0|        return "parser error";
  103|  23.2k|    }
  104|  23.2k|}
m_opt_choice_str:
  613|   518k|{
  614|  1.58M|    for (const struct m_opt_choice_alternatives *c = choices; c->name; c++) {
  ------------------
  |  Branch (614:63): [True: 1.58M, False: 0]
  ------------------
  615|  1.58M|        if (c->value == value)
  ------------------
  |  Branch (615:13): [True: 518k, False: 1.06M]
  ------------------
  616|   518k|            return c->name;
  617|  1.58M|    }
  618|      0|    mp_require(false && "Invalid choice value!");
  ------------------
  |  |   42|      0|#define mp_require assert
  ------------------
  619|      0|}
m_obj_list_find:
 2940|  27.3k|{
 2941|   105k|    for (int i = 0; ; i++) {
 2942|   105k|        if (!l->get_desc(dst, i))
  ------------------
  |  Branch (2942:13): [True: 0, False: 105k]
  ------------------
 2943|      0|            break;
 2944|   105k|        if (bstr_equals0(name, dst->name))
  ------------------
  |  Branch (2944:13): [True: 27.3k, False: 78.0k]
  ------------------
 2945|  27.3k|            return true;
 2946|   105k|    }
 2947|      0|    for (int i = 0; l->aliases[i][0]; i++) {
  ------------------
  |  Branch (2947:21): [True: 0, False: 0]
  ------------------
 2948|      0|        const char *aname = l->aliases[i][0];
 2949|      0|        const char *alias = l->aliases[i][1];
 2950|      0|        if (bstr_equals0(name, aname) && m_obj_list_find(dst, l, bstr0(alias)))
  ------------------
  |  Branch (2950:13): [True: 0, False: 0]
  |  Branch (2950:42): [True: 0, False: 0]
  ------------------
 2951|      0|        {
 2952|      0|            dst->replaced_name = aname;
 2953|      0|            return true;
 2954|      0|        }
 2955|      0|    }
 2956|      0|    return false;
 2957|      0|}
node_get_alloc:
 3906|  11.6k|{
 3907|       |    // Assume it was allocated with copy_node(), which allocates all
 3908|       |    // sub-nodes with the parent node as talloc parent.
 3909|  11.6k|    switch (node->format) {
 3910|      0|    case MPV_FORMAT_STRING:
  ------------------
  |  Branch (3910:5): [True: 0, False: 11.6k]
  ------------------
 3911|      0|        return node->u.string;
 3912|      0|    case MPV_FORMAT_NODE_ARRAY:
  ------------------
  |  Branch (3912:5): [True: 0, False: 11.6k]
  ------------------
 3913|  5.81k|    case MPV_FORMAT_NODE_MAP:
  ------------------
  |  Branch (3913:5): [True: 5.81k, False: 5.81k]
  ------------------
 3914|  5.81k|        return node->u.list;
 3915|  5.81k|    default:
  ------------------
  |  Branch (3915:5): [True: 5.81k, False: 5.81k]
  ------------------
 3916|  5.81k|        return NULL;
 3917|  11.6k|    }
 3918|  11.6k|}
m_option.c:parse_bool:
  151|   162k|{
  152|   162k|    if (bstr_equals0(param, "yes") || !param.len) {
  ------------------
  |  Branch (152:9): [True: 29.0k, False: 133k]
  |  Branch (152:39): [True: 0, False: 133k]
  ------------------
  153|  29.0k|        if (dst)
  ------------------
  |  Branch (153:13): [True: 29.0k, False: 0]
  ------------------
  154|  29.0k|            VAL(dst) = 1;
  ------------------
  |  |  147|  29.0k|#define VAL(x) (*(bool *)(x))
  ------------------
  155|  29.0k|        return 1;
  156|  29.0k|    }
  157|   133k|    if (bstr_equals0(param, "no")) {
  ------------------
  |  Branch (157:9): [True: 133k, False: 0]
  ------------------
  158|   133k|        if (dst)
  ------------------
  |  Branch (158:13): [True: 133k, False: 0]
  ------------------
  159|   133k|            VAL(dst) = 0;
  ------------------
  |  |  147|   133k|#define VAL(x) (*(bool *)(x))
  ------------------
  160|   133k|        return 1;
  161|   133k|    }
  162|      0|    bool is_help = bstr_equals0(param, "help");
  163|      0|    if (is_help) {
  ------------------
  |  Branch (163:9): [True: 0, False: 0]
  ------------------
  164|      0|        mp_info(log, "Valid values for %.*s flag are:\n", BSTR_P(name));
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (74:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  165|      0|    } else {
  166|      0|        mp_fatal(log, "Invalid parameter for %.*s flag: %.*s\n",
  ------------------
  |  |   71|      0|#define mp_fatal(log, ...)      mp_msg(log, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  167|      0|                 BSTR_P(name), BSTR_P(param));
  168|      0|        mp_info(log, "Valid values are:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  169|      0|    }
  170|      0|    mp_info(log, "    yes\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  171|      0|    mp_info(log, "    no\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  172|      0|    mp_info(log, "    (passing nothing)\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  173|      0|    return is_help ? M_OPT_EXIT : M_OPT_INVALID;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
                  return is_help ? M_OPT_EXIT : M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  |  Branch (173:12): [True: 0, False: 0]
  ------------------
  174|   133k|}
m_option.c:copy_opt:
  140|  3.98M|{
  141|  3.98M|    if (dst && src)
  ------------------
  |  Branch (141:9): [True: 3.98M, False: 0]
  |  Branch (141:16): [True: 3.98M, False: 0]
  ------------------
  142|  3.98M|        memcpy(dst, src, opt->type->size);
  143|  3.98M|}
m_option.c:bool_equal:
  207|   219k|{
  208|   219k|    return VAL(a) == VAL(b);
  ------------------
  |  |  147|   219k|#define VAL(x) (*(bool *)(x))
  ------------------
                  return VAL(a) == VAL(b);
  ------------------
  |  |  147|   219k|#define VAL(x) (*(bool *)(x))
  ------------------
  209|   219k|}
m_option.c:parse_int:
  357|  52.2k|{
  358|  52.2k|    long long tmp;
  359|  52.2k|    int r = parse_longlong(log, opt, INT_MIN, INT_MAX, name, param, &tmp);
  360|  52.2k|    if (r >= 0 && dst)
  ------------------
  |  Branch (360:9): [True: 52.2k, False: 0]
  |  Branch (360:19): [True: 52.2k, False: 0]
  ------------------
  361|  52.2k|        *(int *)dst = tmp;
  362|  52.2k|    return r;
  363|  52.2k|}
m_option.c:parse_longlong:
  313|  52.2k|{
  314|  52.2k|    if (param.len == 0)
  ------------------
  |  Branch (314:9): [True: 0, False: 52.2k]
  ------------------
  315|      0|        return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  316|       |
  317|  52.2k|    struct bstr rest;
  318|  52.2k|    long long tmp_int = bstrtoll(param, &rest, 10);
  319|  52.2k|    if (rest.len)
  ------------------
  |  Branch (319:9): [True: 0, False: 52.2k]
  ------------------
  320|      0|        tmp_int = bstrtoll(param, &rest, 0);
  321|  52.2k|    if (rest.len) {
  ------------------
  |  Branch (321:9): [True: 0, False: 52.2k]
  ------------------
  322|      0|        mp_err(log, "The %.*s option must be an integer: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  323|      0|               BSTR_P(name), BSTR_P(param));
  324|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  325|      0|    }
  326|       |
  327|  52.2k|    long long min = OPT_INT_MIN(opt, long long, i_min);
  ------------------
  |  |   58|  52.2k|#define OPT_INT_MIN(opt, T, Tm) ((opt)->min < (opt)->max \
  |  |  ------------------
  |  |  |  Branch (58:34): [True: 5.81k, False: 46.4k]
  |  |  ------------------
  |  |   59|  52.2k|    ? ((opt)->min <= (double)(Tm) ? (Tm) : (T)((opt)->min)) : (Tm))
  |  |  ------------------
  |  |  |  Branch (59:8): [True: 0, False: 5.81k]
  |  |  ------------------
  ------------------
  328|  52.2k|    if (tmp_int < min) {
  ------------------
  |  Branch (328:9): [True: 0, False: 52.2k]
  ------------------
  329|      0|        mp_err(log, "The %.*s option must be >= %lld: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  330|      0|               BSTR_P(name), min, BSTR_P(param));
  331|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  332|      0|    }
  333|       |
  334|  52.2k|    long long max = OPT_INT_MAX(opt, long long, i_max);
  ------------------
  |  |   60|  52.2k|#define OPT_INT_MAX(opt, T, Tm) ((opt)->min < (opt)->max \
  |  |  ------------------
  |  |  |  Branch (60:34): [True: 5.81k, False: 46.4k]
  |  |  ------------------
  |  |   61|  52.2k|    ? ((opt)->max >= (double)(Tm) ? (Tm) : (T)((opt)->max)) : (Tm))
  |  |  ------------------
  |  |  |  Branch (61:8): [True: 5.81k, False: 0]
  |  |  ------------------
  ------------------
  335|  52.2k|    if (tmp_int > max) {
  ------------------
  |  Branch (335:9): [True: 0, False: 52.2k]
  ------------------
  336|      0|        mp_err(log, "The %.*s option must be <= %lld: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  337|      0|               BSTR_P(name), max, BSTR_P(param));
  338|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  339|      0|    }
  340|       |
  341|  52.2k|    if (dst)
  ------------------
  |  Branch (341:9): [True: 52.2k, False: 0]
  ------------------
  342|  52.2k|        *(long long *)dst = tmp_int;
  343|       |
  344|  52.2k|    return 1;
  345|  52.2k|}
m_option.c:print_int:
  376|  11.6k|{
  377|  11.6k|    if (opt->type->size == sizeof(int64_t))
  ------------------
  |  Branch (377:9): [True: 0, False: 11.6k]
  ------------------
  378|      0|        return talloc_asprintf(NULL, "%"PRId64, *(const int64_t *)val);
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  379|  11.6k|    return talloc_asprintf(NULL, "%d", *(const int *)val);
  ------------------
  |  |   52|  11.6k|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|  11.6k|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  380|  11.6k|}
m_option.c:int_equal:
  473|  35.9k|{
  474|  35.9k|    return *(int *)a == *(int *)b;
  475|  35.9k|}
m_option.c:parse_byte_size:
  512|  5.81k|{
  513|  5.81k|    if (param.len == 0)
  ------------------
  |  Branch (513:9): [True: 0, False: 5.81k]
  ------------------
  514|      0|        return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  515|       |
  516|  5.81k|    struct bstr r;
  517|  5.81k|    long long tmp_int = bstrtoll(param, &r, 0);
  518|  5.81k|    int64_t unit = 1;
  519|  5.81k|    if (r.len) {
  ------------------
  |  Branch (519:9): [True: 5.81k, False: 0]
  ------------------
  520|  5.81k|        if (bstrcasecmp0(r, "b") == 0) {
  ------------------
  |  Branch (520:13): [True: 0, False: 5.81k]
  ------------------
  521|      0|            unit = 1;
  522|  5.81k|        } else if (bstrcasecmp0(r, "kib") == 0 || bstrcasecmp0(r, "k") == 0) {
  ------------------
  |  Branch (522:20): [True: 0, False: 5.81k]
  |  Branch (522:51): [True: 5.81k, False: 0]
  ------------------
  523|  5.81k|            unit = 1024;
  524|  5.81k|        } else if (bstrcasecmp0(r, "mib") == 0 || bstrcasecmp0(r, "m") == 0) {
  ------------------
  |  Branch (524:20): [True: 0, False: 0]
  |  Branch (524:51): [True: 0, False: 0]
  ------------------
  525|      0|            unit = 1024 * 1024;
  526|      0|        } else if (bstrcasecmp0(r, "gib") == 0 || bstrcasecmp0(r, "g") == 0) {
  ------------------
  |  Branch (526:20): [True: 0, False: 0]
  |  Branch (526:51): [True: 0, False: 0]
  ------------------
  527|      0|            unit = 1024 * 1024 * 1024;
  528|      0|        } else if (bstrcasecmp0(r, "tib") == 0 || bstrcasecmp0(r, "t") == 0) {
  ------------------
  |  Branch (528:20): [True: 0, False: 0]
  |  Branch (528:51): [True: 0, False: 0]
  ------------------
  529|      0|            unit = 1024 * 1024 * 1024 * 1024LL;
  530|      0|        } else {
  531|      0|            mp_err(log, "The %.*s option must be an integer: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  532|      0|                   BSTR_P(name), BSTR_P(param));
  533|      0|            mp_err(log, "The following suffixes are also allowed: "
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  534|      0|                   "KiB, MiB, GiB, TiB, B, K, M, G, T.\n");
  535|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  536|      0|        }
  537|  5.81k|    }
  538|       |
  539|  5.81k|    if (tmp_int < 0) {
  ------------------
  |  Branch (539:9): [True: 0, False: 5.81k]
  ------------------
  540|      0|        mp_err(log, "The %.*s option does not support negative numbers: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  541|      0|               BSTR_P(name), BSTR_P(param));
  542|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  543|      0|    }
  544|       |
  545|  5.81k|    if (INT64_MAX / unit < tmp_int) {
  ------------------
  |  Branch (545:9): [True: 0, False: 5.81k]
  ------------------
  546|      0|        mp_err(log, "The %.*s option overflows: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  547|      0|               BSTR_P(name), BSTR_P(param));
  548|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  549|      0|    }
  550|       |
  551|  5.81k|    tmp_int *= unit;
  552|       |
  553|  5.81k|    int64_t min = OPT_INT_MIN(opt, int64_t, INT64_MIN);
  ------------------
  |  |   58|  5.81k|#define OPT_INT_MIN(opt, T, Tm) ((opt)->min < (opt)->max \
  |  |  ------------------
  |  |  |  Branch (58:34): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |   59|  5.81k|    ? ((opt)->min <= (double)(Tm) ? (Tm) : (T)((opt)->min)) : (Tm))
  |  |  ------------------
  |  |  |  Branch (59:8): [True: 0, False: 5.81k]
  |  |  ------------------
  ------------------
  554|  5.81k|    if (tmp_int < min) {
  ------------------
  |  Branch (554:9): [True: 0, False: 5.81k]
  ------------------
  555|      0|        mp_err(log, "The %.*s option must be >= %"PRId64": %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  556|      0|               BSTR_P(name), min, BSTR_P(param));
  557|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  558|      0|    }
  559|       |
  560|  5.81k|    int64_t max = OPT_INT_MAX(opt, int64_t, INT64_MAX);
  ------------------
  |  |   60|  5.81k|#define OPT_INT_MAX(opt, T, Tm) ((opt)->min < (opt)->max \
  |  |  ------------------
  |  |  |  Branch (60:34): [True: 5.81k, False: 0]
  |  |  ------------------
  |  |   61|  5.81k|    ? ((opt)->max >= (double)(Tm) ? (Tm) : (T)((opt)->max)) : (Tm))
  |  |  ------------------
  |  |  |  Branch (61:8): [True: 0, False: 5.81k]
  |  |  ------------------
  ------------------
  561|  5.81k|    if (tmp_int > max) {
  ------------------
  |  Branch (561:9): [True: 0, False: 5.81k]
  ------------------
  562|      0|        mp_err(log, "The %.*s option must be <= %"PRId64": %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  563|      0|               BSTR_P(name), max, BSTR_P(param));
  564|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  565|      0|    }
  566|       |
  567|  5.81k|    if (dst)
  ------------------
  |  Branch (567:9): [True: 5.81k, False: 0]
  ------------------
  568|  5.81k|        *(int64_t *)dst = tmp_int;
  569|       |
  570|  5.81k|    return 1;
  571|  5.81k|}
m_option.c:parse_choice:
  632|   116k|{
  633|   116k|    const struct m_opt_choice_alternatives *alt = opt->priv;
  634|   389k|    for ( ; alt->name; alt++) {
  ------------------
  |  Branch (634:13): [True: 389k, False: 0]
  ------------------
  635|   389k|        if (!bstrcmp0(param, alt->name))
  ------------------
  |  Branch (635:13): [True: 116k, False: 273k]
  ------------------
  636|   116k|            break;
  637|   389k|    }
  638|   116k|    if (!alt->name && param.len == 0) {
  ------------------
  |  Branch (638:9): [True: 0, False: 116k]
  |  Branch (638:23): [True: 0, False: 0]
  ------------------
  639|       |        // allow flag-style options, e.g. "--mute" implies "--mute=yes"
  640|      0|        for (alt = opt->priv; alt->name; alt++) {
  ------------------
  |  Branch (640:31): [True: 0, False: 0]
  ------------------
  641|      0|            if (!strcmp("yes", alt->name))
  ------------------
  |  Branch (641:17): [True: 0, False: 0]
  ------------------
  642|      0|                break;
  643|      0|        }
  644|      0|    }
  645|   116k|    if (!alt->name) {
  ------------------
  |  Branch (645:9): [True: 0, False: 116k]
  ------------------
  646|      0|        if (!bstrcmp0(param, "help")) {
  ------------------
  |  Branch (646:13): [True: 0, False: 0]
  ------------------
  647|      0|            mp_info(log, "Valid values for option %.*s are:\n", BSTR_P(name));
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (74:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  648|      0|            print_choice_values(log, opt);
  649|      0|            return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  650|      0|        }
  651|      0|        if (param.len == 0)
  ------------------
  |  Branch (651:13): [True: 0, False: 0]
  ------------------
  652|      0|            return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  653|      0|        if (opt->min < opt->max) {
  ------------------
  |  Branch (653:13): [True: 0, False: 0]
  ------------------
  654|      0|            long long val;
  655|      0|            if (parse_longlong(mp_null_log, opt, INT_MIN, INT_MAX, name, param,
  ------------------
  |  Branch (655:17): [True: 0, False: 0]
  ------------------
  656|      0|                               &val) == 1)
  657|      0|            {
  658|      0|                if (dst)
  ------------------
  |  Branch (658:21): [True: 0, False: 0]
  ------------------
  659|      0|                    *(int *)dst = val;
  660|      0|                return 1;
  661|      0|            }
  662|      0|        }
  663|      0|        mp_fatal(log, "Invalid value for option %.*s: %.*s\n",
  ------------------
  |  |   71|      0|#define mp_fatal(log, ...)      mp_msg(log, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  664|      0|                 BSTR_P(name), BSTR_P(param));
  665|      0|        mp_info(log, "Valid values are:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  666|      0|        print_choice_values(log, opt);
  667|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  668|      0|    }
  669|   116k|    if (dst)
  ------------------
  |  Branch (669:9): [True: 116k, False: 0]
  ------------------
  670|   116k|        *(int *)dst = alt->value;
  671|       |
  672|   116k|    return 1;
  673|   116k|}
m_option.c:print_choice:
  810|  5.81k|{
  811|  5.81k|    int ival = 0;
  812|  5.81k|    const struct m_opt_choice_alternatives *alt = get_choice(opt, val, &ival);
  813|  5.81k|    return alt ? talloc_strdup(NULL, alt->name)
  ------------------
  |  |   50|  5.81k|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (813:12): [True: 5.81k, False: 0]
  ------------------
  814|  5.81k|               : talloc_asprintf(NULL, "%d", ival);
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  ------------------
  ------------------
  815|  5.81k|}
m_option.c:get_choice:
  760|  5.81k|{
  761|  5.81k|    int v = *(int *)val;
  762|  5.81k|    const struct m_opt_choice_alternatives *alt;
  763|  5.81k|    for (alt = opt->priv; alt->name; alt++) {
  ------------------
  |  Branch (763:27): [True: 5.81k, False: 0]
  ------------------
  764|  5.81k|        if (alt->value == v)
  ------------------
  |  Branch (764:13): [True: 5.81k, False: 0]
  ------------------
  765|  5.81k|            return alt;
  766|  5.81k|    }
  767|      0|    if (opt->min < opt->max) {
  ------------------
  |  Branch (767:9): [True: 0, False: 0]
  ------------------
  768|      0|        if (v >= opt->min && v <= opt->max) {
  ------------------
  |  Branch (768:13): [True: 0, False: 0]
  |  Branch (768:30): [True: 0, False: 0]
  ------------------
  769|      0|            *out_val = v;
  770|      0|            return NULL;
  771|      0|        }
  772|      0|    }
  773|      0|    MP_ASSERT_UNREACHABLE();
  ------------------
  |  |   42|      0|#define MP_ASSERT_UNREACHABLE() (assert(!"unreachable"), __builtin_unreachable())
  ------------------
  774|      0|}
m_option.c:parse_flags:
  864|  52.2k|{
  865|  52.2k|    int value = 0;
  866|   104k|    while (param.len) {
  ------------------
  |  Branch (866:12): [True: 52.2k, False: 52.2k]
  ------------------
  867|  52.2k|        bstr flag;
  868|  52.2k|        bstr_split_tok(param, "+", &flag, &param);
  869|  52.2k|        int r = apply_flag(opt, &value, flag);
  870|  52.2k|        if (r == M_OPT_UNKNOWN) {
  ------------------
  |  |  517|  52.2k|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (870:13): [True: 0, False: 52.2k]
  ------------------
  871|      0|            mp_fatal(log, "Invalid flag for option %.*s: %.*s\n",
  ------------------
  |  |   71|      0|#define mp_fatal(log, ...)      mp_msg(log, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  872|      0|                     BSTR_P(name), BSTR_P(flag));
  873|      0|            mp_info(log, "Valid flags are:\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  874|      0|            const struct m_opt_choice_alternatives *alt;
  875|      0|            for (alt = opt->priv; alt->name; alt++)
  ------------------
  |  Branch (875:35): [True: 0, False: 0]
  ------------------
  876|      0|                mp_info(log, "    %s\n", alt->name);
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  877|      0|            mp_info(log, "Flags can usually be combined with '+'.\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  878|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  879|  52.2k|        } else if (r < 0) {
  ------------------
  |  Branch (879:20): [True: 0, False: 52.2k]
  ------------------
  880|      0|            mp_fatal(log, "Option %.*s: flag '%.*s' conflicts with a previous "
  ------------------
  |  |   71|      0|#define mp_fatal(log, ...)      mp_msg(log, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  |  Branch (71:57): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  881|      0|                     "flag value.\n", BSTR_P(name), BSTR_P(flag));
  882|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  883|      0|        }
  884|  52.2k|    }
  885|  52.2k|    if (dst)
  ------------------
  |  Branch (885:9): [True: 52.2k, False: 0]
  ------------------
  886|  52.2k|        *(int *)dst = value;
  887|  52.2k|    return 1;
  888|  52.2k|}
m_option.c:apply_flag:
  831|  52.2k|{
  832|  52.2k|    const struct m_opt_choice_alternatives *alt;
  833|   244k|    for (alt = opt->priv; alt->name; alt++) {
  ------------------
  |  Branch (833:27): [True: 244k, False: 0]
  ------------------
  834|   244k|        if (bstr_equals0(flag, alt->name)) {
  ------------------
  |  Branch (834:13): [True: 52.2k, False: 191k]
  ------------------
  835|  52.2k|            if (*val & alt->value)
  ------------------
  |  Branch (835:17): [True: 0, False: 52.2k]
  ------------------
  836|      0|                return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  837|  52.2k|            *val |= alt->value;
  838|  52.2k|            return 0;
  839|  52.2k|        }
  840|   244k|    }
  841|      0|    return M_OPT_UNKNOWN;
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  842|  52.2k|}
m_option.c:parse_double:
  983|   534k|{
  984|   534k|    if (param.len == 0)
  ------------------
  |  Branch (984:9): [True: 0, False: 534k]
  ------------------
  985|      0|        return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  986|       |
  987|   534k|    struct bstr rest;
  988|   534k|    double tmp_float = bstrtod(param, &rest);
  989|       |
  990|   534k|    if (bstr_eatstart0(&rest, ":") || bstr_eatstart0(&rest, "/"))
  ------------------
  |  Branch (990:9): [True: 0, False: 534k]
  |  Branch (990:39): [True: 5.81k, False: 528k]
  ------------------
  991|  5.81k|        tmp_float /= bstrtod(rest, &rest);
  992|       |
  993|   534k|    if ((opt->flags & M_OPT_DEFAULT_NAN) && bstr_equals0(param, "default")) {
  ------------------
  |  |  471|   534k|#define M_OPT_DEFAULT_NAN       (UINT64_C(1) << 58)
  ------------------
  |  Branch (993:9): [True: 0, False: 534k]
  |  Branch (993:45): [True: 0, False: 0]
  ------------------
  994|      0|        tmp_float = NAN;
  995|      0|        goto done;
  996|      0|    }
  997|       |
  998|   534k|    if (rest.len) {
  ------------------
  |  Branch (998:9): [True: 0, False: 534k]
  ------------------
  999|      0|        mp_err(log, "The %.*s option must be a floating point number or a "
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1000|      0|               "ratio (numerator[:/]denominator): %.*s\n",
 1001|      0|               BSTR_P(name), BSTR_P(param));
 1002|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1003|      0|    }
 1004|       |
 1005|   534k|    if (clamp_double(opt, &tmp_float) < 0) {
  ------------------
  |  Branch (1005:9): [True: 0, False: 534k]
  ------------------
 1006|      0|        mp_err(log, "The %.*s option is out of range: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1007|      0|               BSTR_P(name), BSTR_P(param));
 1008|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
 1009|      0|    }
 1010|       |
 1011|   534k|done:
 1012|   534k|    if (dst)
  ------------------
  |  Branch (1012:9): [True: 534k, False: 0]
  ------------------
 1013|   534k|        VAL(dst) = tmp_float;
  ------------------
  |  |  956|   534k|#define VAL(x) (*(double *)(x))
  ------------------
 1014|   534k|    return 1;
 1015|   534k|}
m_option.c:clamp_double:
  959|   575k|{
  960|   575k|    double v = VAL(val);
  ------------------
  |  |  956|   575k|#define VAL(x) (*(double *)(x))
  ------------------
  961|   575k|    int r = 0;
  962|   575k|    if (opt->min < opt->max) {
  ------------------
  |  Branch (962:9): [True: 46.4k, False: 528k]
  ------------------
  963|  46.4k|        if (v > opt->max) {
  ------------------
  |  Branch (963:13): [True: 0, False: 46.4k]
  ------------------
  964|      0|            v = opt->max;
  965|      0|            r = M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  966|      0|        }
  967|  46.4k|        if (v < opt->min) {
  ------------------
  |  Branch (967:13): [True: 0, False: 46.4k]
  ------------------
  968|      0|            v = opt->min;
  969|      0|            r = M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  970|      0|        }
  971|  46.4k|    }
  972|       |    // (setting max/min to INFINITY/-INFINITY is allowed)
  973|   575k|    if (!isfinite(v) && v != opt->max && v != opt->min) {
  ------------------
  |  Branch (973:9): [True: 0, False: 575k]
  |  Branch (973:25): [True: 0, False: 0]
  |  Branch (973:42): [True: 0, False: 0]
  ------------------
  974|      0|        v = opt->min;
  975|      0|        r = M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  976|      0|    }
  977|   575k|    VAL(val) = v;
  ------------------
  |  |  956|   575k|#define VAL(x) (*(double *)(x))
  ------------------
  978|   575k|    return r;
  979|   575k|}
m_option.c:double_equal:
 1088|  5.81k|{
 1089|  5.81k|    double fa = VAL(a), fb = VAL(b);
  ------------------
  |  |  956|  5.81k|#define VAL(x) (*(double *)(x))
  ------------------
                  double fa = VAL(a), fb = VAL(b);
  ------------------
  |  |  956|  5.81k|#define VAL(x) (*(double *)(x))
  ------------------
 1090|  5.81k|    if (isnan(fa) || isnan(fb))
 1091|      0|        return isnan(fa) == isnan(fb);
 1092|  5.81k|    return fa == fb;
 1093|  5.81k|}
m_option.c:parse_float:
 1160|  40.6k|{
 1161|  40.6k|    double tmp;
 1162|  40.6k|    int r = parse_double(log, opt, name, param, &tmp);
 1163|       |
 1164|  40.6k|    if (r == 1 && clamp_float(opt, &tmp) < 0) {
  ------------------
  |  Branch (1164:9): [True: 40.6k, False: 0]
  |  Branch (1164:19): [True: 0, False: 40.6k]
  ------------------
 1165|      0|        mp_err(log, "The %.*s option is out of range: %.*s\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1166|      0|               BSTR_P(name), BSTR_P(param));
 1167|      0|        return M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
 1168|      0|    }
 1169|       |
 1170|  40.6k|    if (r == 1 && dst)
  ------------------
  |  Branch (1170:9): [True: 40.6k, False: 0]
  |  Branch (1170:19): [True: 40.6k, False: 0]
  ------------------
 1171|  40.6k|        VAL(dst) = tmp;
  ------------------
  |  | 1138|  40.6k|#define VAL(x) (*(float *)(x))
  ------------------
 1172|  40.6k|    return r;
 1173|  40.6k|}
m_option.c:clamp_float:
 1141|  40.6k|{
 1142|  40.6k|    double v = *val;
 1143|  40.6k|    int r = clamp_double(opt, &v);
 1144|       |    // Handle the case where range is not set and v is finite
 1145|       |    // but overflows the float range.
 1146|  40.6k|    if (isfinite(v) && v > FLT_MAX) {
  ------------------
  |  Branch (1146:24): [True: 0, False: 40.6k]
  ------------------
 1147|      0|        v = FLT_MAX;
 1148|      0|        r = M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
 1149|      0|    }
 1150|  40.6k|    if (isfinite(v) && v < -FLT_MAX) {
  ------------------
  |  Branch (1150:24): [True: 0, False: 40.6k]
  ------------------
 1151|      0|        v = -FLT_MAX;
 1152|      0|        r = M_OPT_OUT_OF_RANGE;
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
 1153|      0|    }
 1154|  40.6k|    *val = v;
 1155|  40.6k|    return r;
 1156|  40.6k|}
m_option.c:parse_str:
 1249|  1.16M|{
 1250|  1.16M|    if (dst) {
  ------------------
  |  Branch (1250:9): [True: 1.16M, False: 0]
  ------------------
 1251|  1.16M|        talloc_free(VAL(dst));
  ------------------
  |  |   47|  1.16M|#define talloc_free                     ta_free
  ------------------
                      talloc_free(VAL(dst));
  ------------------
  |  | 1245|  1.16M|#define VAL(x) (*(char **)(x))
  ------------------
 1252|  1.16M|        VAL(dst) = bstrdup0(NULL, param);
  ------------------
  |  | 1245|  1.16M|#define VAL(x) (*(char **)(x))
  ------------------
 1253|  1.16M|    }
 1254|       |
 1255|  1.16M|    return 0;
 1256|  1.16M|}
m_option.c:print_str:
 1259|   237k|{
 1260|   237k|    return talloc_strdup(NULL, VAL(val) ? VAL(val) : "");
  ------------------
  |  |   50|   237k|#define talloc_strdup                   ta_xstrdup
  ------------------
                  return talloc_strdup(NULL, VAL(val) ? VAL(val) : "");
  ------------------
  |  | 1245|   237k|#define VAL(x) (*(char **)(x))
  |  |  ------------------
  |  |  |  Branch (1245:16): [True: 237k, False: 0]
  |  |  ------------------
  ------------------
                  return talloc_strdup(NULL, VAL(val) ? VAL(val) : "");
  ------------------
  |  | 1245|   237k|#define VAL(x) (*(char **)(x))
  ------------------
 1261|   237k|}
m_option.c:copy_str:
 1264|  5.54M|{
 1265|  5.54M|    if (dst && src)
  ------------------
  |  Branch (1265:9): [True: 5.54M, False: 0]
  |  Branch (1265:16): [True: 5.54M, False: 0]
  ------------------
 1266|  5.54M|        talloc_replace(NULL, VAL(dst), VAL(src));
  ------------------
  |  |   54|  5.54M|#define talloc_replace                  ta_replace
  |  |  ------------------
  |  |  |  |  106|  5.54M|    do {                                                \
  |  |  |  |  107|  5.54M|        if (!(str)) {                                   \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (107:13): [True: 5.54M, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  108|  5.54M|            (str) = ta_xstrdup((ta_parent), (replace)); \
  |  |  |  |  109|  5.54M|        } else {                                        \
  |  |  |  |  110|      0|            *(str) = '\0';                              \
  |  |  |  |  111|      0|            ta_xstrdup_append(&(str), (replace));       \
  |  |  |  |  ------------------
  |  |  |  |  |  |  123|      0|#define ta_xstrdup_append(...)          ta_oom_b(ta_strdup_append(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  112|      0|        }                                               \
  |  |  |  |  113|  5.54M|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1267|  5.54M|}
m_option.c:free_str:
 1294|  6.93M|{
 1295|  6.93M|    if (src && VAL(src)) {
  ------------------
  |  | 1245|  6.93M|#define VAL(x) (*(char **)(x))
  |  |  ------------------
  |  |  |  Branch (1245:16): [True: 2.98M, False: 3.94M]
  |  |  ------------------
  ------------------
  |  Branch (1295:9): [True: 6.93M, False: 0]
  ------------------
 1296|  2.98M|        talloc_free(VAL(src));
  ------------------
  |  |   47|  2.98M|#define talloc_free                     ta_free
  ------------------
                      talloc_free(VAL(src));
  ------------------
  |  | 1245|  2.98M|#define VAL(x) (*(char **)(x))
  ------------------
 1297|  2.98M|        VAL(src) = NULL;
  ------------------
  |  | 1245|  2.98M|#define VAL(x) (*(char **)(x))
  ------------------
 1298|  2.98M|    }
 1299|  6.93M|}
m_option.c:str_equal:
 1289|  5.81k|{
 1290|  5.81k|    return bstr_equals(bstr0(VAL(a)), bstr0(VAL(b)));
  ------------------
  |  | 1245|  5.81k|#define VAL(x) (*(char **)(x))
  ------------------
                  return bstr_equals(bstr0(VAL(a)), bstr0(VAL(b)));
  ------------------
  |  | 1245|  5.81k|#define VAL(x) (*(char **)(x))
  ------------------
 1291|  5.81k|}
m_option.c:parse_str_list:
 1626|  17.4k|{
 1627|  17.4k|    return parse_str_list_impl(log, opt, name, param, dst, OP_NONE);
  ------------------
  |  | 1318|  17.4k|#define OP_NONE 0
  ------------------
 1628|  17.4k|}
m_option.c:parse_str_list_impl:
 1471|  17.4k|{
 1472|  17.4k|    char **res;
 1473|  17.4k|    int op = default_op;
 1474|       |
 1475|  17.4k|    if (bstr_endswith0(name, "-add")) {
  ------------------
  |  Branch (1475:9): [True: 0, False: 17.4k]
  ------------------
 1476|      0|        op = OP_ADD;
  ------------------
  |  | 1319|      0|#define OP_ADD 1
  ------------------
 1477|  17.4k|    } else if (bstr_endswith0(name, "-append")) {
  ------------------
  |  Branch (1477:16): [True: 0, False: 17.4k]
  ------------------
 1478|      0|        op = OP_APPEND;
  ------------------
  |  | 1324|      0|#define OP_APPEND 6
  ------------------
 1479|  17.4k|    } else if (bstr_endswith0(name, "-pre")) {
  ------------------
  |  Branch (1479:16): [True: 0, False: 17.4k]
  ------------------
 1480|      0|        op = OP_PRE;
  ------------------
  |  | 1320|      0|#define OP_PRE 2
  ------------------
 1481|  17.4k|    } else if (bstr_endswith0(name, "-clr")) {
  ------------------
  |  Branch (1481:16): [True: 0, False: 17.4k]
  ------------------
 1482|      0|        op = OP_CLR;
  ------------------
  |  | 1321|      0|#define OP_CLR 3
  ------------------
 1483|  17.4k|    } else if (bstr_endswith0(name, "-del")) {
  ------------------
  |  Branch (1483:16): [True: 0, False: 17.4k]
  ------------------
 1484|      0|        op = OP_DEL;
  ------------------
  |  | 1322|      0|#define OP_DEL 4
  ------------------
 1485|  17.4k|    } else if (bstr_endswith0(name, "-set")) {
  ------------------
  |  Branch (1485:16): [True: 0, False: 17.4k]
  ------------------
 1486|      0|        op = OP_NONE;
  ------------------
  |  | 1318|      0|#define OP_NONE 0
  ------------------
 1487|  17.4k|    } else if (bstr_endswith0(name, "-toggle")) {
  ------------------
  |  Branch (1487:16): [True: 0, False: 17.4k]
  ------------------
 1488|      0|        op = OP_TOGGLE;
  ------------------
  |  | 1323|      0|#define OP_TOGGLE 5
  ------------------
 1489|  17.4k|    } else if (bstr_endswith0(name, "-remove")) {
  ------------------
  |  Branch (1489:16): [True: 0, False: 17.4k]
  ------------------
 1490|      0|        op = OP_REMOVE;
  ------------------
  |  | 1325|      0|#define OP_REMOVE 7
  ------------------
 1491|      0|    }
 1492|       |
 1493|  17.4k|    if (op == OP_TOGGLE || op == OP_REMOVE) {
  ------------------
  |  | 1323|  34.8k|#define OP_TOGGLE 5
  ------------------
                  if (op == OP_TOGGLE || op == OP_REMOVE) {
  ------------------
  |  | 1325|  17.4k|#define OP_REMOVE 7
  ------------------
  |  Branch (1493:9): [True: 0, False: 17.4k]
  |  Branch (1493:28): [True: 0, False: 17.4k]
  ------------------
 1494|      0|        if (dst) {
  ------------------
  |  Branch (1494:13): [True: 0, False: 0]
  ------------------
 1495|      0|            res = talloc_array(NULL, char *, 2);
  ------------------
  |  |   29|      0|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|      0|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1496|      0|            res[0] = bstrdup0(res, param);
 1497|      0|            res[1] = NULL;
 1498|      0|            bool found = str_list_remove(res, 2, dst);
 1499|      0|            if (found)
  ------------------
  |  Branch (1499:17): [True: 0, False: 0]
  ------------------
 1500|      0|                return 1;
 1501|      0|        }
 1502|      0|        if (op == OP_REMOVE)
  ------------------
  |  | 1325|      0|#define OP_REMOVE 7
  ------------------
  |  Branch (1502:13): [True: 0, False: 0]
  ------------------
 1503|      0|            return 1; // ignore if not found
 1504|      0|        op = OP_APPEND;
  ------------------
  |  | 1324|      0|#define OP_APPEND 6
  ------------------
 1505|      0|    }
 1506|       |
 1507|       |    // Clear the list ??
 1508|  17.4k|    if (op == OP_CLR) {
  ------------------
  |  | 1321|  17.4k|#define OP_CLR 3
  ------------------
  |  Branch (1508:9): [True: 0, False: 17.4k]
  ------------------
 1509|      0|        if (dst)
  ------------------
  |  Branch (1509:13): [True: 0, False: 0]
  ------------------
 1510|      0|            free_str_list(dst);
 1511|      0|        return 0;
 1512|      0|    }
 1513|       |
 1514|       |    // All other ops need a param
 1515|  17.4k|    if (param.len == 0 && op != OP_NONE)
  ------------------
  |  | 1318|      0|#define OP_NONE 0
  ------------------
  |  Branch (1515:9): [True: 0, False: 17.4k]
  |  Branch (1515:27): [True: 0, False: 0]
  ------------------
 1516|      0|        return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
 1517|       |
 1518|  17.4k|    if (!dst)
  ------------------
  |  Branch (1518:9): [True: 0, False: 17.4k]
  ------------------
 1519|      0|        return 1;
 1520|       |
 1521|  17.4k|    int n = 0;
 1522|  17.4k|    res = separate_input_param(opt, param, &n, op);
 1523|  17.4k|    if (!res)
  ------------------
  |  Branch (1523:9): [True: 0, False: 17.4k]
  ------------------
 1524|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1525|       |
 1526|  17.4k|    switch (op) {
  ------------------
  |  Branch (1526:13): [True: 17.4k, False: 0]
  ------------------
 1527|      0|    case OP_ADD:
  ------------------
  |  | 1319|      0|#define OP_ADD 1
  ------------------
  |  Branch (1527:5): [True: 0, False: 17.4k]
  ------------------
 1528|      0|    case OP_APPEND:
  ------------------
  |  | 1324|      0|#define OP_APPEND 6
  ------------------
  |  Branch (1528:5): [True: 0, False: 17.4k]
  ------------------
 1529|      0|        return str_list_add(res, n, dst, 0);
 1530|      0|    case OP_PRE:
  ------------------
  |  | 1320|      0|#define OP_PRE 2
  ------------------
  |  Branch (1530:5): [True: 0, False: 17.4k]
  ------------------
 1531|      0|        return str_list_add(res, n, dst, 1);
 1532|      0|    case OP_DEL:
  ------------------
  |  | 1322|      0|#define OP_DEL 4
  ------------------
  |  Branch (1532:5): [True: 0, False: 17.4k]
  ------------------
 1533|      0|        return str_list_remove(res, n, dst);
 1534|  17.4k|    }
 1535|       |
 1536|  17.4k|    if (VAL(dst))
  ------------------
  |  | 1316|  17.4k|#define VAL(x) (*(char ***)(x))
  |  |  ------------------
  |  |  |  Branch (1316:16): [True: 0, False: 17.4k]
  |  |  ------------------
  ------------------
 1537|      0|        free_str_list(dst);
 1538|  17.4k|    VAL(dst) = res;
  ------------------
  |  | 1316|  17.4k|#define VAL(x) (*(char ***)(x))
  ------------------
 1539|       |
 1540|  17.4k|    if (!res[0])
  ------------------
  |  Branch (1540:9): [True: 0, False: 17.4k]
  ------------------
 1541|      0|        free_str_list(dst);
 1542|       |
 1543|  17.4k|    return 1;
 1544|  17.4k|}
m_option.c:separate_input_param:
 1409|  17.4k|{
 1410|  17.4k|    char separator = opt->priv ? *(char *)opt->priv : OPTION_LIST_SEPARATOR;
  ------------------
  |  |  632|  34.8k|#define OPTION_LIST_SEPARATOR ','
  ------------------
  |  Branch (1410:22): [True: 0, False: 17.4k]
  ------------------
 1411|  17.4k|    if (op == OP_APPEND || op == OP_REMOVE)
  ------------------
  |  | 1324|  34.8k|#define OP_APPEND 6
  ------------------
                  if (op == OP_APPEND || op == OP_REMOVE)
  ------------------
  |  | 1325|  17.4k|#define OP_REMOVE 7
  ------------------
  |  Branch (1411:9): [True: 0, False: 17.4k]
  |  Branch (1411:28): [True: 0, False: 17.4k]
  ------------------
 1412|      0|        separator = 0; // specially handled
 1413|  17.4k|    struct bstr str = param;
 1414|  17.4k|    int n = *len;
 1415|  34.8k|    while (str.len) {
  ------------------
  |  Branch (1415:12): [True: 17.4k, False: 17.4k]
  ------------------
 1416|  17.4k|        get_nextsep(&str, separator, 0);
 1417|  17.4k|        str = bstr_cut(str, 1);
 1418|  17.4k|        n++;
 1419|  17.4k|    }
 1420|  17.4k|    if (n == 0 && op != OP_NONE)
  ------------------
  |  | 1318|      0|#define OP_NONE 0
  ------------------
  |  Branch (1420:9): [True: 0, False: 17.4k]
  |  Branch (1420:19): [True: 0, False: 0]
  ------------------
 1421|      0|        return NULL;
 1422|       |
 1423|  17.4k|    char **list = talloc_array(NULL, char *, n + 2);
  ------------------
  |  |   29|  17.4k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  17.4k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  17.4k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1424|  17.4k|    str = bstrdup(NULL, param);
 1425|  17.4k|    char *ptr = str.start;
 1426|  17.4k|    n = 0;
 1427|       |
 1428|  17.4k|    while (1) {
  ------------------
  |  Branch (1428:12): [Folded - Ignored]
  ------------------
 1429|  17.4k|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 1430|  17.4k|        if (n >= 100)
  ------------------
  |  Branch (1430:13): [True: 0, False: 17.4k]
  ------------------
 1431|      0|            break;
 1432|  17.4k|#endif
 1433|  17.4k|        struct bstr el = get_nextsep(&str, separator, 1);
 1434|  17.4k|        list[n] = bstrdup0(NULL, el);
 1435|  17.4k|        n++;
 1436|  17.4k|        if (!str.len)
  ------------------
  |  Branch (1436:13): [True: 17.4k, False: 0]
  ------------------
 1437|  17.4k|            break;
 1438|      0|        str = bstr_cut(str, 1);
 1439|      0|    }
 1440|  17.4k|    list[n] = NULL;
 1441|  17.4k|    *len = n;
 1442|  17.4k|    talloc_free(ptr);
  ------------------
  |  |   47|  17.4k|#define talloc_free                     ta_free
  ------------------
 1443|  17.4k|    return list;
 1444|  17.4k|}
m_option.c:get_nextsep:
 1377|  34.8k|{
 1378|  34.8k|    struct bstr str = *ptr;
 1379|  34.8k|    struct bstr orig = str;
 1380|  34.8k|    for (;;) {
 1381|  34.8k|        int idx = sep ? bstrchr(str, sep) : -1;
  ------------------
  |  Branch (1381:19): [True: 34.8k, False: 0]
  ------------------
 1382|  34.8k|        if (idx > 0 && str.start[idx - 1] == '\\') {
  ------------------
  |  Branch (1382:13): [True: 0, False: 34.8k]
  |  Branch (1382:24): [True: 0, False: 0]
  ------------------
 1383|      0|            if (modify) {
  ------------------
  |  Branch (1383:17): [True: 0, False: 0]
  ------------------
 1384|      0|                memmove(str.start + idx - 1, str.start + idx, str.len - idx);
 1385|      0|                str.len--;
 1386|      0|                str = bstr_cut(str, idx);
 1387|      0|            } else
 1388|      0|                str = bstr_cut(str, idx + 1);
 1389|  34.8k|        } else {
 1390|  34.8k|            str = bstr_cut(str, idx < 0 ? str.len : idx);
  ------------------
  |  Branch (1390:33): [True: 34.8k, False: 0]
  ------------------
 1391|  34.8k|            break;
 1392|  34.8k|        }
 1393|  34.8k|    }
 1394|  34.8k|    *ptr = str;
 1395|  34.8k|    return bstr_splice(orig, 0, str.start - orig.start);
 1396|  34.8k|}
m_option.c:copy_str_list:
 1547|  2.90M|{
 1548|  2.90M|    int n;
 1549|  2.90M|    char **d, **s;
 1550|       |
 1551|  2.90M|    if (!(dst && src))
  ------------------
  |  Branch (1551:11): [True: 2.90M, False: 0]
  |  Branch (1551:18): [True: 2.90M, False: 0]
  ------------------
 1552|      0|        return;
 1553|  2.90M|    s = VAL(src);
  ------------------
  |  | 1316|  2.90M|#define VAL(x) (*(char ***)(x))
  ------------------
 1554|       |
 1555|  2.90M|    if (VAL(dst))
  ------------------
  |  | 1316|  2.90M|#define VAL(x) (*(char ***)(x))
  |  |  ------------------
  |  |  |  Branch (1316:16): [True: 0, False: 2.90M]
  |  |  ------------------
  ------------------
 1556|      0|        free_str_list(dst);
 1557|       |
 1558|  2.90M|    if (!s) {
  ------------------
  |  Branch (1558:9): [True: 2.07M, False: 827k]
  ------------------
 1559|  2.07M|        VAL(dst) = NULL;
  ------------------
  |  | 1316|  2.07M|#define VAL(x) (*(char ***)(x))
  ------------------
 1560|  2.07M|        return;
 1561|  2.07M|    }
 1562|       |
 1563|  10.6M|    for (n = 0; s[n] != NULL; n++)
  ------------------
  |  Branch (1563:17): [True: 9.81M, False: 827k]
  ------------------
 1564|  9.81M|        /* NOTHING */;
 1565|   827k|    d = talloc_array(NULL, char *, n + 1);
  ------------------
  |  |   29|   827k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|   827k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   827k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1566|  11.4M|    for (; n >= 0; n--)
  ------------------
  |  Branch (1566:12): [True: 10.6M, False: 827k]
  ------------------
 1567|  10.6M|        d[n] = talloc_strdup(NULL, s[n]);
  ------------------
  |  |   50|  10.6M|#define talloc_strdup                   ta_xstrdup
  ------------------
 1568|       |
 1569|   827k|    VAL(dst) = d;
  ------------------
  |  | 1316|   827k|#define VAL(x) (*(char ***)(x))
  ------------------
 1570|   827k|}
m_option.c:free_str_list:
 1328|  2.97M|{
 1329|  2.97M|    char **d;
 1330|  2.97M|    int i;
 1331|       |
 1332|  2.97M|    if (!dst || !VAL(dst))
  ------------------
  |  | 1316|  2.97M|#define VAL(x) (*(char ***)(x))
  ------------------
  |  Branch (1332:9): [True: 0, False: 2.97M]
  |  Branch (1332:17): [True: 2.09M, False: 874k]
  ------------------
 1333|  2.09M|        return;
 1334|   874k|    d = VAL(dst);
  ------------------
  |  | 1316|   874k|#define VAL(x) (*(char ***)(x))
  ------------------
 1335|       |
 1336|  10.7M|    for (i = 0; d[i] != NULL; i++)
  ------------------
  |  Branch (1336:17): [True: 9.89M, False: 874k]
  ------------------
 1337|  9.89M|        talloc_free(d[i]);
  ------------------
  |  |   47|  9.89M|#define talloc_free                     ta_free
  ------------------
 1338|   874k|    talloc_free(d);
  ------------------
  |  |   47|   874k|#define talloc_free                     ta_free
  ------------------
 1339|   874k|    VAL(dst) = NULL;
  ------------------
  |  | 1316|   874k|#define VAL(x) (*(char ***)(x))
  ------------------
 1340|   874k|}
m_option.c:str_list_equal:
 1631|  5.81k|{
 1632|  5.81k|    char **la = VAL(a);
  ------------------
  |  | 1316|  5.81k|#define VAL(x) (*(char ***)(x))
  ------------------
 1633|  5.81k|    char **lb = VAL(b);
  ------------------
  |  | 1316|  5.81k|#define VAL(x) (*(char ***)(x))
  ------------------
 1634|       |
 1635|  5.81k|    bool a_empty = !la || !la[0];
  ------------------
  |  Branch (1635:20): [True: 5.81k, False: 0]
  |  Branch (1635:27): [True: 0, False: 0]
  ------------------
 1636|  5.81k|    bool b_empty = !lb || !lb[0];
  ------------------
  |  Branch (1636:20): [True: 0, False: 5.81k]
  |  Branch (1636:27): [True: 0, False: 5.81k]
  ------------------
 1637|  5.81k|    if (a_empty || b_empty)
  ------------------
  |  Branch (1637:9): [True: 5.81k, False: 0]
  |  Branch (1637:20): [True: 0, False: 0]
  ------------------
 1638|  5.81k|        return a_empty == b_empty;
 1639|       |
 1640|      0|    for (int n = 0; la[n] || lb[n]; n++) {
  ------------------
  |  Branch (1640:21): [True: 0, False: 0]
  |  Branch (1640:30): [True: 0, False: 0]
  ------------------
 1641|      0|        if (!la[n] || !lb[n])
  ------------------
  |  Branch (1641:13): [True: 0, False: 0]
  |  Branch (1641:23): [True: 0, False: 0]
  ------------------
 1642|      0|            return false;
 1643|      0|        if (strcmp(la[n], lb[n]) != 0)
  ------------------
  |  Branch (1643:13): [True: 0, False: 0]
  ------------------
 1644|      0|            return false;
 1645|      0|    }
 1646|       |
 1647|      0|    return true;
 1648|      0|}
m_option.c:parse_keyvalue_list:
 1700|  29.0k|{
 1701|  29.0k|    char **lst = NULL;
 1702|  29.0k|    int num = 0;
 1703|  29.0k|    int r = 0;
 1704|  29.0k|    bool append = false;
 1705|  29.0k|    bool full_value = false;
 1706|       |
 1707|  29.0k|    if ((opt->flags & M_OPT_HAVE_HELP) && bstr_equals0(param, "help"))
  ------------------
  |  |  468|  29.0k|#define M_OPT_HAVE_HELP         (UINT64_C(1) << 59)
  ------------------
  |  Branch (1707:9): [True: 0, False: 29.0k]
  |  Branch (1707:43): [True: 0, False: 0]
  ------------------
 1708|      0|        param = bstr0("help=");
 1709|       |
 1710|  29.0k|    int op = 0;
 1711|  29.0k|    if (bstr_endswith0(name, "-del")) {
  ------------------
  |  Branch (1711:9): [True: 0, False: 29.0k]
  ------------------
 1712|      0|        op = OP_DEL;
  ------------------
  |  | 1322|      0|#define OP_DEL 4
  ------------------
 1713|  29.0k|    } else if (bstr_endswith0(name, "-remove")) {
  ------------------
  |  Branch (1713:16): [True: 0, False: 29.0k]
  ------------------
 1714|      0|        op = OP_REMOVE;
  ------------------
  |  | 1325|      0|#define OP_REMOVE 7
  ------------------
 1715|      0|    }
 1716|       |
 1717|  29.0k|    if (bstr_endswith0(name, "-add")) {
  ------------------
  |  Branch (1717:9): [True: 5.81k, False: 23.2k]
  ------------------
 1718|  5.81k|        append = true;
 1719|  23.2k|    } else if (bstr_endswith0(name, "-append")) {
  ------------------
  |  Branch (1719:16): [True: 17.4k, False: 5.81k]
  ------------------
 1720|  17.4k|        append = full_value = true;
 1721|  17.4k|    } else if (bstr_endswith0(name, "-clr")) {
  ------------------
  |  Branch (1721:16): [True: 0, False: 5.81k]
  ------------------
 1722|      0|        if (dst)
  ------------------
  |  Branch (1722:13): [True: 0, False: 0]
  ------------------
 1723|      0|            free_str_list(dst);
 1724|      0|        return 0;
 1725|  5.81k|    } else if (op == OP_DEL || op == OP_REMOVE) {
  ------------------
  |  | 1322|  11.6k|#define OP_DEL 4
  ------------------
                  } else if (op == OP_DEL || op == OP_REMOVE) {
  ------------------
  |  | 1325|  5.81k|#define OP_REMOVE 7
  ------------------
  |  Branch (1725:16): [True: 0, False: 5.81k]
  |  Branch (1725:32): [True: 0, False: 5.81k]
  ------------------
 1726|      0|        int n = 0;
 1727|      0|        char **res = separate_input_param(opt, param, &n, op);
 1728|      0|        if (!res)
  ------------------
  |  Branch (1728:13): [True: 0, False: 0]
  ------------------
 1729|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1730|      0|        lst = dst ? VAL(dst) : NULL;
  ------------------
  |  | 1316|      0|#define VAL(x) (*(char ***)(x))
  ------------------
  |  Branch (1730:15): [True: 0, False: 0]
  ------------------
 1731|      0|        for (int i = 0; i < n; i++) {
  ------------------
  |  Branch (1731:25): [True: 0, False: 0]
  ------------------
 1732|      0|            int index = dst ? keyvalue_list_find_key(lst, bstr0(res[i])) : -1;
  ------------------
  |  Branch (1732:25): [True: 0, False: 0]
  ------------------
 1733|      0|            if (index >= 0) {
  ------------------
  |  Branch (1733:17): [True: 0, False: 0]
  ------------------
 1734|      0|                keyvalue_list_del_key(lst, index);
 1735|      0|                VAL(dst) = lst;
  ------------------
  |  | 1316|      0|#define VAL(x) (*(char ***)(x))
  ------------------
 1736|      0|            }
 1737|      0|            talloc_free(res[i]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1738|      0|        }
 1739|      0|        talloc_free(res);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1740|      0|        return 1;
 1741|      0|    }
 1742|       |
 1743|  29.0k|    if (append && dst) {
  ------------------
  |  Branch (1743:9): [True: 23.2k, False: 5.81k]
  |  Branch (1743:19): [True: 23.2k, False: 0]
  ------------------
 1744|  23.2k|        lst = VAL(dst);
  ------------------
  |  | 1316|  23.2k|#define VAL(x) (*(char ***)(x))
  ------------------
 1745|  23.2k|        for (int n = 0; lst && lst[n]; n++)
  ------------------
  |  Branch (1745:25): [True: 0, False: 23.2k]
  |  Branch (1745:32): [True: 0, False: 0]
  ------------------
 1746|      0|            num++;
 1747|  23.2k|    }
 1748|       |
 1749|  29.0k|    while (param.len) {
  ------------------
  |  Branch (1749:12): [True: 29.0k, False: 0]
  ------------------
 1750|  29.0k|        bstr key, val;
 1751|  29.0k|        r = read_subparam(log, name, "=", &param, &key);
 1752|  29.0k|        if (r < 0)
  ------------------
  |  Branch (1752:13): [True: 0, False: 29.0k]
  ------------------
 1753|      0|            break;
 1754|  29.0k|        if (!bstr_eatstart0(&param, "=")) {
  ------------------
  |  Branch (1754:13): [True: 0, False: 29.0k]
  ------------------
 1755|      0|            mp_err(log, "Expected '=' and a value.\n");
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
 1756|      0|            r = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1757|      0|            break;
 1758|      0|        }
 1759|  29.0k|        if (full_value) {
  ------------------
  |  Branch (1759:13): [True: 17.4k, False: 11.6k]
  ------------------
 1760|  17.4k|            val = param;
 1761|  17.4k|            param.len = 0;
 1762|  17.4k|        } else {
 1763|  11.6k|            r = read_subparam(log, name, ",", &param, &val);
 1764|  11.6k|            if (r < 0)
  ------------------
  |  Branch (1764:17): [True: 0, False: 11.6k]
  ------------------
 1765|      0|                break;
 1766|  11.6k|        }
 1767|  29.0k|        if (dst) {
  ------------------
  |  Branch (1767:13): [True: 29.0k, False: 0]
  ------------------
 1768|  29.0k|            int index = keyvalue_list_find_key(lst, key);
 1769|  29.0k|            if (index >= 0) {
  ------------------
  |  Branch (1769:17): [True: 0, False: 29.0k]
  ------------------
 1770|      0|                keyvalue_list_del_key(lst, index);
 1771|      0|                num -= 2;
 1772|      0|            }
 1773|  29.0k|            MP_TARRAY_APPEND(NULL, lst, num, bstrto0(NULL, key));
  ------------------
  |  |  105|  29.0k|    do {                                            \
  |  |  106|  29.0k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  29.0k|    do {                                            \
  |  |  |  |   97|  29.0k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  29.0k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  29.0k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  29.0k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 29.0k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  29.0k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  29.0k|    do {                                                        \
  |  |  |  |  |  |   89|  29.0k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  29.0k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  29.0k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  29.0k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  29.0k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  29.0k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  29.0k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  29.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  29.0k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  29.0k|        (idxvar)++;                                 \
  |  |  109|  29.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1774|  29.0k|            MP_TARRAY_APPEND(NULL, lst, num, bstrto0(NULL, val));
  ------------------
  |  |  105|  29.0k|    do {                                            \
  |  |  106|  29.0k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  29.0k|    do {                                            \
  |  |  |  |   97|  29.0k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  29.0k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  29.0k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  29.0k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 29.0k]
  |  |  |  |  ------------------
  |  |  |  |   99|  29.0k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  29.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  29.0k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  29.0k|        (idxvar)++;                                 \
  |  |  109|  29.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1775|  29.0k|            MP_TARRAY_APPEND(NULL, lst, num, NULL);
  ------------------
  |  |  105|  29.0k|    do {                                            \
  |  |  106|  29.0k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  29.0k|    do {                                            \
  |  |  |  |   97|  29.0k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  29.0k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  29.0k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  29.0k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 29.0k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  29.0k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  29.0k|    do {                                                        \
  |  |  |  |  |  |   89|  29.0k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  29.0k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  29.0k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  29.0k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  29.0k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  29.0k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  29.0k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  29.0k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  29.0k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  29.0k|        (idxvar)++;                                 \
  |  |  109|  29.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1776|  29.0k|            num -= 1;
 1777|  29.0k|        }
 1778|       |
 1779|  29.0k|        if (!bstr_eatstart0(&param, ",") && !bstr_eatstart0(&param, ":"))
  ------------------
  |  Branch (1779:13): [True: 29.0k, False: 0]
  |  Branch (1779:45): [True: 29.0k, False: 0]
  ------------------
 1780|  29.0k|            break;
 1781|  29.0k|    }
 1782|       |
 1783|  29.0k|    if (param.len) {
  ------------------
  |  Branch (1783:9): [True: 0, False: 29.0k]
  ------------------
 1784|      0|        mp_err(log, "Unparsable garbage at end of option value: '%.*s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1785|      0|               BSTR_P(param));
 1786|      0|        r = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1787|      0|    }
 1788|       |
 1789|  29.0k|    if (dst) {
  ------------------
  |  Branch (1789:9): [True: 29.0k, False: 0]
  ------------------
 1790|  29.0k|        if (!append)
  ------------------
  |  Branch (1790:13): [True: 5.81k, False: 23.2k]
  ------------------
 1791|  5.81k|            free_str_list(dst);
 1792|  29.0k|        VAL(dst) = lst;
  ------------------
  |  | 1316|  29.0k|#define VAL(x) (*(char ***)(x))
  ------------------
 1793|  29.0k|        if (r < 0)
  ------------------
  |  Branch (1793:13): [True: 0, False: 29.0k]
  ------------------
 1794|      0|            free_str_list(dst);
 1795|  29.0k|    } else {
 1796|      0|        free_str_list(&lst);
 1797|      0|    }
 1798|  29.0k|    return r;
 1799|  29.0k|}
m_option.c:keyvalue_list_find_key:
 1677|  29.0k|{
 1678|  29.0k|    for (int n = 0; lst && lst[n] && lst[n + 1]; n += 2) {
  ------------------
  |  Branch (1678:21): [True: 0, False: 29.0k]
  |  Branch (1678:28): [True: 0, False: 0]
  |  Branch (1678:38): [True: 0, False: 0]
  ------------------
 1679|      0|        if (bstr_equals0(str, lst[n]))
  ------------------
  |  Branch (1679:13): [True: 0, False: 0]
  ------------------
 1680|      0|            return n / 2;
 1681|      0|    }
 1682|  29.0k|    return -1;
 1683|  29.0k|}
m_option.c:read_subparam:
 1982|  40.6k|{
 1983|  40.6k|    bstr p = *str;
 1984|  40.6k|    bstr subparam = {0};
 1985|       |
 1986|  40.6k|    if (bstr_eatstart0(&p, "\"")) {
  ------------------
  |  Branch (1986:9): [True: 0, False: 40.6k]
  ------------------
 1987|      0|        int optlen = bstrcspn(p, "\"");
 1988|      0|        subparam = bstr_splice(p, 0, optlen);
 1989|      0|        p = bstr_cut(p, optlen);
 1990|      0|        if (!bstr_startswith0(p, "\"")) {
  ------------------
  |  Branch (1990:13): [True: 0, False: 0]
  ------------------
 1991|      0|            mp_err(log, "Terminating '\"' missing for '%.*s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1992|      0|                   BSTR_P(optname));
 1993|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1994|      0|        }
 1995|      0|        p = bstr_cut(p, 1);
 1996|  40.6k|    } else if (bstr_eatstart0(&p, "[")) {
  ------------------
  |  Branch (1996:16): [True: 0, False: 40.6k]
  ------------------
 1997|      0|        bstr s = p;
 1998|      0|        int balance = 1;
 1999|      0|        while (p.len && balance > 0) {
  ------------------
  |  Branch (1999:16): [True: 0, False: 0]
  |  Branch (1999:25): [True: 0, False: 0]
  ------------------
 2000|      0|            if (p.start[0] == '[') {
  ------------------
  |  Branch (2000:17): [True: 0, False: 0]
  ------------------
 2001|      0|                balance++;
 2002|      0|            } else if (p.start[0] == ']') {
  ------------------
  |  Branch (2002:24): [True: 0, False: 0]
  ------------------
 2003|      0|                balance--;
 2004|      0|            }
 2005|      0|            p = bstr_cut(p, 1);
 2006|      0|        }
 2007|      0|        if (balance != 0) {
  ------------------
  |  Branch (2007:13): [True: 0, False: 0]
  ------------------
 2008|      0|            mp_err(log, "Terminating ']' missing for '%.*s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2009|      0|                   BSTR_P(optname));
 2010|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 2011|      0|        }
 2012|      0|        subparam = bstr_splice(s, 0, s.len - p.len - 1);
 2013|  40.6k|    } else if (bstr_eatstart0(&p, "%")) {
  ------------------
  |  Branch (2013:16): [True: 0, False: 40.6k]
  ------------------
 2014|      0|        int optlen = bstrtoll(p, &p, 0);
 2015|      0|        if (!bstr_startswith0(p, "%") || (optlen > p.len - 1)) {
  ------------------
  |  Branch (2015:13): [True: 0, False: 0]
  |  Branch (2015:42): [True: 0, False: 0]
  ------------------
 2016|      0|            mp_err(log, "Invalid length %d for '%.*s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2017|      0|                   optlen, BSTR_P(optname));
 2018|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 2019|      0|        }
 2020|      0|        subparam = bstr_splice(p, 1, optlen + 1);
 2021|      0|        p = bstr_cut(p, optlen + 1);
 2022|  40.6k|    } else {
 2023|       |        // Skip until the next character that could possibly be a meta
 2024|       |        // character in option parsing.
 2025|  40.6k|        int optlen = bstrcspn(p, termset);
 2026|  40.6k|        subparam = bstr_splice(p, 0, optlen);
 2027|  40.6k|        p = bstr_cut(p, optlen);
 2028|  40.6k|    }
 2029|       |
 2030|  40.6k|    *str = p;
 2031|  40.6k|    *out_subparam = subparam;
 2032|  40.6k|    return 0;
 2033|  40.6k|}
m_option.c:print_keyvalue_list:
 1802|  5.81k|{
 1803|  5.81k|    char **lst = VAL(src);
  ------------------
  |  | 1316|  5.81k|#define VAL(x) (*(char ***)(x))
  ------------------
 1804|  5.81k|    char *ret = talloc_strdup(NULL, "");
  ------------------
  |  |   50|  5.81k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1805|  5.81k|    for (int n = 0; lst && lst[n] && lst[n + 1]; n += 2) {
  ------------------
  |  Branch (1805:21): [True: 0, False: 5.81k]
  |  Branch (1805:28): [True: 0, False: 0]
  |  Branch (1805:38): [True: 0, False: 0]
  ------------------
 1806|      0|        if (ret[0])
  ------------------
  |  Branch (1806:13): [True: 0, False: 0]
  ------------------
 1807|      0|            ret = talloc_strdup_append(ret, ",");
  ------------------
  |  |   57|      0|#define talloc_strdup_append            ta_talloc_strdup_append
  ------------------
 1808|      0|        ret = talloc_asprintf_append(ret, "%s=%s", lst[n], lst[n + 1]);
  ------------------
  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  ------------------
 1809|      0|    }
 1810|  5.81k|    return ret;
 1811|  5.81k|}
m_option.c:parse_msglevels:
 1894|  5.81k|{
 1895|  5.81k|    if (bstr_equals0(param, "help")) {
  ------------------
  |  Branch (1895:9): [True: 0, False: 5.81k]
  ------------------
 1896|      0|        mp_info(log, "Syntax:\n\n   --msg-level=module1=level,module2=level,...\n\n"
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 1897|      0|                     "'module' is output prefix as shown with -v, or a prefix\n"
 1898|      0|                     "of it. level is one of:\n\n"
 1899|      0|                     "  fatal error warn info status v debug trace\n\n"
 1900|      0|                     "The level specifies the minimum log level a message\n"
 1901|      0|                     "must have to be printed.\n"
 1902|      0|                     "The special module name 'all' affects all modules.\n");
 1903|      0|        return M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
 1904|      0|    }
 1905|       |
 1906|  5.81k|    char **dst_copy = NULL;
 1907|  5.81k|    int r = m_option_type_keyvalue_list.parse(log, opt, name, param, &dst_copy);
 1908|  5.81k|    if (r >= 0)
  ------------------
  |  Branch (1908:9): [True: 5.81k, False: 0]
  ------------------
 1909|  5.81k|        r = check_msg_levels(log, dst_copy);
 1910|       |
 1911|  5.81k|    if (r >= 0)
  ------------------
  |  Branch (1911:9): [True: 5.81k, False: 0]
  ------------------
 1912|  5.81k|        m_option_type_keyvalue_list.copy(opt, dst, &dst_copy);
 1913|  5.81k|    m_option_type_keyvalue_list.free(&dst_copy);
 1914|  5.81k|    return r;
 1915|  5.81k|}
m_option.c:check_msg_levels:
 1881|  5.81k|{
 1882|  11.6k|    for (int n = 0; list && list[n * 2 + 0]; n++) {
  ------------------
  |  Branch (1882:21): [True: 11.6k, False: 0]
  |  Branch (1882:29): [True: 5.81k, False: 5.81k]
  ------------------
 1883|  5.81k|        char *level = list[n * 2 + 1];
 1884|  5.81k|        if (mp_msg_find_level(level) < 0 && strcmp(level, "no") != 0) {
  ------------------
  |  Branch (1884:13): [True: 0, False: 5.81k]
  |  Branch (1884:45): [True: 0, False: 0]
  ------------------
 1885|      0|            mp_err(log, "Invalid message level '%s'\n", level);
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
 1886|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 1887|      0|        }
 1888|  5.81k|    }
 1889|  5.81k|    return 1;
 1890|  5.81k|}
m_option.c:copy_channels:
 2696|   192k|{
 2697|   192k|    if (!(dst && src))
  ------------------
  |  Branch (2697:11): [True: 192k, False: 0]
  |  Branch (2697:18): [True: 192k, False: 0]
  ------------------
 2698|      0|        return;
 2699|       |
 2700|   192k|    struct m_channels *ch = dst;
 2701|   192k|    free_channels(dst);
 2702|   192k|    *ch = *(struct m_channels *)src;
 2703|   192k|    ch->chmaps =
 2704|   192k|        talloc_memdup(NULL, ch->chmaps, sizeof(ch->chmaps[0]) * ch->num_chmaps);
  ------------------
  |  |   49|   192k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|   192k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|   192k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|   192k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|   192k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2705|   192k|}
m_option.c:free_channels:
 2686|   385k|{
 2687|   385k|    if (!src)
  ------------------
  |  Branch (2687:9): [True: 0, False: 385k]
  ------------------
 2688|      0|        return;
 2689|       |
 2690|   385k|    struct m_channels *ch = src;
 2691|   385k|    talloc_free(ch->chmaps);
  ------------------
  |  |   47|   385k|#define talloc_free                     ta_free
  ------------------
 2692|   385k|    *ch = (struct m_channels){0};
 2693|   385k|}
m_option.c:parse_time:
 2774|  87.1k|{
 2775|  87.1k|    if (param.len == 0)
  ------------------
  |  Branch (2775:9): [True: 0, False: 87.1k]
  ------------------
 2776|      0|        return M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
 2777|       |
 2778|  87.1k|    double time = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  87.1k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 2779|  87.1k|    if (HAS_NOPTS(opt) && bstr_equals0(param, "no")) {
  ------------------
  |  | 2770|   174k|#define HAS_NOPTS(opt) ((opt)->flags & M_OPT_ALLOW_NO)
  |  |  ------------------
  |  |  |  |  476|  87.1k|#define M_OPT_ALLOW_NO          (UINT64_C(1) << 57)
  |  |  ------------------
  |  |  |  Branch (2770:24): [True: 0, False: 87.1k]
  |  |  ------------------
  ------------------
  |  Branch (2779:27): [True: 0, False: 0]
  ------------------
 2780|       |        // nothing
 2781|  87.1k|    } else if (!parse_timestring(param, &time, 0)) {
  ------------------
  |  Branch (2781:16): [True: 0, False: 87.1k]
  ------------------
 2782|      0|        mp_err(log, "Option %.*s: invalid time: '%.*s'\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2783|      0|               BSTR_P(name), BSTR_P(param));
 2784|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 2785|      0|    }
 2786|       |
 2787|  87.1k|    if (dst)
  ------------------
  |  Branch (2787:9): [True: 87.1k, False: 0]
  ------------------
 2788|  87.1k|        *(double *)dst = time;
 2789|  87.1k|    return 1;
 2790|  87.1k|}
m_option.c:parse_timestring:
 2736|  87.1k|{
 2737|  87.1k|    int len;
 2738|  87.1k|    unsigned h, m;
 2739|  87.1k|    double s;
 2740|  87.1k|    *time = 0; /* ensure initialization for error cases */
 2741|  87.1k|    bool neg = bstr_eatstart0(&str, "-");
 2742|  87.1k|    if (!neg)
  ------------------
  |  Branch (2742:9): [True: 46.4k, False: 40.6k]
  ------------------
 2743|  46.4k|        bstr_eatstart0(&str, "+");
 2744|  87.1k|    bool sci = bstr_find0(str, "e-") >= 0 || bstr_find0(str, "e+") >= 0;
  ------------------
  |  Branch (2744:16): [True: 0, False: 87.1k]
  |  Branch (2744:46): [True: 0, False: 87.1k]
  ------------------
 2745|       |    /* non-scientific notation timestamps shouldn't contain anymore +/- after this point */
 2746|  87.1k|    if (!sci && (bstrchr(str, '-') >= 0 || bstrchr(str, '+') >= 0))
  ------------------
  |  Branch (2746:9): [True: 87.1k, False: 0]
  |  Branch (2746:18): [True: 0, False: 87.1k]
  |  Branch (2746:44): [True: 0, False: 87.1k]
  ------------------
 2747|      0|        return 0;
 2748|  87.1k|    if (bstr_sscanf(str, "%u:%u:%lf%n", &h, &m, &s, &len) >= 3) {
  ------------------
  |  Branch (2748:9): [True: 0, False: 87.1k]
  ------------------
 2749|      0|        if (m >= 60 || s >= 60)
  ------------------
  |  Branch (2749:13): [True: 0, False: 0]
  |  Branch (2749:24): [True: 0, False: 0]
  ------------------
 2750|      0|            return 0; /* minutes or seconds are out of range */
 2751|      0|        *time = 3600.0 * h + 60 * m + s;
 2752|  87.1k|    } else if (bstr_sscanf(str, "%u:%lf%n", &m, &s, &len) >= 2) {
  ------------------
  |  Branch (2752:16): [True: 0, False: 87.1k]
  ------------------
 2753|      0|        if (s >= 60)
  ------------------
  |  Branch (2753:13): [True: 0, False: 0]
  ------------------
 2754|      0|            return 0; /* seconds are out of range */
 2755|      0|        *time = 60.0 * m + s;
 2756|  87.1k|    } else if (bstr_sscanf(str, "%lf%n", &s, &len) >= 1) {
  ------------------
  |  Branch (2756:16): [True: 87.1k, False: 0]
  ------------------
 2757|  87.1k|        *time = s;
 2758|  87.1k|    } else {
 2759|      0|        return 0;  /* unsupported time format */
 2760|      0|    }
 2761|  87.1k|    if (len < str.len && str.start[len] != endchar)
  ------------------
  |  Branch (2761:9): [True: 0, False: 87.1k]
  |  Branch (2761:26): [True: 0, False: 0]
  ------------------
 2762|      0|        return 0;  /* invalid extra characters at the end */
 2763|  87.1k|    if (!isfinite(*time))
  ------------------
  |  Branch (2763:9): [True: 0, False: 87.1k]
  ------------------
 2764|      0|        return 0;
 2765|  87.1k|    if (neg)
  ------------------
  |  Branch (2765:9): [True: 40.6k, False: 46.4k]
  ------------------
 2766|  40.6k|        *time = -*time;
 2767|  87.1k|    return len;
 2768|  87.1k|}
m_option.c:parse_obj_settings_list:
 3398|  23.2k|{
 3399|  23.2k|    m_obj_settings_t *res = NULL;
 3400|  23.2k|    int op = OP_NONE;
  ------------------
  |  | 1318|  23.2k|#define OP_NONE 0
  ------------------
 3401|  23.2k|    bool *mark_del = NULL;
 3402|  23.2k|    int num_items = obj_settings_list_num_items(dst ? VAL(dst) : 0);
  ------------------
  |  | 2936|  23.2k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
  |  Branch (3402:49): [True: 23.2k, False: 0]
  ------------------
 3403|  23.2k|    const struct m_obj_list *ol = opt->priv;
 3404|  23.2k|    int ret = 1;
 3405|       |
 3406|  23.2k|    mp_assert(opt->priv);
  ------------------
  |  |   41|  23.2k|#define mp_assert assert
  ------------------
 3407|       |
 3408|  23.2k|    if (bstr_endswith0(name, "-add")) {
  ------------------
  |  Branch (3408:9): [True: 0, False: 23.2k]
  ------------------
 3409|      0|        op = OP_ADD;
  ------------------
  |  | 1319|      0|#define OP_ADD 1
  ------------------
 3410|  23.2k|    } else if (bstr_endswith0(name, "-append")) {
  ------------------
  |  Branch (3410:16): [True: 0, False: 23.2k]
  ------------------
 3411|      0|        op = OP_APPEND;
  ------------------
  |  | 1324|      0|#define OP_APPEND 6
  ------------------
 3412|  23.2k|    } else if (bstr_endswith0(name, "-set")) {
  ------------------
  |  Branch (3412:16): [True: 0, False: 23.2k]
  ------------------
 3413|      0|        op = OP_NONE;
  ------------------
  |  | 1318|      0|#define OP_NONE 0
  ------------------
 3414|  23.2k|    } else if (bstr_endswith0(name, "-pre")) {
  ------------------
  |  Branch (3414:16): [True: 0, False: 23.2k]
  ------------------
 3415|      0|        op = OP_PRE;
  ------------------
  |  | 1320|      0|#define OP_PRE 2
  ------------------
 3416|  23.2k|    } else if (bstr_endswith0(name, "-remove")) {
  ------------------
  |  Branch (3416:16): [True: 0, False: 23.2k]
  ------------------
 3417|      0|        op = OP_REMOVE;
  ------------------
  |  | 1325|      0|#define OP_REMOVE 7
  ------------------
 3418|  23.2k|    } else if (bstr_endswith0(name, "-clr")) {
  ------------------
  |  Branch (3418:16): [True: 0, False: 23.2k]
  ------------------
 3419|      0|        op = OP_CLR;
  ------------------
  |  | 1321|      0|#define OP_CLR 3
  ------------------
 3420|  23.2k|    } else if (bstr_endswith0(name, "-toggle")) {
  ------------------
  |  Branch (3420:16): [True: 0, False: 23.2k]
  ------------------
 3421|      0|        op = OP_TOGGLE;
  ------------------
  |  | 1323|      0|#define OP_TOGGLE 5
  ------------------
 3422|  23.2k|    } else if (bstr_endswith0(name, "-help")) {
  ------------------
  |  Branch (3422:16): [True: 0, False: 23.2k]
  ------------------
 3423|      0|        mp_err(log, "Option %s:\n"
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
 3424|      0|                "Supported operations are:\n"
 3425|      0|                "  %s-set\n"
 3426|      0|                " Overwrite the old list with the given list\n\n"
 3427|      0|                "  %s-append\n"
 3428|      0|                " Append the given item to the current list\n\n"
 3429|      0|                "  %s-add\n"
 3430|      0|                " Append the given list to the current list\n\n"
 3431|      0|                "  %s-pre\n"
 3432|      0|                " Prepend the given list to the current list\n\n"
 3433|      0|                "  %s-remove\n"
 3434|      0|                " Remove the given item from the current list\n\n"
 3435|      0|                "  %s-toggle\n"
 3436|      0|                " Add the item to the list, or remove it if it's already added.\n\n"
 3437|      0|                "  %s-clr\n"
 3438|      0|                " Clear the current list.\n\n",
 3439|      0|                opt->name, opt->name, opt->name, opt->name, opt->name,
 3440|      0|                opt->name, opt->name, opt->name);
 3441|       |
 3442|      0|        ret = M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
 3443|      0|        goto done;
 3444|      0|    }
 3445|       |
 3446|  23.2k|    if (!bstrcmp0(param, "help")) {
  ------------------
  |  Branch (3446:9): [True: 0, False: 23.2k]
  ------------------
 3447|      0|        mp_info(log, "Available %s:\n", ol->description);
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 3448|      0|        for (int n = 0; ; n++) {
 3449|      0|            struct m_obj_desc desc;
 3450|      0|            if (!ol->get_desc(&desc, n))
  ------------------
  |  Branch (3450:17): [True: 0, False: 0]
  ------------------
 3451|      0|                break;
 3452|      0|            if (!desc.hidden) {
  ------------------
  |  Branch (3452:17): [True: 0, False: 0]
  ------------------
 3453|      0|                mp_info(log, "  %-16s %s\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 3454|      0|                       desc.name, desc.description);
 3455|      0|            }
 3456|      0|        }
 3457|      0|        mp_info(log, "\n");
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 3458|      0|        if (ol->print_help_list)
  ------------------
  |  Branch (3458:13): [True: 0, False: 0]
  ------------------
 3459|      0|            ol->print_help_list(log);
 3460|      0|        if (!ol->use_global_options) {
  ------------------
  |  Branch (3460:13): [True: 0, False: 0]
  ------------------
 3461|      0|            mp_info(log, "Get help on individual entries via: --%s=entry=help\n",
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 3462|      0|                    opt->name);
 3463|      0|        }
 3464|      0|        ret = M_OPT_EXIT;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
 3465|      0|        goto done;
 3466|      0|    }
 3467|       |
 3468|  23.2k|    if (op == OP_CLR) {
  ------------------
  |  | 1321|  23.2k|#define OP_CLR 3
  ------------------
  |  Branch (3468:9): [True: 0, False: 23.2k]
  ------------------
 3469|      0|        if (param.len) {
  ------------------
  |  Branch (3469:13): [True: 0, False: 0]
  ------------------
 3470|      0|            mp_err(log, "Option %.*s: -clr does not take an argument.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3471|      0|                   BSTR_P(name));
 3472|      0|            ret = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3473|      0|            goto done;
 3474|      0|        }
 3475|      0|        if (dst)
  ------------------
  |  Branch (3475:13): [True: 0, False: 0]
  ------------------
 3476|      0|            free_obj_settings_list(dst);
 3477|      0|        ret = 0;
 3478|      0|        goto done;
 3479|  23.2k|    } else if (op == OP_REMOVE) {
  ------------------
  |  | 1325|  23.2k|#define OP_REMOVE 7
  ------------------
  |  Branch (3479:16): [True: 0, False: 23.2k]
  ------------------
 3480|      0|        mark_del = talloc_zero_array(NULL, bool, num_items + 1);
  ------------------
  |  |   30|      0|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|      0|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3481|      0|    }
 3482|       |
 3483|  23.2k|    if (op != OP_NONE && param.len == 0) {
  ------------------
  |  | 1318|  46.4k|#define OP_NONE 0
  ------------------
  |  Branch (3483:9): [True: 0, False: 23.2k]
  |  Branch (3483:26): [True: 0, False: 0]
  ------------------
 3484|      0|        ret = M_OPT_MISSING_PARAM;
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
 3485|      0|        goto done;
 3486|      0|    }
 3487|       |
 3488|  46.4k|    while (param.len > 0) {
  ------------------
  |  Branch (3488:12): [True: 23.2k, False: 23.2k]
  ------------------
 3489|  23.2k|        int r = 0;
 3490|  23.2k|        if (op == OP_REMOVE)
  ------------------
  |  | 1325|  23.2k|#define OP_REMOVE 7
  ------------------
  |  Branch (3490:13): [True: 0, False: 23.2k]
  ------------------
 3491|      0|            r = parse_obj_settings_del(log, name, &param, dst, mark_del);
 3492|  23.2k|        if (r == 0) {
  ------------------
  |  Branch (3492:13): [True: 23.2k, False: 0]
  ------------------
 3493|  23.2k|            r = parse_obj_settings(log, name, op, &param, ol, dst ? &res : NULL);
  ------------------
  |  Branch (3493:63): [True: 23.2k, False: 0]
  ------------------
 3494|  23.2k|        }
 3495|  23.2k|        if (r < 0) {
  ------------------
  |  Branch (3495:13): [True: 0, False: 23.2k]
  ------------------
 3496|      0|            free_obj_settings_list(&res);
 3497|      0|            ret = r;
 3498|      0|            goto done;
 3499|      0|        }
 3500|  23.2k|        if (param.len > 0) {
  ------------------
  |  Branch (3500:13): [True: 0, False: 23.2k]
  ------------------
 3501|      0|            const char sep[2] = {OPTION_LIST_SEPARATOR, 0};
  ------------------
  |  |  632|      0|#define OPTION_LIST_SEPARATOR ','
  ------------------
 3502|      0|            if (!bstr_eatstart0(&param, sep)) {
  ------------------
  |  Branch (3502:17): [True: 0, False: 0]
  ------------------
 3503|      0|                free_obj_settings_list(&res);
 3504|      0|                ret = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3505|      0|                goto done;
 3506|      0|            }
 3507|      0|            if (param.len == 0) {
  ------------------
  |  Branch (3507:17): [True: 0, False: 0]
  ------------------
 3508|      0|                if (!ol->allow_trailer) {
  ------------------
  |  Branch (3508:21): [True: 0, False: 0]
  ------------------
 3509|      0|                    free_obj_settings_list(&res);
 3510|      0|                    ret = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3511|      0|                    goto done;
 3512|      0|                }
 3513|      0|                if (dst) {
  ------------------
  |  Branch (3513:21): [True: 0, False: 0]
  ------------------
 3514|      0|                    m_obj_settings_t item = {
 3515|      0|                        .name = talloc_strdup(NULL, ""),
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
 3516|      0|                    };
 3517|      0|                    if (!obj_settings_list_insert_at(log, &res, -1, &item))
  ------------------
  |  Branch (3517:25): [True: 0, False: 0]
  ------------------
 3518|      0|                        obj_setting_free(&item);
 3519|      0|                }
 3520|      0|            }
 3521|      0|        }
 3522|  23.2k|    }
 3523|       |
 3524|  23.2k|    if (op != OP_NONE && res && res[0].name && res[1].name) {
  ------------------
  |  | 1318|  46.4k|#define OP_NONE 0
  ------------------
  |  Branch (3524:9): [True: 0, False: 23.2k]
  |  Branch (3524:26): [True: 0, False: 0]
  |  Branch (3524:33): [True: 0, False: 0]
  |  Branch (3524:48): [True: 0, False: 0]
  ------------------
 3525|      0|        if (op == OP_APPEND) {
  ------------------
  |  | 1324|      0|#define OP_APPEND 6
  ------------------
  |  Branch (3525:13): [True: 0, False: 0]
  ------------------
 3526|      0|            mp_err(log, "Option %.*s: -append takes only 1 item (no ',').\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3527|      0|                   BSTR_P(name));
 3528|      0|            free_obj_settings_list(&res);
 3529|      0|            ret = M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3530|      0|            goto done;
 3531|      0|        }
 3532|      0|    }
 3533|       |
 3534|  23.2k|    if (dst) {
  ------------------
  |  Branch (3534:9): [True: 23.2k, False: 0]
  ------------------
 3535|  23.2k|        m_obj_settings_t *list = VAL(dst);
  ------------------
  |  | 2936|  23.2k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3536|  23.2k|        if (op == OP_PRE) {
  ------------------
  |  | 1320|  23.2k|#define OP_PRE 2
  ------------------
  |  Branch (3536:13): [True: 0, False: 23.2k]
  ------------------
 3537|      0|            int prepend_counter = 0;
 3538|      0|            for (int n = 0; res && res[n].name; n++) {
  ------------------
  |  Branch (3538:29): [True: 0, False: 0]
  |  Branch (3538:36): [True: 0, False: 0]
  ------------------
 3539|      0|                int label = obj_settings_list_find_by_label0(list, res[n].label);
 3540|      0|                if (label < 0) {
  ------------------
  |  Branch (3540:21): [True: 0, False: 0]
  ------------------
 3541|      0|                    if (!obj_settings_list_insert_at(log, &list, prepend_counter, &res[n]))
  ------------------
  |  Branch (3541:25): [True: 0, False: 0]
  ------------------
 3542|      0|                        obj_setting_free(&res[n]);
 3543|      0|                    prepend_counter++;
 3544|      0|                } else {
 3545|       |                    // Prefer replacement semantics, instead of actually
 3546|       |                    // prepending.
 3547|      0|                    obj_setting_free(&list[label]);
 3548|      0|                    list[label] = res[n];
 3549|      0|                }
 3550|      0|            }
 3551|      0|            talloc_free(res);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 3552|  23.2k|        } else if (op == OP_ADD || op == OP_APPEND) {
  ------------------
  |  | 1319|  46.4k|#define OP_ADD 1
  ------------------
                      } else if (op == OP_ADD || op == OP_APPEND) {
  ------------------
  |  | 1324|  23.2k|#define OP_APPEND 6
  ------------------
  |  Branch (3552:20): [True: 0, False: 23.2k]
  |  Branch (3552:36): [True: 0, False: 23.2k]
  ------------------
 3553|      0|            for (int n = 0; res && res[n].name; n++) {
  ------------------
  |  Branch (3553:29): [True: 0, False: 0]
  |  Branch (3553:36): [True: 0, False: 0]
  ------------------
 3554|      0|                int label = obj_settings_list_find_by_label0(list, res[n].label);
 3555|      0|                if (label < 0) {
  ------------------
  |  Branch (3555:21): [True: 0, False: 0]
  ------------------
 3556|      0|                    if (!obj_settings_list_insert_at(log, &list, -1, &res[n]))
  ------------------
  |  Branch (3556:25): [True: 0, False: 0]
  ------------------
 3557|      0|                        obj_setting_free(&res[n]);
 3558|      0|                } else {
 3559|       |                    // Prefer replacement semantics, instead of actually
 3560|       |                    // appending.
 3561|      0|                    obj_setting_free(&list[label]);
 3562|      0|                    list[label] = res[n];
 3563|      0|                }
 3564|      0|            }
 3565|      0|            talloc_free(res);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 3566|  23.2k|        } else if (op == OP_TOGGLE) {
  ------------------
  |  | 1323|  23.2k|#define OP_TOGGLE 5
  ------------------
  |  Branch (3566:20): [True: 0, False: 23.2k]
  ------------------
 3567|      0|            for (int n = 0; res && res[n].name; n++) {
  ------------------
  |  Branch (3567:29): [True: 0, False: 0]
  |  Branch (3567:36): [True: 0, False: 0]
  ------------------
 3568|      0|                if (res[n].label && !res[n].name[0]) {
  ------------------
  |  Branch (3568:21): [True: 0, False: 0]
  |  Branch (3568:37): [True: 0, False: 0]
  ------------------
 3569|       |                    // Toggle enable/disable special case.
 3570|      0|                    int found =
 3571|      0|                        obj_settings_list_find_by_label0(list, res[n].label);
 3572|      0|                    if (found < 0) {
  ------------------
  |  Branch (3572:25): [True: 0, False: 0]
  ------------------
 3573|      0|                        mp_warn(log, "Option %.*s: Label %s not found\n",
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (73:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3574|      0|                                BSTR_P(name), res[n].label);
 3575|      0|                    } else {
 3576|      0|                        list[found].enabled = !list[found].enabled;
 3577|      0|                    }
 3578|      0|                    obj_setting_free(&res[n]);
 3579|      0|                } else {
 3580|      0|                    int found = obj_settings_find_by_content(list, &res[n]);
 3581|      0|                    if (found < 0) {
  ------------------
  |  Branch (3581:25): [True: 0, False: 0]
  ------------------
 3582|      0|                        if (!obj_settings_list_insert_at(log, &list, -1, &res[n]))
  ------------------
  |  Branch (3582:29): [True: 0, False: 0]
  ------------------
 3583|      0|                            obj_setting_free(&res[n]);
 3584|      0|                    } else {
 3585|      0|                        obj_settings_list_del_at(&list, found);
 3586|      0|                        obj_setting_free(&res[n]);
 3587|      0|                    }
 3588|      0|                }
 3589|      0|            }
 3590|      0|            talloc_free(res);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 3591|  23.2k|        } else if (op == OP_REMOVE) {
  ------------------
  |  | 1325|  23.2k|#define OP_REMOVE 7
  ------------------
  |  Branch (3591:20): [True: 0, False: 23.2k]
  ------------------
 3592|      0|            for (int n = num_items - 1; n >= 0; n--) {
  ------------------
  |  Branch (3592:41): [True: 0, False: 0]
  ------------------
 3593|      0|                if (mark_del[n])
  ------------------
  |  Branch (3593:21): [True: 0, False: 0]
  ------------------
 3594|      0|                    obj_settings_list_del_at(&list, n);
 3595|      0|            }
 3596|      0|            for (int n = 0; res && res[n].name; n++) {
  ------------------
  |  Branch (3596:29): [True: 0, False: 0]
  |  Branch (3596:36): [True: 0, False: 0]
  ------------------
 3597|      0|                int found = obj_settings_find_by_content(list, &res[n]);
 3598|      0|                if (found >= 0)
  ------------------
  |  Branch (3598:21): [True: 0, False: 0]
  ------------------
 3599|      0|                    obj_settings_list_del_at(&list, found);
 3600|      0|            }
 3601|      0|            free_obj_settings_list(&res);
 3602|  23.2k|        } else {
 3603|  23.2k|            mp_assert(op == OP_NONE);
  ------------------
  |  |   41|  23.2k|#define mp_assert assert
  ------------------
 3604|  23.2k|            free_obj_settings_list(&list);
 3605|  23.2k|            list = res;
 3606|  23.2k|        }
 3607|  23.2k|        VAL(dst) = list;
  ------------------
  |  | 2936|  23.2k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3608|  23.2k|    }
 3609|       |
 3610|  23.2k|done:
 3611|  23.2k|    talloc_free(mark_del);
  ------------------
  |  |   47|  23.2k|#define talloc_free                     ta_free
  ------------------
 3612|  23.2k|    return ret;
 3613|  23.2k|}
m_option.c:obj_settings_list_num_items:
 2977|  46.4k|{
 2978|  46.4k|    int num = 0;
 2979|  46.4k|    while (obj_list && obj_list[num].name)
  ------------------
  |  Branch (2979:12): [True: 0, False: 46.4k]
  |  Branch (2979:24): [True: 0, False: 0]
  ------------------
 2980|      0|        num++;
 2981|  46.4k|    return num;
 2982|  46.4k|}
m_option.c:parse_obj_settings:
 3277|  23.2k|{
 3278|  23.2k|    int r;
 3279|  23.2k|    char **plist = NULL;
 3280|  23.2k|    struct m_obj_desc desc;
 3281|  23.2k|    bstr str = {0};
 3282|  23.2k|    bstr label = {0};
 3283|  23.2k|    bool nopos = list->disallow_positional_parameters;
 3284|  23.2k|    bool enabled = true;
 3285|       |
 3286|  23.2k|    if (bstr_eatstart0(pstr, "@")) {
  ------------------
  |  Branch (3286:9): [True: 0, False: 23.2k]
  ------------------
 3287|      0|        bstr rest;
 3288|      0|        if (!bstr_split_tok(*pstr, ":", &label, &rest)) {
  ------------------
  |  Branch (3288:13): [True: 0, False: 0]
  ------------------
 3289|       |            // "@labelname" is the special enable/disable toggle syntax
 3290|      0|            if (op == OP_TOGGLE) {
  ------------------
  |  | 1323|      0|#define OP_TOGGLE 5
  ------------------
  |  Branch (3290:17): [True: 0, False: 0]
  ------------------
 3291|      0|                int idx = bstrspn(*pstr, NAMECH);
  ------------------
  |  | 3271|      0|#define NAMECH "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
  ------------------
 3292|      0|                label = bstr_splice(*pstr, 0, idx);
 3293|      0|                if (label.len) {
  ------------------
  |  Branch (3293:21): [True: 0, False: 0]
  ------------------
 3294|      0|                    *pstr = bstr_cut(*pstr, idx);
 3295|      0|                    goto done;
 3296|      0|                }
 3297|      0|            }
 3298|      0|            mp_err(log, "Option %.*s: ':' expected after label.\n", BSTR_P(opt));
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3299|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3300|      0|        }
 3301|      0|        *pstr = rest;
 3302|      0|        if (label.len == 0) {
  ------------------
  |  Branch (3302:13): [True: 0, False: 0]
  ------------------
 3303|      0|            mp_err(log, "Option %.*s: label name expected.\n", BSTR_P(opt));
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3304|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3305|      0|        }
 3306|      0|    }
 3307|       |
 3308|  23.2k|    if (list->allow_disable_entries && bstr_eatstart0(pstr, "!"))
  ------------------
  |  Branch (3308:9): [True: 0, False: 23.2k]
  |  Branch (3308:40): [True: 0, False: 0]
  ------------------
 3309|      0|        enabled = false;
 3310|       |
 3311|  23.2k|    bool has_param = false;
 3312|  23.2k|    int idx = bstrspn(*pstr, NAMECH);
  ------------------
  |  | 3271|  23.2k|#define NAMECH "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
  ------------------
 3313|  23.2k|    str = bstr_splice(*pstr, 0, idx);
 3314|  23.2k|    if (!str.len) {
  ------------------
  |  Branch (3314:9): [True: 0, False: 23.2k]
  ------------------
 3315|      0|        mp_err(log, "Option %.*s: item name expected.\n", BSTR_P(opt));
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3316|      0|        return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3317|      0|    }
 3318|  23.2k|    *pstr = bstr_cut(*pstr, idx);
 3319|       |    // video filters use "=", VOs use ":"
 3320|  23.2k|    if (bstr_eatstart0(pstr, "=") || bstr_eatstart0(pstr, ":"))
  ------------------
  |  Branch (3320:9): [True: 0, False: 23.2k]
  |  Branch (3320:38): [True: 0, False: 23.2k]
  ------------------
 3321|      0|        has_param = true;
 3322|       |
 3323|  23.2k|    bool skip = false;
 3324|  23.2k|    if (m_obj_list_find(&desc, list, str)) {
  ------------------
  |  Branch (3324:9): [True: 23.2k, False: 0]
  ------------------
 3325|  23.2k|        if (desc.replaced_name)
  ------------------
  |  Branch (3325:13): [True: 0, False: 23.2k]
  ------------------
 3326|      0|            mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
 3327|  23.2k|                   desc.replaced_name, desc.name);
 3328|  23.2k|    } else {
 3329|      0|        char name[80];
 3330|      0|        snprintf(name, sizeof(name), "%.*s", BSTR_P(str));
  ------------------
  |  |  283|      0|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3331|      0|        if (list->check_unknown_entry && !list->check_unknown_entry(name)) {
  ------------------
  |  Branch (3331:13): [True: 0, False: 0]
  |  Branch (3331:42): [True: 0, False: 0]
  ------------------
 3332|      0|            mp_err(log, "Option %.*s: '%.*s' isn't supported.\n",
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  |  Branch (72:55): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 3333|      0|                   BSTR_P(opt), BSTR_P(str));
 3334|      0|            return M_OPT_INVALID;
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
 3335|      0|        }
 3336|      0|        desc = (struct m_obj_desc){0};
 3337|      0|        skip = true;
 3338|      0|    }
 3339|       |
 3340|  23.2k|    if (has_param) {
  ------------------
  |  Branch (3340:9): [True: 0, False: 23.2k]
  ------------------
 3341|      0|        struct m_config *config = NULL;
 3342|      0|        if (!skip)
  ------------------
  |  Branch (3342:13): [True: 0, False: 0]
  ------------------
 3343|      0|            config = m_config_from_obj_desc_noalloc(NULL, log, &desc);
 3344|      0|        r = m_obj_parse_sub_config(log, opt, str, pstr, config,
 3345|      0|                                   M_SETOPT_CHECK_ONLY, nopos, &desc, list,
 3346|      0|                                   _ret ? &plist : NULL);
  ------------------
  |  Branch (3346:36): [True: 0, False: 0]
  ------------------
 3347|      0|        talloc_free(config);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 3348|      0|        if (r < 0)
  ------------------
  |  Branch (3348:13): [True: 0, False: 0]
  ------------------
 3349|      0|            return r;
 3350|      0|    }
 3351|  23.2k|    if (!_ret)
  ------------------
  |  Branch (3351:9): [True: 0, False: 23.2k]
  ------------------
 3352|      0|        return 1;
 3353|       |
 3354|  23.2k|done: ;
 3355|  23.2k|    m_obj_settings_t item = {
 3356|  23.2k|        .name = bstrto0(NULL, str),
 3357|  23.2k|        .label = bstrdup0(NULL, label),
 3358|  23.2k|        .enabled = enabled,
 3359|  23.2k|        .attribs = plist,
 3360|  23.2k|    };
 3361|  23.2k|    if (!obj_settings_list_insert_at(log, _ret, -1, &item))
  ------------------
  |  Branch (3361:9): [True: 0, False: 23.2k]
  ------------------
 3362|      0|        obj_setting_free(&item);
 3363|  23.2k|    return 1;
 3364|  23.2k|}
m_option.c:obj_settings_list_insert_at:
 3006|  23.2k|{
 3007|  23.2k|    int num = obj_settings_list_num_items(*p_obj_list);
 3008|       |    // Limit list entries to 100. obj_settings_list is not designed to hold more
 3009|       |    // items, and it quickly starts taking ages to add all items.
 3010|  23.2k|    if (num > 100) {
  ------------------
  |  Branch (3010:9): [True: 0, False: 23.2k]
  ------------------
 3011|      0|        mp_warn(log, "Object settings list capacity exceeded: "
  ------------------
  |  |   73|      0|#define mp_warn(log, ...)       mp_msg(log, MSGL_WARN, __VA_ARGS__)
  ------------------
 3012|      0|                     "a maximum of 100 elements is allowed.\n");
 3013|      0|        return false;
 3014|      0|    }
 3015|  23.2k|    if (idx < 0)
  ------------------
  |  Branch (3015:9): [True: 23.2k, False: 0]
  ------------------
 3016|  23.2k|        idx = num + idx + 1;
 3017|  23.2k|    mp_assert(idx >= 0 && idx <= num);
  ------------------
  |  |   41|  23.2k|#define mp_assert assert
  ------------------
 3018|  23.2k|    *p_obj_list = talloc_realloc(NULL, *p_obj_list, struct m_obj_settings,
  ------------------
  |  |   33|  23.2k|#define talloc_realloc                  ta_xrealloc
  |  |  ------------------
  |  |  |  |  144|  23.2k|    (type *)ta_xrealloc_size(ta_parent, ptr, ta_calc_array_size(sizeof(type), count))
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  23.2k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  23.2k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  23.2k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  23.2k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3019|  23.2k|                                 num + 2);
 3020|  23.2k|    memmove(*p_obj_list + idx + 1, *p_obj_list + idx,
 3021|  23.2k|            (num - idx) * sizeof(m_obj_settings_t));
 3022|  23.2k|    (*p_obj_list)[idx] = *item;
 3023|  23.2k|    (*p_obj_list)[num + 1] = (m_obj_settings_t){0};
 3024|  23.2k|    return true;
 3025|  23.2k|}
m_option.c:obj_setting_free:
 2960|   383k|{
 2961|   383k|    talloc_free(item->name);
  ------------------
  |  |   47|   383k|#define talloc_free                     ta_free
  ------------------
 2962|   383k|    talloc_free(item->label);
  ------------------
  |  |   47|   383k|#define talloc_free                     ta_free
  ------------------
 2963|   383k|    free_str_list(&(item->attribs));
 2964|   383k|}
m_option.c:copy_obj_settings_list:
 3070|   432k|{
 3071|   432k|    m_obj_settings_t *d, *s;
 3072|   432k|    int n;
 3073|       |
 3074|   432k|    if (!(dst && src))
  ------------------
  |  Branch (3074:11): [True: 432k, False: 0]
  |  Branch (3074:18): [True: 432k, False: 0]
  ------------------
 3075|      0|        return;
 3076|       |
 3077|   432k|    s = VAL(src);
  ------------------
  |  | 2936|   432k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3078|       |
 3079|   432k|    if (VAL(dst))
  ------------------
  |  | 2936|   432k|#define VAL(x) (*(m_obj_settings_t **)(x))
  |  |  ------------------
  |  |  |  Branch (2936:16): [True: 0, False: 432k]
  |  |  ------------------
  ------------------
 3080|      0|        free_obj_settings_list(dst);
 3081|   432k|    if (!s)
  ------------------
  |  Branch (3081:9): [True: 254k, False: 178k]
  ------------------
 3082|   254k|        return;
 3083|       |
 3084|   538k|    for (n = 0; s[n].name; n++)
  ------------------
  |  Branch (3084:17): [True: 360k, False: 178k]
  ------------------
 3085|   360k|        /* NOP */;
 3086|   178k|    d = talloc_array(NULL, struct m_obj_settings, n + 1);
  ------------------
  |  |   29|   178k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|   178k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   178k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3087|   538k|    for (n = 0; s[n].name; n++) {
  ------------------
  |  Branch (3087:17): [True: 360k, False: 178k]
  ------------------
 3088|   360k|        d[n].name = talloc_strdup(NULL, s[n].name);
  ------------------
  |  |   50|   360k|#define talloc_strdup                   ta_xstrdup
  ------------------
 3089|   360k|        d[n].label = talloc_strdup(NULL, s[n].label);
  ------------------
  |  |   50|   360k|#define talloc_strdup                   ta_xstrdup
  ------------------
 3090|   360k|        d[n].enabled = s[n].enabled;
 3091|   360k|        d[n].attribs = NULL;
 3092|   360k|        copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
 3093|   360k|    }
 3094|   178k|    d[n].name = NULL;
 3095|   178k|    d[n].label = NULL;
 3096|   178k|    d[n].attribs = NULL;
 3097|   178k|    VAL(dst) = d;
  ------------------
  |  | 2936|   178k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3098|   178k|}
m_option.c:free_obj_settings_list:
 3054|   469k|{
 3055|   469k|    int n;
 3056|   469k|    m_obj_settings_t *d;
 3057|       |
 3058|   469k|    if (!dst || !VAL(dst))
  ------------------
  |  | 2936|   469k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
  |  Branch (3058:9): [True: 0, False: 469k]
  |  Branch (3058:17): [True: 267k, False: 201k]
  ------------------
 3059|   267k|        return;
 3060|       |
 3061|   201k|    d = VAL(dst);
  ------------------
  |  | 2936|   201k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3062|   585k|    for (n = 0; d[n].name; n++)
  ------------------
  |  Branch (3062:17): [True: 383k, False: 201k]
  ------------------
 3063|   383k|        obj_setting_free(&d[n]);
 3064|   201k|    talloc_free(d);
  ------------------
  |  |   47|   201k|#define talloc_free                     ta_free
  ------------------
 3065|   201k|    VAL(dst) = NULL;
  ------------------
  |  | 2936|   201k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3066|   201k|}
m_option.c:obj_settings_list_equal:
 3761|  11.6k|{
 3762|  11.6k|    struct m_obj_settings *a = VAL(pa);
  ------------------
  |  | 2936|  11.6k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3763|  11.6k|    struct m_obj_settings *b = VAL(pb);
  ------------------
  |  | 2936|  11.6k|#define VAL(x) (*(m_obj_settings_t **)(x))
  ------------------
 3764|       |
 3765|  11.6k|    if (a == b || !a || !b)
  ------------------
  |  Branch (3765:9): [True: 0, False: 11.6k]
  |  Branch (3765:19): [True: 11.6k, False: 0]
  |  Branch (3765:25): [True: 0, False: 0]
  ------------------
 3766|  11.6k|        return a == b || (!a && !b[0].name) || (!b && !a[0].name);
  ------------------
  |  Branch (3766:16): [True: 0, False: 11.6k]
  |  Branch (3766:27): [True: 11.6k, False: 0]
  |  Branch (3766:33): [True: 0, False: 11.6k]
  |  Branch (3766:49): [True: 0, False: 11.6k]
  |  Branch (3766:55): [True: 0, False: 0]
  ------------------
 3767|       |
 3768|      0|    for (int n = 0; a[n].name || b[n].name; n++) {
  ------------------
  |  Branch (3768:21): [True: 0, False: 0]
  |  Branch (3768:34): [True: 0, False: 0]
  ------------------
 3769|      0|        if (!a[n].name || !b[n].name)
  ------------------
  |  Branch (3769:13): [True: 0, False: 0]
  |  Branch (3769:27): [True: 0, False: 0]
  ------------------
 3770|      0|            return false;
 3771|      0|        if (!m_obj_settings_equal(&a[n], &b[n]))
  ------------------
  |  Branch (3771:13): [True: 0, False: 0]
  ------------------
 3772|      0|            return false;
 3773|      0|    }
 3774|       |
 3775|      0|    return true;
 3776|      0|}
m_option.c:free_node:
 3921|  11.6k|{
 3922|  11.6k|    if (src) {
  ------------------
  |  Branch (3922:9): [True: 11.6k, False: 0]
  ------------------
 3923|  11.6k|        struct mpv_node *node = &VAL(src);
  ------------------
  |  | 3816|  11.6k|#define VAL(x) (*(struct mpv_node *)(x))
  ------------------
 3924|  11.6k|        talloc_free(node_get_alloc(node));
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
 3925|  11.6k|        *node = (struct mpv_node){{0}};
 3926|  11.6k|    }
 3927|  11.6k|}
m_option.c:parse_cycle_dir:
 3964|  5.81k|{
 3965|  5.81k|    double val;
 3966|  5.81k|    if (bstrcmp0(param, "up") == 0) {
  ------------------
  |  Branch (3966:9): [True: 0, False: 5.81k]
  ------------------
 3967|      0|        val = +1;
 3968|  5.81k|    } else if (bstrcmp0(param, "down") == 0) {
  ------------------
  |  Branch (3968:16): [True: 5.81k, False: 0]
  ------------------
 3969|  5.81k|        val = -1;
 3970|  5.81k|    } else {
 3971|      0|        return m_option_type_double.parse(log, opt, name, param, dst);
 3972|      0|    }
 3973|  5.81k|    *(double *)dst = val;
 3974|  5.81k|    return 1;
 3975|  5.81k|}

client.c:m_option_free:
  577|  11.6k|{
  578|  11.6k|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 11.6k, False: 0]
  ------------------
  579|  11.6k|        opt->type->free(dst);
  580|  11.6k|}
command.c:m_option_free:
  577|  5.81k|{
  578|  5.81k|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 5.81k, False: 0]
  ------------------
  579|  5.81k|        opt->type->free(dst);
  580|  5.81k|}
f_output_chain.c:m_option_free:
  577|  25.3k|{
  578|  25.3k|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 25.3k, False: 0]
  ------------------
  579|  25.3k|        opt->type->free(dst);
  580|  25.3k|}
cmd.c:m_option_free:
  577|  2.44M|{
  578|  2.44M|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 1.30M, False: 1.14M]
  ------------------
  579|  1.30M|        opt->type->free(dst);
  580|  2.44M|}
cmd.c:m_option_copy:
  570|   371k|{
  571|   371k|    if (opt->type->copy)
  ------------------
  |  Branch (571:9): [True: 371k, False: 0]
  ------------------
  572|   371k|        opt->type->copy(opt, dst, src);
  573|   371k|}
cmd.c:m_option_print:
  547|  29.0k|{
  548|  29.0k|    if (opt->type->print)
  ------------------
  |  Branch (548:9): [True: 29.0k, False: 0]
  ------------------
  549|  29.0k|        return opt->type->print(opt, val_ptr);
  550|      0|    else
  551|      0|        return NULL;
  552|  29.0k|}
m_config_core.c:m_option_free:
  577|  43.1M|{
  578|  43.1M|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 7.71M, False: 35.4M]
  ------------------
  579|  7.71M|        opt->type->free(dst);
  580|  43.1M|}
m_config_core.c:m_option_equal:
  605|   284k|{
  606|       |    // Handle trivial equivalence.
  607|       |    // If not implemented, assume this type has no actual values => always equal.
  608|   284k|    if (a == b || !opt->type->equal)
  ------------------
  |  Branch (608:9): [True: 0, False: 284k]
  |  Branch (608:19): [True: 0, False: 284k]
  ------------------
  609|      0|        return true;
  610|   284k|    return opt->type->equal(opt, a, b);
  611|   284k|}
m_config_core.c:m_option_copy:
  570|  7.82M|{
  571|  7.82M|    if (opt->type->copy)
  ------------------
  |  Branch (571:9): [True: 7.82M, False: 0]
  ------------------
  572|  7.82M|        opt->type->copy(opt, dst, src);
  573|  7.82M|}
m_config_frontend.c:m_option_copy:
  570|  4.48M|{
  571|  4.48M|    if (opt->type->copy)
  ------------------
  |  Branch (571:9): [True: 4.48M, False: 0]
  ------------------
  572|  4.48M|        opt->type->copy(opt, dst, src);
  573|  4.48M|}
m_config_frontend.c:m_option_free:
  577|  4.45M|{
  578|  4.45M|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 848k, False: 3.60M]
  ------------------
  579|   848k|        opt->type->free(dst);
  580|  4.45M|}
m_property.c:m_option_pretty_print:
  557|  77.3k|{
  558|  77.3k|    m_option_t o = *opt;
  559|  77.3k|    if (fixed_len)
  ------------------
  |  Branch (559:9): [True: 0, False: 77.3k]
  ------------------
  560|      0|        o.flags |= M_OPT_FIXED_LEN_PRINT;
  ------------------
  |  |  482|      0|#define M_OPT_FIXED_LEN_PRINT   (UINT64_C(1) << 55)
  ------------------
  561|  77.3k|    if (opt->type->pretty_print)
  ------------------
  |  Branch (561:9): [True: 0, False: 77.3k]
  ------------------
  562|      0|        return opt->type->pretty_print(&o, val_ptr);
  563|  77.3k|    else
  564|  77.3k|        return m_option_print(&o, val_ptr);
  565|  77.3k|}
m_property.c:m_option_free:
  577|   231k|{
  578|   231k|    if (opt->type->free)
  ------------------
  |  Branch (578:9): [True: 231k, False: 0]
  ------------------
  579|   231k|        opt->type->free(dst);
  580|   231k|}
m_property.c:m_option_print:
  547|   231k|{
  548|   231k|    if (opt->type->print)
  ------------------
  |  Branch (548:9): [True: 231k, False: 0]
  ------------------
  549|   231k|        return opt->type->print(opt, val_ptr);
  550|      0|    else
  551|      0|        return NULL;
  552|   231k|}

m_property_list_find:
   65|   541k|{
   66|  5.95M|    for (int n = 0; list && list[n].name; n++) {
  ------------------
  |  Branch (66:21): [True: 5.95M, False: 0]
  |  Branch (66:29): [True: 5.95M, False: 0]
  ------------------
   67|  5.95M|        if (strcmp(list[n].name, name) == 0)
  ------------------
  |  Branch (67:13): [True: 541k, False: 5.41M]
  ------------------
   68|   541k|            return (struct m_property *)&list[n];
   69|  5.95M|    }
   70|      0|    return NULL;
   71|   541k|}
m_property_do:
  100|   231k|{
  101|   231k|    union m_option_value val = m_option_value_default;
  102|   231k|    int r;
  103|       |
  104|   231k|    struct m_option opt = {0};
  105|   231k|    r = do_action(prop_list, name, M_PROPERTY_GET_TYPE, &opt, ctx);
  106|   231k|    if (r <= 0)
  ------------------
  |  Branch (106:9): [True: 0, False: 231k]
  ------------------
  107|      0|        return r;
  108|   231k|    mp_assert(opt.type);
  ------------------
  |  |   41|   231k|#define mp_assert assert
  ------------------
  109|       |
  110|   231k|    switch (action) {
  111|      0|    case M_PROPERTY_FIXED_LEN_PRINT:
  ------------------
  |  Branch (111:5): [True: 0, False: 231k]
  ------------------
  112|  77.3k|    case M_PROPERTY_PRINT: {
  ------------------
  |  Branch (112:5): [True: 77.3k, False: 154k]
  ------------------
  113|  77.3k|        if ((r = do_action(prop_list, name, action, arg, ctx)) >= 0)
  ------------------
  |  Branch (113:13): [True: 0, False: 77.3k]
  ------------------
  114|      0|            return r;
  115|       |        // Fallback to m_option
  116|  77.3k|        if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
  ------------------
  |  Branch (116:13): [True: 0, False: 77.3k]
  ------------------
  117|      0|            return r;
  118|  77.3k|        char *str = m_option_pretty_print(&opt, &val, action == M_PROPERTY_FIXED_LEN_PRINT);
  119|  77.3k|        m_option_free(&opt, &val);
  120|  77.3k|        *(char **)arg = str;
  121|  77.3k|        return str != NULL;
  122|  77.3k|    }
  123|   154k|    case M_PROPERTY_GET_STRING: {
  ------------------
  |  Branch (123:5): [True: 154k, False: 77.3k]
  ------------------
  124|   154k|        if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
  ------------------
  |  Branch (124:13): [True: 0, False: 154k]
  ------------------
  125|      0|            return r;
  126|   154k|        char *str = m_option_print(&opt, &val);
  127|   154k|        m_option_free(&opt, &val);
  128|   154k|        *(char **)arg = str;
  129|   154k|        return str != NULL;
  130|   154k|    }
  131|      0|    case M_PROPERTY_SET_STRING: {
  ------------------
  |  Branch (131:5): [True: 0, False: 231k]
  ------------------
  132|      0|        struct mpv_node node = { .format = MPV_FORMAT_STRING, .u.string = arg };
  133|      0|        return m_property_do(log, prop_list, name, M_PROPERTY_SET_NODE, &node, ctx);
  134|   154k|    }
  135|      0|    case M_PROPERTY_MULTIPLY: {
  ------------------
  |  Branch (135:5): [True: 0, False: 231k]
  ------------------
  136|      0|        return m_property_multiply(log, prop_list, name, *(double *)arg, ctx);
  137|   154k|    }
  138|      0|    case M_PROPERTY_SWITCH: {
  ------------------
  |  Branch (138:5): [True: 0, False: 231k]
  ------------------
  139|      0|        if (!log)
  ------------------
  |  Branch (139:13): [True: 0, False: 0]
  ------------------
  140|      0|            return M_PROPERTY_ERROR;
  141|      0|        struct m_property_switch_arg *sarg = arg;
  142|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_SWITCH, arg, ctx)) !=
  ------------------
  |  Branch (142:13): [True: 0, False: 0]
  ------------------
  143|      0|            M_PROPERTY_NOT_IMPLEMENTED)
  144|      0|            return r;
  145|       |        // Fallback to m_option
  146|      0|        r = m_property_do(log, prop_list, name, M_PROPERTY_GET_CONSTRICTED_TYPE,
  147|      0|                          &opt, ctx);
  148|      0|        if (r <= 0)
  ------------------
  |  Branch (148:13): [True: 0, False: 0]
  ------------------
  149|      0|            return r;
  150|      0|        mp_assert(opt.type);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  151|      0|        if (!opt.type->add)
  ------------------
  |  Branch (151:13): [True: 0, False: 0]
  ------------------
  152|      0|            return M_PROPERTY_NOT_IMPLEMENTED;
  153|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
  ------------------
  |  Branch (153:13): [True: 0, False: 0]
  ------------------
  154|      0|            return r;
  155|      0|        opt.type->add(&opt, &val, sarg->inc, sarg->wrap);
  156|      0|        r = do_action(prop_list, name, M_PROPERTY_SET, &val, ctx);
  157|      0|        m_option_free(&opt, &val);
  158|      0|        return r;
  159|      0|    }
  160|      0|    case M_PROPERTY_GET_CONSTRICTED_TYPE: {
  ------------------
  |  Branch (160:5): [True: 0, False: 231k]
  ------------------
  161|      0|        r = do_action(prop_list, name, action, arg, ctx);
  162|      0|        if (r >= 0 || r == M_PROPERTY_UNAVAILABLE)
  ------------------
  |  Branch (162:13): [True: 0, False: 0]
  |  Branch (162:23): [True: 0, False: 0]
  ------------------
  163|      0|            return r;
  164|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_GET_TYPE, arg, ctx)) >= 0)
  ------------------
  |  Branch (164:13): [True: 0, False: 0]
  ------------------
  165|      0|            return r;
  166|      0|        return M_PROPERTY_NOT_IMPLEMENTED;
  167|      0|    }
  168|      0|    case M_PROPERTY_SET: {
  ------------------
  |  Branch (168:5): [True: 0, False: 231k]
  ------------------
  169|      0|        return do_action(prop_list, name, M_PROPERTY_SET, arg, ctx);
  170|      0|    }
  171|      0|    case M_PROPERTY_GET_NODE: {
  ------------------
  |  Branch (171:5): [True: 0, False: 231k]
  ------------------
  172|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_GET_NODE, arg, ctx)) !=
  ------------------
  |  Branch (172:13): [True: 0, False: 0]
  ------------------
  173|      0|            M_PROPERTY_NOT_IMPLEMENTED)
  174|      0|            return r;
  175|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_GET, &val, ctx)) <= 0)
  ------------------
  |  Branch (175:13): [True: 0, False: 0]
  ------------------
  176|      0|            return r;
  177|      0|        struct mpv_node *node = arg;
  178|      0|        int err = m_option_get_node(&opt, NULL, node, &val);
  179|      0|        if (err == M_OPT_UNKNOWN) {
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (179:13): [True: 0, False: 0]
  ------------------
  180|      0|            r = M_PROPERTY_NOT_IMPLEMENTED;
  181|      0|        } else if (err < 0) {
  ------------------
  |  Branch (181:20): [True: 0, False: 0]
  ------------------
  182|      0|            r = M_PROPERTY_INVALID_FORMAT;
  183|      0|        } else {
  184|      0|            r = M_PROPERTY_OK;
  185|      0|        }
  186|      0|        m_option_free(&opt, &val);
  187|      0|        return r;
  188|      0|    }
  189|      0|    case M_PROPERTY_SET_NODE: {
  ------------------
  |  Branch (189:5): [True: 0, False: 231k]
  ------------------
  190|      0|        if (!log)
  ------------------
  |  Branch (190:13): [True: 0, False: 0]
  ------------------
  191|      0|            return M_PROPERTY_ERROR;
  192|      0|        if ((r = do_action(prop_list, name, M_PROPERTY_SET_NODE, arg, ctx)) !=
  ------------------
  |  Branch (192:13): [True: 0, False: 0]
  ------------------
  193|      0|            M_PROPERTY_NOT_IMPLEMENTED)
  194|      0|            return r;
  195|      0|        int err = m_option_set_node_or_string(log, &opt, name, &val, arg);
  196|      0|        if (err == M_OPT_UNKNOWN) {
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (196:13): [True: 0, False: 0]
  ------------------
  197|      0|            r = M_PROPERTY_NOT_IMPLEMENTED;
  198|      0|        } else if (err < 0) {
  ------------------
  |  Branch (198:20): [True: 0, False: 0]
  ------------------
  199|      0|            r = M_PROPERTY_INVALID_FORMAT;
  200|      0|        } else {
  201|      0|            r = do_action(prop_list, name, M_PROPERTY_SET, &val, ctx);
  202|      0|        }
  203|      0|        m_option_free(&opt, &val);
  204|      0|        return r;
  205|      0|    }
  206|      0|    default:
  ------------------
  |  Branch (206:5): [True: 0, False: 231k]
  ------------------
  207|      0|        return do_action(prop_list, name, action, arg, ctx);
  208|   231k|    }
  209|   231k|}
m_properties_expand_string:
  290|  77.3k|{
  291|  77.3k|    char *ret = NULL;
  292|  77.3k|    int ret_len = 0;
  293|  77.3k|    bool skip = false;
  294|  77.3k|    int level = 0, skip_level = 0;
  295|  77.3k|    bstr str = bstr0(str0);
  296|  77.3k|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  297|  77.3k|    int n = 0;
  298|  77.3k|#endif
  299|       |
  300|  1.54M|    while (str.len) {
  ------------------
  |  Branch (300:12): [True: 1.46M, False: 77.3k]
  ------------------
  301|  1.46M|        if (level > 0 && bstr_eatstart0(&str, "}")) {
  ------------------
  |  Branch (301:13): [True: 850k, False: 618k]
  |  Branch (301:26): [True: 231k, False: 618k]
  ------------------
  302|   231k|            if (skip && level <= skip_level)
  ------------------
  |  Branch (302:17): [True: 154k, False: 77.3k]
  |  Branch (302:25): [True: 154k, False: 0]
  ------------------
  303|   154k|                skip = false;
  304|   231k|            level--;
  305|  1.23M|        } else if (bstr_startswith0(str, "${") && bstr_find0(str, "}") >= 0) {
  ------------------
  |  Branch (305:20): [True: 231k, False: 1.00M]
  |  Branch (305:51): [True: 231k, False: 0]
  ------------------
  306|   231k|            str = bstr_cut(str, 2);
  307|   231k|            level++;
  308|       |
  309|       |            // Assume ":" and "}" can't be part of the property name
  310|       |            // => if ":" comes before "}", it must be for the fallback
  311|   231k|            int term_pos = bstrcspn(str, ":}");
  312|   231k|            bstr name = bstr_splice(str, 0, term_pos < 0 ? str.len : term_pos);
  ------------------
  |  Branch (312:45): [True: 0, False: 231k]
  ------------------
  313|   231k|            str = bstr_cut(str, term_pos);
  314|   231k|            bool have_fallback = bstr_eatstart0(&str, ":");
  315|       |
  316|   231k|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  317|   231k|            if (n++ > 10)
  ------------------
  |  Branch (317:17): [True: 0, False: 231k]
  ------------------
  318|      0|                break;
  319|   231k|#endif
  320|       |
  321|   231k|            if (!skip) {
  ------------------
  |  Branch (321:17): [True: 231k, False: 0]
  ------------------
  322|   231k|                skip = expand_property(prop_list, &ret, &ret_len, name,
  323|   231k|                                       have_fallback, ctx);
  324|   231k|                if (skip)
  ------------------
  |  Branch (324:21): [True: 154k, False: 77.3k]
  ------------------
  325|   154k|                    skip_level = level;
  326|   231k|            }
  327|  1.00M|        } else if (level == 0 && bstr_eatstart0(&str, "$>")) {
  ------------------
  |  Branch (327:20): [True: 463k, False: 541k]
  |  Branch (327:34): [True: 0, False: 463k]
  ------------------
  328|      0|            append_str(&ret, &ret_len, str);
  329|      0|            break;
  330|  1.00M|        } else {
  331|  1.00M|            char c;
  332|       |
  333|       |            // Other combinations, e.g. "$x", are added verbatim
  334|  1.00M|            if (bstr_eatstart0(&str, "$$")) {
  ------------------
  |  Branch (334:17): [True: 0, False: 1.00M]
  ------------------
  335|      0|                c = '$';
  336|  1.00M|            } else if (bstr_eatstart0(&str, "$}")) {
  ------------------
  |  Branch (336:24): [True: 0, False: 1.00M]
  ------------------
  337|      0|                c = '}';
  338|  1.00M|            } else {
  339|  1.00M|                c = str.start[0];
  340|  1.00M|                str = bstr_cut(str, 1);
  341|  1.00M|            }
  342|       |
  343|  1.00M|            if (!skip)
  ------------------
  |  Branch (343:17): [True: 463k, False: 541k]
  ------------------
  344|   463k|                MP_TARRAY_APPEND(NULL, ret, ret_len, c);
  ------------------
  |  |  105|   463k|    do {                                            \
  |  |  106|   463k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|   463k|    do {                                            \
  |  |  |  |   97|   463k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|   463k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|   463k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|   463k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 845, False: 463k]
  |  |  |  |  ------------------
  |  |  |  |   99|   463k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    845|    do {                                                        \
  |  |  |  |  |  |   89|    845|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    845|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    845|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    845|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    845|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    845|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    845|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|   463k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|   463k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|   463k|        (idxvar)++;                                 \
  |  |  109|   463k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  345|  1.00M|        }
  346|  1.46M|    }
  347|       |
  348|  77.3k|    MP_TARRAY_APPEND(NULL, ret, ret_len, '\0');
  ------------------
  |  |  105|  77.3k|    do {                                            \
  |  |  106|  77.3k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  77.3k|    do {                                            \
  |  |  |  |   97|  77.3k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  77.3k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  77.3k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  77.3k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 9, False: 77.3k]
  |  |  |  |  ------------------
  |  |  |  |   99|  77.3k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      9|    do {                                                        \
  |  |  |  |  |  |   89|      9|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      9|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      9|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      9|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      9|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      9|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      9|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  77.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  77.3k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  77.3k|        (idxvar)++;                                 \
  |  |  109|  77.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  349|  77.3k|    return ret;
  350|  77.3k|}
m_property_strdup_ro:
  432|   541k|{
  433|   541k|    if (!var)
  ------------------
  |  Branch (433:9): [True: 0, False: 541k]
  ------------------
  434|      0|        return M_PROPERTY_UNAVAILABLE;
  435|   541k|    switch (action) {
  ------------------
  |  Branch (435:13): [True: 77.3k, False: 463k]
  ------------------
  436|   231k|    case M_PROPERTY_GET:
  ------------------
  |  Branch (436:5): [True: 231k, False: 309k]
  ------------------
  437|   231k|        *(char **)arg = talloc_strdup(NULL, var);
  ------------------
  |  |   50|   231k|#define talloc_strdup                   ta_xstrdup
  ------------------
  438|   231k|        return M_PROPERTY_OK;
  439|   231k|    case M_PROPERTY_GET_TYPE:
  ------------------
  |  Branch (439:5): [True: 231k, False: 309k]
  ------------------
  440|   231k|        *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_STRING};
  ------------------
  |  |  233|   231k|#define CONF_TYPE_STRING        (&m_option_type_string)
  ------------------
  441|   231k|        return M_PROPERTY_OK;
  442|   541k|    }
  443|  77.3k|    return M_PROPERTY_NOT_IMPLEMENTED;
  444|   541k|}
m_property.c:do_action:
   75|   541k|{
   76|   541k|    struct m_property *prop;
   77|   541k|    struct m_property_action_arg ka;
   78|   541k|    const char *sep = strchr(name, '/');
   79|   541k|    if (sep && sep[1]) {
  ------------------
  |  Branch (79:9): [True: 0, False: 541k]
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        char base[128];
   81|      0|        snprintf(base, sizeof(base), "%.*s", (int)(sep - name), name);
   82|      0|        prop = m_property_list_find(prop_list, base);
   83|      0|        ka = (struct m_property_action_arg) {
   84|      0|            .key = sep + 1,
   85|      0|            .action = action,
   86|      0|            .arg = arg,
   87|      0|        };
   88|      0|        action = M_PROPERTY_KEY_ACTION;
   89|      0|        arg = &ka;
   90|      0|    } else
   91|   541k|        prop = m_property_list_find(prop_list, name);
   92|   541k|    if (!prop)
  ------------------
  |  Branch (92:9): [True: 0, False: 541k]
  ------------------
   93|      0|        return M_PROPERTY_UNKNOWN;
   94|   541k|    return prop->call(ctx, prop, action, arg);
   95|   541k|}
m_property.c:expand_property:
  257|   231k|{
  258|   231k|    bool cond_yes = bstr_eatstart0(&prop, "?");
  259|   231k|    bool cond_no = !cond_yes && bstr_eatstart0(&prop, "!");
  ------------------
  |  Branch (259:20): [True: 154k, False: 77.3k]
  |  Branch (259:33): [True: 77.3k, False: 77.3k]
  ------------------
  260|   231k|    bool test = cond_yes || cond_no;
  ------------------
  |  Branch (260:17): [True: 77.3k, False: 154k]
  |  Branch (260:29): [True: 77.3k, False: 77.3k]
  ------------------
  261|   231k|    bool raw = bstr_eatstart0(&prop, "=");
  262|   231k|    bool fixed_len = !raw && bstr_eatstart0(&prop, ">");
  ------------------
  |  Branch (262:22): [True: 231k, False: 0]
  |  Branch (262:30): [True: 0, False: 231k]
  ------------------
  263|   231k|    bstr comp_with = {0};
  264|   231k|    bool comp = test && bstr_split_tok(prop, "==", &prop, &comp_with);
  ------------------
  |  Branch (264:17): [True: 154k, False: 77.3k]
  |  Branch (264:25): [True: 0, False: 154k]
  ------------------
  265|   231k|    if (test && !comp)
  ------------------
  |  Branch (265:9): [True: 154k, False: 77.3k]
  |  Branch (265:17): [True: 154k, False: 0]
  ------------------
  266|   154k|        raw = true;
  267|   231k|    int method = raw ? M_PROPERTY_GET_STRING : M_PROPERTY_PRINT;
  ------------------
  |  Branch (267:18): [True: 154k, False: 77.3k]
  ------------------
  268|   231k|    method = fixed_len ? M_PROPERTY_FIXED_LEN_PRINT : method;
  ------------------
  |  Branch (268:14): [True: 0, False: 231k]
  ------------------
  269|       |
  270|   231k|    char *s = NULL;
  271|   231k|    int r = m_property_do_bstr(prop_list, prop, method, &s, ctx);
  272|   231k|    bool skip;
  273|   231k|    if (comp) {
  ------------------
  |  Branch (273:9): [True: 0, False: 231k]
  ------------------
  274|      0|        skip = ((s && bstr_equals0(comp_with, s)) != cond_yes);
  ------------------
  |  Branch (274:18): [True: 0, False: 0]
  |  Branch (274:23): [True: 0, False: 0]
  ------------------
  275|   231k|    } else if (test) {
  ------------------
  |  Branch (275:16): [True: 154k, False: 77.3k]
  ------------------
  276|   154k|        skip = (!!s != cond_yes);
  277|   154k|    } else {
  278|  77.3k|        skip = !!s;
  279|  77.3k|        char *append = s;
  280|  77.3k|        if (!s && !silent_error && !raw)
  ------------------
  |  Branch (280:13): [True: 0, False: 77.3k]
  |  Branch (280:19): [True: 0, False: 0]
  |  Branch (280:36): [True: 0, False: 0]
  ------------------
  281|      0|            append = (r == M_PROPERTY_UNAVAILABLE) ? "(unavailable)" : "(error)";
  ------------------
  |  Branch (281:22): [True: 0, False: 0]
  ------------------
  282|  77.3k|        append_str(ret, ret_len, bstr0(append));
  283|  77.3k|    }
  284|   231k|    talloc_free(s);
  ------------------
  |  |   47|   231k|#define talloc_free                     ta_free
  ------------------
  285|   231k|    return skip;
  286|   231k|}
m_property.c:m_property_do_bstr:
  240|   231k|{
  241|   231k|    char *name0 = bstrdup0(NULL, name);
  242|   231k|    int ret = m_property_do(NULL, prop_list, name0, action, arg, ctx);
  243|   231k|    talloc_free(name0);
  ------------------
  |  |   47|   231k|#define talloc_free                     ta_free
  ------------------
  244|   231k|    return ret;
  245|   231k|}
m_property.c:append_str:
  248|  77.3k|{
  249|  77.3k|    MP_TARRAY_GROW(NULL, *s, *len + append.len);
  ------------------
  |  |   96|  77.3k|    do {                                            \
  |  |   97|  77.3k|        size_t nextidx_ = (nextidx);                \
  |  |   98|  77.3k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  77.3k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  77.3k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 77.3k, False: 0]
  |  |  ------------------
  |  |   99|  77.3k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|  77.3k|    do {                                                        \
  |  |  |  |   89|  77.3k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|  77.3k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|  77.3k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|  77.3k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|  77.3k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|  77.3k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|  77.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  77.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  250|  77.3k|    if (append.len)
  ------------------
  |  Branch (250:9): [True: 77.3k, False: 0]
  ------------------
  251|  77.3k|        memcpy(*s + *len, append.start, append.len);
  252|  77.3k|    *len = *len + append.len;
  253|  77.3k|}

m_config_parse:
   45|  5.81k|{
   46|  5.81k|    m_profile_t *profile = m_config_add_profile(config, initial_section);
   47|  5.81k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  5.81k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  5.81k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
   48|  5.81k|    int line_no = 0;
   49|  5.81k|    int errors = 0;
   50|       |
   51|  5.81k|    bstr_eatstart0(&data, "\xEF\xBB\xBF"); // skip BOM
   52|       |
   53|   569k|    while (data.len) {
  ------------------
  |  Branch (53:12): [True: 563k, False: 5.81k]
  ------------------
   54|   563k|        talloc_free_children(tmp);
  ------------------
  |  |   46|   563k|#define talloc_free_children            ta_free_children
  ------------------
   55|   563k|        bool ok = false;
   56|       |
   57|   563k|        line_no++;
   58|   563k|        char loc[512];
   59|   563k|        snprintf(loc, sizeof(loc), "%s:%d:", location, line_no);
   60|       |
   61|   563k|        bstr line = bstr_strip_linebreaks(bstr_getline(data, &data));
   62|   563k|        if (!skip_ws(&line))
  ------------------
  |  Branch (62:13): [True: 145k, False: 418k]
  ------------------
   63|   145k|            continue;
   64|       |
   65|       |        // Profile declaration
   66|   418k|        if (bstr_eatstart0(&line, "[")) {
  ------------------
  |  Branch (66:13): [True: 69.7k, False: 348k]
  ------------------
   67|  69.7k|            bstr profilename;
   68|  69.7k|            if (!bstr_split_tok(line, "]", &profilename, &line)) {
  ------------------
  |  Branch (68:17): [True: 0, False: 69.7k]
  ------------------
   69|      0|                MP_ERR(config, "%s missing closing ]\n", loc);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   70|      0|                goto error;
   71|      0|            }
   72|  69.7k|            if (skip_ws(&line)) {
  ------------------
  |  Branch (72:17): [True: 0, False: 69.7k]
  ------------------
   73|      0|                MP_ERR(config, "%s unparsable extra characters: '%.*s'\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   74|      0|                       loc, BSTR_P(line));
   75|      0|                goto error;
   76|      0|            }
   77|  69.7k|            profile = m_config_add_profile(config, bstrto0(tmp, profilename));
   78|  69.7k|            continue;
   79|  69.7k|        }
   80|       |
   81|   348k|        bstr_eatstart0(&line, "--");
   82|       |
   83|   348k|        bstr option = line;
   84|  4.72M|        while (line.len && (mp_isalnum(line.start[0]) || line.start[0] == '_' ||
  ------------------
  |  Branch (84:16): [True: 4.72M, False: 0]
  |  Branch (84:29): [True: 3.99M, False: 726k]
  |  Branch (84:58): [True: 0, False: 726k]
  ------------------
   85|  4.72M|                            line.start[0] == '-'))
  ------------------
  |  Branch (85:29): [True: 377k, False: 348k]
  ------------------
   86|  4.37M|            line = bstr_cut(line, 1);
   87|   348k|        option.len = option.len - line.len;
   88|   348k|        skip_ws(&line);
   89|       |
   90|   348k|        bstr value = {0};
   91|   348k|        if (bstr_eatstart0(&line, "=")) {
  ------------------
  |  Branch (91:13): [True: 348k, False: 0]
  ------------------
   92|   348k|            skip_ws(&line);
   93|   348k|            if (line.len && (line.start[0] == '"' || line.start[0] == '\'')) {
  ------------------
  |  Branch (93:17): [True: 348k, False: 0]
  |  Branch (93:30): [True: 0, False: 348k]
  |  Branch (93:54): [True: 0, False: 348k]
  ------------------
   94|       |                // Simple quoting, like "value"
   95|      0|                char term[2] = {line.start[0], 0};
   96|      0|                line = bstr_cut(line, 1);
   97|      0|                if (!bstr_split_tok(line, term, &value, &line)) {
  ------------------
  |  Branch (97:21): [True: 0, False: 0]
  ------------------
   98|      0|                    MP_ERR(config, "%s unterminated quote\n", loc);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   99|      0|                    goto error;
  100|      0|                }
  101|   348k|            } else if (bstr_eatstart0(&line, "%")) {
  ------------------
  |  Branch (101:24): [True: 0, False: 348k]
  ------------------
  102|       |                // Quoting with length, like %5%value
  103|      0|                bstr rest;
  104|      0|                long long len = bstrtoll(line, &rest, 10);
  105|      0|                if (rest.len == line.len || !bstr_eatstart0(&rest, "%") ||
  ------------------
  |  Branch (105:21): [True: 0, False: 0]
  |  Branch (105:45): [True: 0, False: 0]
  ------------------
  106|      0|                    len > rest.len)
  ------------------
  |  Branch (106:21): [True: 0, False: 0]
  ------------------
  107|      0|                {
  108|      0|                    MP_ERR(config, "%s fixed-length quoting expected - put "
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  109|      0|                           "\"quotes\" around the option value if you did not "
  110|      0|                           "intend to use this, but your option value starts "
  111|      0|                           "with '%%'\n", loc);
  112|      0|                    goto error;
  113|      0|                }
  114|      0|                value = bstr_splice(rest, 0, len);
  115|      0|                line = bstr_cut(rest, len);
  116|   348k|            } else {
  117|       |                // No quoting; take everything until the comment or end of line
  118|   348k|                int end = bstrchr(line, '#');
  119|   348k|                value = bstr_strip(end < 0 ? line : bstr_splice(line, 0, end));
  ------------------
  |  Branch (119:36): [True: 290k, False: 58.1k]
  ------------------
  120|   348k|                line.len = 0;
  121|   348k|            }
  122|   348k|        }
  123|   348k|        if (skip_ws(&line)) {
  ------------------
  |  Branch (123:13): [True: 0, False: 348k]
  ------------------
  124|      0|            MP_ERR(config, "%s unparsable extra characters: '%.*s'\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  125|      0|                   loc, BSTR_P(line));
  126|      0|            goto error;
  127|      0|        }
  128|       |
  129|   348k|        int res = m_config_set_profile_option(config, profile, option, value);
  130|   348k|        if (res < 0) {
  ------------------
  |  Branch (130:13): [True: 23.2k, False: 325k]
  ------------------
  131|  23.2k|            MP_ERR(config, "%s setting option %.*s='%.*s' failed.\n",
  ------------------
  |  |   85|  23.2k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  92.9k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 23.2k, False: 0]
  |  |  |  |  |  Branch (82:57): [True: 23.2k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|  23.2k|                   loc, BSTR_P(option), BSTR_P(value));
  133|  23.2k|            goto error;
  134|  23.2k|        }
  135|       |
  136|   325k|        ok = true;
  137|   348k|    error:
  138|   348k|        if (!ok)
  ------------------
  |  Branch (138:13): [True: 23.2k, False: 325k]
  ------------------
  139|  23.2k|            errors++;
  140|   348k|        if (errors > 16) {
  ------------------
  |  Branch (140:13): [True: 0, False: 348k]
  ------------------
  141|      0|            MP_ERR(config, "%s: too many errors, stopping.\n", location);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  142|      0|            break;
  143|      0|        }
  144|   348k|    }
  145|       |
  146|  5.81k|    if (config->recursion_depth == 0)
  ------------------
  |  Branch (146:9): [True: 5.81k, False: 0]
  ------------------
  147|  5.81k|        m_config_finish_default_profile(config, flags);
  148|       |
  149|  5.81k|    talloc_free(tmp);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  150|  5.81k|    return 1;
  151|  5.81k|}
parse_configfile.c:skip_ws:
   36|  1.67M|{
   37|  1.67M|    *s = bstr_lstrip(*s);
   38|  1.67M|    if (bstr_startswith0(*s, "#"))
  ------------------
  |  Branch (38:9): [True: 69.7k, False: 1.60M]
  ------------------
   39|  69.7k|        s->len = 0;
   40|  1.67M|    return s->len;
   41|  1.67M|}

mp_init_paths:
  109|  5.81k|{
  110|  5.81k|    TA_FREEP(&global->configdir);
  ------------------
  |  |   81|  5.81k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  5.81k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  111|       |
  112|  5.81k|    const char *force_configdir = getenv("MPV_HOME");
  113|  5.81k|    if (opts->force_configdir && opts->force_configdir[0])
  ------------------
  |  Branch (113:9): [True: 0, False: 5.81k]
  |  Branch (113:34): [True: 0, False: 0]
  ------------------
  114|      0|        force_configdir = opts->force_configdir;
  115|  5.81k|    if (!opts->load_config)
  ------------------
  |  Branch (115:9): [True: 5.81k, False: 0]
  ------------------
  116|  5.81k|        force_configdir = "";
  117|       |
  118|  5.81k|    global->configdir = mp_get_user_path(global, global, force_configdir);
  119|  5.81k|}
mp_find_user_file:
  123|   107k|{
  124|   107k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|   107k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|   107k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  125|   107k|    char *res = (char *)mp_get_platform_path(tmp, global, type);
  126|   107k|    if (res)
  ------------------
  |  Branch (126:9): [True: 0, False: 107k]
  ------------------
  127|      0|        res = mp_path_join(talloc_ctx, res, filename);
  128|   107k|    talloc_free(tmp);
  ------------------
  |  |   47|   107k|#define talloc_free                     ta_free
  ------------------
  129|   107k|    MP_DBG(global, "%s path: '%s' -> '%s'\n", type, filename, res ? res : "-");
  ------------------
  |  |   89|   107k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   214k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 107k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  130|   107k|    return res;
  131|   107k|}
mp_find_all_config_files:
  170|  23.2k|{
  171|  23.2k|    return mp_find_all_config_files_limited(talloc_ctx, global, 64, filename);
  172|  23.2k|}
mp_find_config_file:
  176|  4.53k|{
  177|  4.53k|    char **l = mp_find_all_config_files_limited(talloc_ctx, global, 1, filename);
  178|  4.53k|    char *r = l && l[0] ? talloc_steal(talloc_ctx, l[0]) : NULL;
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  |  Branch (178:15): [True: 4.53k, False: 0]
  |  Branch (178:20): [True: 0, False: 4.53k]
  ------------------
  179|  4.53k|    talloc_free(l);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  180|  4.53k|    return r;
  181|  4.53k|}
mp_get_user_path:
  185|  52.2k|{
  186|  52.2k|    if (!path)
  ------------------
  |  Branch (186:9): [True: 29.0k, False: 23.2k]
  ------------------
  187|  29.0k|        return NULL;
  188|  23.2k|    char *res = NULL;
  189|  23.2k|    bstr bpath = bstr0(path);
  190|  23.2k|    if (bstr_eatstart0(&bpath, "~")) {
  ------------------
  |  Branch (190:9): [True: 11.6k, False: 11.6k]
  ------------------
  191|       |        // parse to "~" <prefix> "/" <rest>
  192|  11.6k|        bstr prefix, rest;
  193|  11.6k|        if (bstr_split_tok(bpath, "/", &prefix, &rest)) {
  ------------------
  |  Branch (193:13): [True: 11.6k, False: 0]
  ------------------
  194|  11.6k|            const char *rest0 = rest.start; // ok in this case
  195|  11.6k|            if (bstr_equals0(prefix, "~")) {
  ------------------
  |  Branch (195:17): [True: 0, False: 11.6k]
  ------------------
  196|      0|                res = mp_find_config_file(talloc_ctx, global, rest0);
  197|      0|                if (!res) {
  ------------------
  |  Branch (197:21): [True: 0, False: 0]
  ------------------
  198|      0|                    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|      0|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      0|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  199|      0|                    const char *p = mp_get_platform_path(tmp, global, "home");
  200|      0|                    res = mp_path_join_bstr(talloc_ctx, bstr0(p), rest);
  201|      0|                    talloc_free(tmp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  202|      0|                }
  203|  11.6k|            } else if (bstr_equals0(prefix, "")) {
  ------------------
  |  Branch (203:24): [True: 0, False: 11.6k]
  ------------------
  204|      0|                char *home = getenv("HOME");
  205|      0|                if (!home)
  ------------------
  |  Branch (205:21): [True: 0, False: 0]
  ------------------
  206|      0|                    home = getenv("USERPROFILE");
  207|      0|                res = mp_path_join_bstr(talloc_ctx, bstr0(home), rest);
  208|  11.6k|            } else if (bstr_eatstart0(&prefix, "~")) {
  ------------------
  |  Branch (208:24): [True: 11.6k, False: 0]
  ------------------
  209|  11.6k|                void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  11.6k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  11.6k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  210|  11.6k|                char type[80];
  211|  11.6k|                snprintf(type, sizeof(type), "%.*s", BSTR_P(prefix));
  ------------------
  |  |  283|  11.6k|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 11.6k, False: 0]
  |  |  ------------------
  ------------------
  212|  11.6k|                const char *p = mp_get_platform_path(tmp, global, type);
  213|  11.6k|                res = mp_path_join_bstr(talloc_ctx, bstr0(p), rest);
  214|  11.6k|                talloc_free(tmp);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
  215|  11.6k|            }
  216|  11.6k|        }
  217|  11.6k|    }
  218|  23.2k|    if (!res) {
  ------------------
  |  Branch (218:9): [True: 11.6k, False: 11.6k]
  ------------------
  219|  11.6k|        res = talloc_strdup(talloc_ctx, path);
  ------------------
  |  |   50|  11.6k|#define talloc_strdup                   ta_xstrdup
  ------------------
  220|  11.6k|    } else {
  221|  11.6k|        MP_DBG(global, "user path: '%s' -> '%s'\n", path, res);
  ------------------
  |  |   89|  11.6k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  11.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  222|  11.6k|    }
  223|  23.2k|    return res;
  224|  52.2k|}
mp_mk_user_dir:
  236|  5.81k|{
  237|  5.81k|    char *dir = mp_find_user_file(NULL, global, type, subdir);
  238|  5.81k|    if (dir)
  ------------------
  |  Branch (238:9): [True: 0, False: 5.81k]
  ------------------
  239|      0|        mp_mkdirp(dir);
  240|  5.81k|    talloc_free(dir);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  241|  5.81k|}
path.c:mp_get_platform_path:
   74|   257k|{
   75|   257k|    mp_assert(talloc_ctx);
  ------------------
  |  |   41|   257k|#define mp_assert assert
  ------------------
   76|       |
   77|   257k|    if (global->configdir) {
  ------------------
  |  Branch (77:9): [True: 257k, False: 0]
  ------------------
   78|       |        // Return NULL for all platform paths if --no-config is passed
   79|   257k|        if (!global->configdir[0])
  ------------------
  |  Branch (79:13): [True: 257k, False: 0]
  ------------------
   80|   257k|            return NULL;
   81|       |
   82|       |        // force all others to NULL, only first returns the path
   83|      0|        for (int n = 0; n < MP_ARRAY_SIZE(config_dirs); n++) {
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (83:25): [True: 0, False: 0]
  ------------------
   84|      0|            if (strcmp(config_dirs[n], type) == 0)
  ------------------
  |  Branch (84:17): [True: 0, False: 0]
  ------------------
   85|      0|                return (n == 0) ? global->configdir : NULL;
  ------------------
  |  Branch (85:24): [True: 0, False: 0]
  ------------------
   86|      0|        }
   87|      0|    }
   88|       |
   89|       |    // Return the native config path if the platform doesn't support the
   90|       |    // type we are trying to fetch.
   91|      0|    const char *fallback_type = NULL;
   92|      0|    if (!strcmp(type, "cache") || !strcmp(type, "state"))
  ------------------
  |  Branch (92:9): [True: 0, False: 0]
  |  Branch (92:35): [True: 0, False: 0]
  ------------------
   93|      0|        fallback_type = "home";
   94|       |
   95|      0|    for (int n = 0; n < MP_ARRAY_SIZE(path_resolvers); n++) {
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (95:21): [True: 0, False: 0]
  ------------------
   96|      0|        const char *path = path_resolvers[n](talloc_ctx, type);
   97|      0|        if (path && path[0])
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  |  Branch (97:21): [True: 0, False: 0]
  ------------------
   98|      0|            return path;
   99|      0|    }
  100|       |
  101|      0|    if (fallback_type) {
  ------------------
  |  Branch (101:9): [True: 0, False: 0]
  ------------------
  102|      0|        mp_assert(strcmp(fallback_type, type) != 0);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  103|      0|        return mp_get_platform_path(talloc_ctx, global, fallback_type);
  104|      0|    }
  105|      0|    return NULL;
  106|      0|}
path.c:mp_find_all_config_files_limited:
  137|  27.7k|{
  138|  27.7k|    char **ret = talloc_array(talloc_ctx, char*, 2); // 2 preallocated
  ------------------
  |  |   29|  27.7k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  27.7k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  27.7k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  139|  27.7k|    int num_ret = 0;
  140|       |
  141|   166k|    for (int i = 0; i < MP_ARRAY_SIZE(config_dirs); i++) {
  ------------------
  |  |   48|   166k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (141:21): [True: 138k, False: 27.7k]
  ------------------
  142|   138k|        const char *dir = mp_get_platform_path(ret, global, config_dirs[i]);
  143|   138k|        bstr s = bstr0(filename);
  144|   138k|        while (dir && num_ret < max_files && s.len) {
  ------------------
  |  Branch (144:16): [True: 0, False: 138k]
  |  Branch (144:23): [True: 0, False: 0]
  |  Branch (144:46): [True: 0, False: 0]
  ------------------
  145|      0|            bstr fn;
  146|      0|            bstr_split_tok(s, "|", &fn, &s);
  147|       |
  148|      0|            char *file = mp_path_join_bstr(ret, bstr0(dir), fn);
  149|      0|            if (mp_path_exists(file)) {
  ------------------
  |  Branch (149:17): [True: 0, False: 0]
  ------------------
  150|      0|                MP_DBG(global, "config path: '%.*s' -> '%s'\n",
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  151|      0|                        BSTR_P(fn), file);
  152|      0|                MP_TARRAY_APPEND(NULL, ret, num_ret, file);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  153|      0|            } else {
  154|      0|                MP_DBG(global, "config path: '%.*s' -/-> '%s'\n",
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  155|      0|                        BSTR_P(fn), file);
  156|      0|            }
  157|      0|        }
  158|   138k|    }
  159|       |
  160|  27.7k|    MP_TARRAY_GROW(NULL, ret, num_ret);
  ------------------
  |  |   96|  27.7k|    do {                                            \
  |  |   97|  27.7k|        size_t nextidx_ = (nextidx);                \
  |  |   98|  27.7k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|  27.7k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|  27.7k|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 27.7k]
  |  |  ------------------
  |  |   99|  27.7k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|  27.7k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  161|  27.7k|    ret[num_ret] = NULL;
  162|       |
  163|  27.7k|    for (int n = 0; n < num_ret / 2; n++)
  ------------------
  |  Branch (163:21): [True: 0, False: 27.7k]
  ------------------
  164|      0|        MPSWAP(char*, ret[n], ret[num_ret - n - 1]);
  ------------------
  |  |   47|      0|    do { type SWAP_tmp = b; b = a; a = SWAP_tmp; } while (0)
  |  |  ------------------
  |  |  |  Branch (47:59): [Folded - Ignored]
  |  |  ------------------
  ------------------
  165|  27.7k|    return ret;
  166|  27.7k|}

mp_get_user_langs:
   26|  4.53k|{
   27|  4.53k|    static const char *const list[] = {
   28|  4.53k|        "LC_ALL",
   29|  4.53k|        "LC_MESSAGES",
   30|  4.53k|        "LANG",
   31|  4.53k|        NULL
   32|  4.53k|    };
   33|       |
   34|  4.53k|    size_t nb = 0;
   35|  4.53k|    char **ret = NULL;
   36|  4.53k|    bool has_c = false;
   37|       |
   38|       |    // Prefer anything we get from LANGUAGE first
   39|  4.53k|    for (const char *langList = getenv("LANGUAGE"); langList && *langList;) {
  ------------------
  |  Branch (39:53): [True: 0, False: 4.53k]
  |  Branch (39:65): [True: 0, False: 0]
  ------------------
   40|      0|        size_t len = strcspn(langList, ":");
   41|      0|        MP_TARRAY_GROW(NULL, ret, nb);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   42|      0|        char *lang = talloc_strndup(ret, langList, len);
  ------------------
  |  |   51|      0|#define talloc_strndup                  ta_xstrndup
  ------------------
   43|      0|        for (int i = 0; i < len; i++) {
  ------------------
  |  Branch (43:25): [True: 0, False: 0]
  ------------------
   44|      0|            if (lang[i] == '_')
  ------------------
  |  Branch (44:17): [True: 0, False: 0]
  ------------------
   45|      0|                lang[i] = '-';
   46|      0|        }
   47|      0|        ret[nb++] = lang;
   48|      0|        langList += len;
   49|      0|        while (*langList == ':')
  ------------------
  |  Branch (49:16): [True: 0, False: 0]
  ------------------
   50|      0|            langList++;
   51|      0|    }
   52|       |
   53|       |    // Then, the language components of other relevant locale env vars
   54|  18.1k|    for (int i = 0; list[i]; i++) {
  ------------------
  |  Branch (54:21): [True: 13.6k, False: 4.53k]
  ------------------
   55|  13.6k|        const char *envval = getenv(list[i]);
   56|  13.6k|        if (envval && *envval) {
  ------------------
  |  Branch (56:13): [True: 0, False: 13.6k]
  |  Branch (56:23): [True: 0, False: 0]
  ------------------
   57|      0|            size_t len = strcspn(envval, ".@");
   58|      0|            if (!strncmp("C", envval, len)) {
  ------------------
  |  Branch (58:17): [True: 0, False: 0]
  ------------------
   59|      0|                has_c = true;
   60|      0|                continue;
   61|      0|            }
   62|       |
   63|      0|            MP_TARRAY_GROW(NULL, ret, nb);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   64|      0|            char *lang = talloc_strndup(ret, envval, len);
  ------------------
  |  |   51|      0|#define talloc_strndup                  ta_xstrndup
  ------------------
   65|      0|            for (int j = 0; j < len; j++) {
  ------------------
  |  Branch (65:29): [True: 0, False: 0]
  ------------------
   66|      0|                if (lang[j] == '_')
  ------------------
  |  Branch (66:21): [True: 0, False: 0]
  ------------------
   67|      0|                    lang[j] = '-';
   68|      0|            }
   69|       |
   70|      0|            ret[nb++] = lang;
   71|      0|        }
   72|  13.6k|    }
   73|       |
   74|  4.53k|    if (has_c && !nb) {
  ------------------
  |  Branch (74:9): [True: 0, False: 4.53k]
  |  Branch (74:18): [True: 0, False: 0]
  ------------------
   75|      0|        MP_TARRAY_GROW(NULL, ret, nb);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   76|      0|        ret[nb++] = talloc_strdup(ret, "en");
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
   77|      0|    }
   78|       |
   79|       |    // Null-terminate the list
   80|  4.53k|    MP_TARRAY_APPEND(NULL, ret, nb, NULL);
  ------------------
  |  |  105|  4.53k|    do {                                            \
  |  |  106|  4.53k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.53k|    do {                                            \
  |  |  |  |   97|  4.53k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.53k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.53k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.53k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.53k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.53k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.53k|    do {                                                        \
  |  |  |  |  |  |   89|  4.53k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.53k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.53k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.53k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.53k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.53k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.53k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.53k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.53k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.53k|        (idxvar)++;                                 \
  |  |  109|  4.53k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   81|       |
   82|  4.53k|    return ret;
   83|  4.53k|}

client.c:mp_mutex_init:
  110|  17.4k|{
  111|  17.4k|#ifndef NDEBUG
  112|  17.4k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  17.4k|    int ret = 0;
  118|  17.4k|    pthread_mutexattr_t attr;
  119|  17.4k|    ret = pthread_mutexattr_init(&attr);
  120|  17.4k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 17.4k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  17.4k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  17.4k|    ret = pthread_mutex_init(mutex, &attr);
  125|  17.4k|    pthread_mutexattr_destroy(&attr);
  126|  17.4k|    mp_assert(!ret);
  ------------------
  |  |   41|  17.4k|#define mp_assert assert
  ------------------
  127|  17.4k|    return ret;
  128|  17.4k|}
client.c:mp_cond_init:
  136|  5.81k|{
  137|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  138|       |
  139|  5.81k|    int ret = 0;
  140|  5.81k|    pthread_condattr_t attr;
  141|  5.81k|    ret = pthread_condattr_init(&attr);
  142|  5.81k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 5.81k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  5.81k|    cond->clk_id = CLOCK_REALTIME;
  146|  5.81k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  5.81k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 5.81k, False: 0]
  ------------------
  148|  5.81k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  5.81k|#endif
  150|       |
  151|  5.81k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  5.81k|    pthread_condattr_destroy(&attr);
  153|  5.81k|    return ret;
  154|  5.81k|}
client.c:mp_cond_timedwait_until:
  202|  77.4k|{
  203|  77.4k|    return mp_cond_timedwait(cond, mutex, until - mp_time_ns());
  204|  77.4k|}
client.c:mp_cond_timedwait:
  181|  77.4k|{
  182|  77.4k|    mp_assert(cond);
  ------------------
  |  |   41|  77.4k|#define mp_assert assert
  ------------------
  183|       |
  184|  77.4k|    timeout = MPMAX(0, timeout);
  ------------------
  |  |   43|  77.4k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 77.4k]
  |  |  ------------------
  ------------------
  185|       |    // consider anything above 1000 days as infinity
  186|  77.4k|    if (timeout > MP_TIME_S_TO_NS(1000 * 24 * 60 * 60))
  ------------------
  |  |   59|  77.4k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (186:9): [True: 51.9k, False: 25.5k]
  ------------------
  187|  51.9k|        return pthread_cond_wait(&cond->cond, mutex);
  188|       |
  189|  25.5k|    struct timespec ts;
  190|  25.5k|    clock_gettime(cond->clk_id, &ts);
  191|  25.5k|    ts.tv_sec  += timeout / MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  25.5k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  192|  25.5k|    ts.tv_nsec += timeout % MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  25.5k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  193|  25.5k|    if (ts.tv_nsec >= MP_TIME_S_TO_NS(1)) {
  ------------------
  |  |   59|  25.5k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (193:9): [True: 25.5k, False: 0]
  ------------------
  194|  25.5k|        ts.tv_nsec -= MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  25.5k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  195|  25.5k|        ts.tv_sec++;
  196|  25.5k|    }
  197|       |
  198|  25.5k|    return pthread_cond_timedwait(&cond->cond, mutex, &ts);
  199|  77.4k|}
client.c:mp_cond_destroy:
  157|  5.81k|{
  158|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  159|  5.81k|    return pthread_cond_destroy(&cond->cond);
  160|  5.81k|}
client.c:mp_thread_set_name:
  219|  5.81k|{
  220|  5.81k|#if HAVE_GLIBC_THREAD_NAME
  221|  5.81k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 5.81k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  5.81k|}
client.c:mp_cond_broadcast:
  163|  98.4k|{
  164|  98.4k|    mp_assert(cond);
  ------------------
  |  |   41|  98.4k|#define mp_assert assert
  ------------------
  165|  98.4k|    return pthread_cond_broadcast(&cond->cond);
  166|  98.4k|}
loadfile.c:mp_thread_set_name:
  219|  7.51k|{
  220|  7.51k|#if HAVE_GLIBC_THREAD_NAME
  221|  7.51k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 7.51k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  7.51k|}
main.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
osd.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
vo.c:mp_mutex_init:
  110|  5.56k|{
  111|  5.56k|#ifndef NDEBUG
  112|  5.56k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.56k|    int ret = 0;
  118|  5.56k|    pthread_mutexattr_t attr;
  119|  5.56k|    ret = pthread_mutexattr_init(&attr);
  120|  5.56k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.56k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.56k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.56k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.56k|    pthread_mutexattr_destroy(&attr);
  126|  5.56k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.56k|#define mp_assert assert
  ------------------
  127|  5.56k|    return ret;
  128|  5.56k|}
vo.c:mp_cond_init:
  136|  2.78k|{
  137|  2.78k|    mp_assert(cond);
  ------------------
  |  |   41|  2.78k|#define mp_assert assert
  ------------------
  138|       |
  139|  2.78k|    int ret = 0;
  140|  2.78k|    pthread_condattr_t attr;
  141|  2.78k|    ret = pthread_condattr_init(&attr);
  142|  2.78k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 2.78k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  2.78k|    cond->clk_id = CLOCK_REALTIME;
  146|  2.78k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  2.78k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 2.78k, False: 0]
  ------------------
  148|  2.78k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  2.78k|#endif
  150|       |
  151|  2.78k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  2.78k|    pthread_condattr_destroy(&attr);
  153|  2.78k|    return ret;
  154|  2.78k|}
vo.c:mp_thread_set_name:
  219|  2.78k|{
  220|  2.78k|#if HAVE_GLIBC_THREAD_NAME
  221|  2.78k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 2.78k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  2.78k|}
vo.c:mp_cond_broadcast:
  163|   236k|{
  164|   236k|    mp_assert(cond);
  ------------------
  |  |   41|   236k|#define mp_assert assert
  ------------------
  165|   236k|    return pthread_cond_broadcast(&cond->cond);
  166|   236k|}
vo.c:mp_cond_destroy:
  157|  2.78k|{
  158|  2.78k|    mp_assert(cond);
  ------------------
  |  |   41|  2.78k|#define mp_assert assert
  ------------------
  159|  2.78k|    return pthread_cond_destroy(&cond->cond);
  160|  2.78k|}
vo.c:mp_cond_timedwait_until:
  202|   112k|{
  203|   112k|    return mp_cond_timedwait(cond, mutex, until - mp_time_ns());
  204|   112k|}
vo.c:mp_cond_timedwait:
  181|   112k|{
  182|   112k|    mp_assert(cond);
  ------------------
  |  |   41|   112k|#define mp_assert assert
  ------------------
  183|       |
  184|   112k|    timeout = MPMAX(0, timeout);
  ------------------
  |  |   43|   112k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 112k]
  |  |  ------------------
  ------------------
  185|       |    // consider anything above 1000 days as infinity
  186|   112k|    if (timeout > MP_TIME_S_TO_NS(1000 * 24 * 60 * 60))
  ------------------
  |  |   59|   112k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (186:9): [True: 0, False: 112k]
  ------------------
  187|      0|        return pthread_cond_wait(&cond->cond, mutex);
  188|       |
  189|   112k|    struct timespec ts;
  190|   112k|    clock_gettime(cond->clk_id, &ts);
  191|   112k|    ts.tv_sec  += timeout / MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   112k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  192|   112k|    ts.tv_nsec += timeout % MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   112k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  193|   112k|    if (ts.tv_nsec >= MP_TIME_S_TO_NS(1)) {
  ------------------
  |  |   59|   112k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (193:9): [True: 112k, False: 0]
  ------------------
  194|   112k|        ts.tv_nsec -= MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   112k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  195|   112k|        ts.tv_sec++;
  196|   112k|    }
  197|       |
  198|   112k|    return pthread_cond_timedwait(&cond->cond, mutex, &ts);
  199|   112k|}
vo.c:mp_cond_wait:
  175|    561|{
  176|    561|    mp_assert(cond);
  ------------------
  |  |   41|    561|#define mp_assert assert
  ------------------
  177|    561|    return pthread_cond_wait(&cond->cond, mutex);
  178|    561|}
buffer.c:mp_cond_broadcast:
  163|   360k|{
  164|   360k|    mp_assert(cond);
  ------------------
  |  |   41|   360k|#define mp_assert assert
  ------------------
  165|   360k|    return pthread_cond_broadcast(&cond->cond);
  166|   360k|}
buffer.c:mp_cond_timedwait:
  181|   300k|{
  182|   300k|    mp_assert(cond);
  ------------------
  |  |   41|   300k|#define mp_assert assert
  ------------------
  183|       |
  184|   300k|    timeout = MPMAX(0, timeout);
  ------------------
  |  |   43|   300k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 300k]
  |  |  ------------------
  ------------------
  185|       |    // consider anything above 1000 days as infinity
  186|   300k|    if (timeout > MP_TIME_S_TO_NS(1000 * 24 * 60 * 60))
  ------------------
  |  |   59|   300k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (186:9): [True: 2.92k, False: 297k]
  ------------------
  187|  2.92k|        return pthread_cond_wait(&cond->cond, mutex);
  188|       |
  189|   297k|    struct timespec ts;
  190|   297k|    clock_gettime(cond->clk_id, &ts);
  191|   297k|    ts.tv_sec  += timeout / MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   297k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  192|   297k|    ts.tv_nsec += timeout % MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   297k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  193|   297k|    if (ts.tv_nsec >= MP_TIME_S_TO_NS(1)) {
  ------------------
  |  |   59|   297k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (193:9): [True: 17.6k, False: 280k]
  ------------------
  194|  17.6k|        ts.tv_nsec -= MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  17.6k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  195|  17.6k|        ts.tv_sec++;
  196|  17.6k|    }
  197|       |
  198|   297k|    return pthread_cond_timedwait(&cond->cond, mutex, &ts);
  199|   300k|}
buffer.c:mp_cond_destroy:
  157|  2.70k|{
  158|  2.70k|    mp_assert(cond);
  ------------------
  |  |   41|  2.70k|#define mp_assert assert
  ------------------
  159|  2.70k|    return pthread_cond_destroy(&cond->cond);
  160|  2.70k|}
buffer.c:mp_mutex_init:
  110|  2.69k|{
  111|  2.69k|#ifndef NDEBUG
  112|  2.69k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  2.69k|    int ret = 0;
  118|  2.69k|    pthread_mutexattr_t attr;
  119|  2.69k|    ret = pthread_mutexattr_init(&attr);
  120|  2.69k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 2.69k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  2.69k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  2.69k|    ret = pthread_mutex_init(mutex, &attr);
  125|  2.69k|    pthread_mutexattr_destroy(&attr);
  126|  2.69k|    mp_assert(!ret);
  ------------------
  |  |   41|  2.69k|#define mp_assert assert
  ------------------
  127|  2.69k|    return ret;
  128|  2.69k|}
buffer.c:mp_cond_init:
  136|  2.69k|{
  137|  2.69k|    mp_assert(cond);
  ------------------
  |  |   41|  2.69k|#define mp_assert assert
  ------------------
  138|       |
  139|  2.69k|    int ret = 0;
  140|  2.69k|    pthread_condattr_t attr;
  141|  2.69k|    ret = pthread_condattr_init(&attr);
  142|  2.69k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 2.69k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  2.69k|    cond->clk_id = CLOCK_REALTIME;
  146|  2.69k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  2.69k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 2.69k, False: 0]
  ------------------
  148|  2.69k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  2.69k|#endif
  150|       |
  151|  2.69k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  2.69k|    pthread_condattr_destroy(&attr);
  153|  2.69k|    return ret;
  154|  2.69k|}
buffer.c:mp_thread_set_name:
  219|  1.34k|{
  220|  1.34k|#if HAVE_GLIBC_THREAD_NAME
  221|  1.34k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 1.34k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  1.34k|}
msg.c:mp_mutex_init:
  110|  23.2k|{
  111|  23.2k|#ifndef NDEBUG
  112|  23.2k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  23.2k|    int ret = 0;
  118|  23.2k|    pthread_mutexattr_t attr;
  119|  23.2k|    ret = pthread_mutexattr_init(&attr);
  120|  23.2k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 23.2k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  23.2k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  23.2k|    ret = pthread_mutex_init(mutex, &attr);
  125|  23.2k|    pthread_mutexattr_destroy(&attr);
  126|  23.2k|    mp_assert(!ret);
  ------------------
  |  |   41|  23.2k|#define mp_assert assert
  ------------------
  127|  23.2k|    return ret;
  128|  23.2k|}
msg.c:mp_cond_init:
  136|  5.81k|{
  137|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  138|       |
  139|  5.81k|    int ret = 0;
  140|  5.81k|    pthread_condattr_t attr;
  141|  5.81k|    ret = pthread_condattr_init(&attr);
  142|  5.81k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 5.81k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  5.81k|    cond->clk_id = CLOCK_REALTIME;
  146|  5.81k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  5.81k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 5.81k, False: 0]
  ------------------
  148|  5.81k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  5.81k|#endif
  150|       |
  151|  5.81k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  5.81k|    pthread_condattr_destroy(&attr);
  153|  5.81k|    return ret;
  154|  5.81k|}
msg.c:mp_cond_destroy:
  157|  5.81k|{
  158|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  159|  5.81k|    return pthread_cond_destroy(&cond->cond);
  160|  5.81k|}
stats.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
demux.c:mp_cond_destroy:
  157|   215k|{
  158|   215k|    mp_assert(cond);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
  159|   215k|    return pthread_cond_destroy(&cond->cond);
  160|   215k|}
demux.c:mp_cond_signal:
  169|  1.78M|{
  170|  1.78M|    mp_assert(cond);
  ------------------
  |  |   41|  1.78M|#define mp_assert assert
  ------------------
  171|  1.78M|    return pthread_cond_signal(&cond->cond);
  172|  1.78M|}
demux.c:mp_thread_set_name:
  219|  4.11k|{
  220|  4.11k|#if HAVE_GLIBC_THREAD_NAME
  221|  4.11k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 4.11k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  4.11k|}
demux.c:mp_cond_timedwait_until:
  202|   614k|{
  203|   614k|    return mp_cond_timedwait(cond, mutex, until - mp_time_ns());
  204|   614k|}
demux.c:mp_cond_timedwait:
  181|   614k|{
  182|   614k|    mp_assert(cond);
  ------------------
  |  |   41|   614k|#define mp_assert assert
  ------------------
  183|       |
  184|   614k|    timeout = MPMAX(0, timeout);
  ------------------
  |  |   43|   614k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 614k]
  |  |  ------------------
  ------------------
  185|       |    // consider anything above 1000 days as infinity
  186|   614k|    if (timeout > MP_TIME_S_TO_NS(1000 * 24 * 60 * 60))
  ------------------
  |  |   59|   614k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (186:9): [True: 165, False: 614k]
  ------------------
  187|    165|        return pthread_cond_wait(&cond->cond, mutex);
  188|       |
  189|   614k|    struct timespec ts;
  190|   614k|    clock_gettime(cond->clk_id, &ts);
  191|   614k|    ts.tv_sec  += timeout / MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   614k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  192|   614k|    ts.tv_nsec += timeout % MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   614k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  193|   614k|    if (ts.tv_nsec >= MP_TIME_S_TO_NS(1)) {
  ------------------
  |  |   59|   614k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (193:9): [True: 613k, False: 464]
  ------------------
  194|   613k|        ts.tv_nsec -= MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|   613k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  195|   613k|        ts.tv_sec++;
  196|   613k|    }
  197|       |
  198|   614k|    return pthread_cond_timedwait(&cond->cond, mutex, &ts);
  199|   614k|}
demux.c:mp_mutex_init:
  110|   215k|{
  111|   215k|#ifndef NDEBUG
  112|   215k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|   215k|    int ret = 0;
  118|   215k|    pthread_mutexattr_t attr;
  119|   215k|    ret = pthread_mutexattr_init(&attr);
  120|   215k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 215k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|   215k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|   215k|    ret = pthread_mutex_init(mutex, &attr);
  125|   215k|    pthread_mutexattr_destroy(&attr);
  126|   215k|    mp_assert(!ret);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
  127|   215k|    return ret;
  128|   215k|}
demux.c:mp_cond_init:
  136|   215k|{
  137|   215k|    mp_assert(cond);
  ------------------
  |  |   41|   215k|#define mp_assert assert
  ------------------
  138|       |
  139|   215k|    int ret = 0;
  140|   215k|    pthread_condattr_t attr;
  141|   215k|    ret = pthread_condattr_init(&attr);
  142|   215k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 215k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|   215k|    cond->clk_id = CLOCK_REALTIME;
  146|   215k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|   215k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 215k, False: 0]
  ------------------
  148|   215k|        cond->clk_id = CLOCK_MONOTONIC;
  149|   215k|#endif
  150|       |
  151|   215k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|   215k|    pthread_condattr_destroy(&attr);
  153|   215k|    return ret;
  154|   215k|}
packet_pool.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
f_async_queue.c:mp_mutex_init:
  110|  1.34k|{
  111|  1.34k|#ifndef NDEBUG
  112|  1.34k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  1.34k|    int ret = 0;
  118|  1.34k|    pthread_mutexattr_t attr;
  119|  1.34k|    ret = pthread_mutexattr_init(&attr);
  120|  1.34k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 1.34k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  1.34k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  1.34k|    ret = pthread_mutex_init(mutex, &attr);
  125|  1.34k|    pthread_mutexattr_destroy(&attr);
  126|  1.34k|    mp_assert(!ret);
  ------------------
  |  |   41|  1.34k|#define mp_assert assert
  ------------------
  127|  1.34k|    return ret;
  128|  1.34k|}
f_decoder_wrapper.c:mp_mutex_init:
  110|  4.88k|{
  111|  4.88k|#ifndef NDEBUG
  112|  4.88k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  4.88k|    int ret = 0;
  118|  4.88k|    pthread_mutexattr_t attr;
  119|  4.88k|    ret = pthread_mutexattr_init(&attr);
  120|  4.88k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 4.88k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  4.88k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  4.88k|    ret = pthread_mutex_init(mutex, &attr);
  125|  4.88k|    pthread_mutexattr_destroy(&attr);
  126|  4.88k|    mp_assert(!ret);
  ------------------
  |  |   41|  4.88k|#define mp_assert assert
  ------------------
  127|  4.88k|    return ret;
  128|  4.88k|}
filter.c:mp_mutex_init:
  110|  96.1k|{
  111|  96.1k|#ifndef NDEBUG
  112|  96.1k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  96.1k|    int ret = 0;
  118|  96.1k|    pthread_mutexattr_t attr;
  119|  96.1k|    ret = pthread_mutexattr_init(&attr);
  120|  96.1k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 96.1k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  96.1k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  96.1k|    ret = pthread_mutex_init(mutex, &attr);
  125|  96.1k|    pthread_mutexattr_destroy(&attr);
  126|  96.1k|    mp_assert(!ret);
  ------------------
  |  |   41|  96.1k|#define mp_assert assert
  ------------------
  127|  96.1k|    return ret;
  128|  96.1k|}
input.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
dispatch.c:mp_cond_destroy:
  157|  8.59k|{
  158|  8.59k|    mp_assert(cond);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
  159|  8.59k|    return pthread_cond_destroy(&cond->cond);
  160|  8.59k|}
dispatch.c:mp_mutex_init:
  110|  8.59k|{
  111|  8.59k|#ifndef NDEBUG
  112|  8.59k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  8.59k|    int ret = 0;
  118|  8.59k|    pthread_mutexattr_t attr;
  119|  8.59k|    ret = pthread_mutexattr_init(&attr);
  120|  8.59k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 8.59k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  8.59k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  8.59k|    ret = pthread_mutex_init(mutex, &attr);
  125|  8.59k|    pthread_mutexattr_destroy(&attr);
  126|  8.59k|    mp_assert(!ret);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
  127|  8.59k|    return ret;
  128|  8.59k|}
dispatch.c:mp_cond_init:
  136|  8.59k|{
  137|  8.59k|    mp_assert(cond);
  ------------------
  |  |   41|  8.59k|#define mp_assert assert
  ------------------
  138|       |
  139|  8.59k|    int ret = 0;
  140|  8.59k|    pthread_condattr_t attr;
  141|  8.59k|    ret = pthread_condattr_init(&attr);
  142|  8.59k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 8.59k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  8.59k|    cond->clk_id = CLOCK_REALTIME;
  146|  8.59k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  8.59k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 8.59k, False: 0]
  ------------------
  148|  8.59k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  8.59k|#endif
  150|       |
  151|  8.59k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  8.59k|    pthread_condattr_destroy(&attr);
  153|  8.59k|    return ret;
  154|  8.59k|}
dispatch.c:mp_cond_wait:
  175|  81.0k|{
  176|  81.0k|    mp_assert(cond);
  ------------------
  |  |   41|  81.0k|#define mp_assert assert
  ------------------
  177|  81.0k|    return pthread_cond_wait(&cond->cond, mutex);
  178|  81.0k|}
dispatch.c:mp_cond_broadcast:
  163|   791k|{
  164|   791k|    mp_assert(cond);
  ------------------
  |  |   41|   791k|#define mp_assert assert
  ------------------
  165|   791k|    return pthread_cond_broadcast(&cond->cond);
  166|   791k|}
dispatch.c:mp_cond_timedwait_until:
  202|  98.3k|{
  203|  98.3k|    return mp_cond_timedwait(cond, mutex, until - mp_time_ns());
  204|  98.3k|}
dispatch.c:mp_cond_timedwait:
  181|  98.3k|{
  182|  98.3k|    mp_assert(cond);
  ------------------
  |  |   41|  98.3k|#define mp_assert assert
  ------------------
  183|       |
  184|  98.3k|    timeout = MPMAX(0, timeout);
  ------------------
  |  |   43|  98.3k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 98.3k]
  |  |  ------------------
  ------------------
  185|       |    // consider anything above 1000 days as infinity
  186|  98.3k|    if (timeout > MP_TIME_S_TO_NS(1000 * 24 * 60 * 60))
  ------------------
  |  |   59|  98.3k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (186:9): [True: 438, False: 97.8k]
  ------------------
  187|    438|        return pthread_cond_wait(&cond->cond, mutex);
  188|       |
  189|  97.8k|    struct timespec ts;
  190|  97.8k|    clock_gettime(cond->clk_id, &ts);
  191|  97.8k|    ts.tv_sec  += timeout / MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  97.8k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  192|  97.8k|    ts.tv_nsec += timeout % MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  97.8k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  193|  97.8k|    if (ts.tv_nsec >= MP_TIME_S_TO_NS(1)) {
  ------------------
  |  |   59|  97.8k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  |  Branch (193:9): [True: 4.45k, False: 93.4k]
  ------------------
  194|  4.45k|        ts.tv_nsec -= MP_TIME_S_TO_NS(1);
  ------------------
  |  |   59|  4.45k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  195|  4.45k|        ts.tv_sec++;
  196|  4.45k|    }
  197|       |
  198|  97.8k|    return pthread_cond_timedwait(&cond->cond, mutex, &ts);
  199|  98.3k|}
rendezvous.c:mp_cond_broadcast:
  163|  2.78k|{
  164|  2.78k|    mp_assert(cond);
  ------------------
  |  |   41|  2.78k|#define mp_assert assert
  ------------------
  165|  2.78k|    return pthread_cond_broadcast(&cond->cond);
  166|  2.78k|}
rendezvous.c:mp_cond_wait:
  175|  2.78k|{
  176|  2.78k|    mp_assert(cond);
  ------------------
  |  |   41|  2.78k|#define mp_assert assert
  ------------------
  177|  2.78k|    return pthread_cond_wait(&cond->cond, mutex);
  178|  2.78k|}
thread_pool.c:mp_cond_broadcast:
  163|  5.81k|{
  164|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  165|  5.81k|    return pthread_cond_broadcast(&cond->cond);
  166|  5.81k|}
thread_pool.c:mp_cond_destroy:
  157|  5.81k|{
  158|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  159|  5.81k|    return pthread_cond_destroy(&cond->cond);
  160|  5.81k|}
thread_pool.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
thread_pool.c:mp_cond_init:
  136|  5.81k|{
  137|  5.81k|    mp_assert(cond);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  138|       |
  139|  5.81k|    int ret = 0;
  140|  5.81k|    pthread_condattr_t attr;
  141|  5.81k|    ret = pthread_condattr_init(&attr);
  142|  5.81k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 5.81k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  5.81k|    cond->clk_id = CLOCK_REALTIME;
  146|  5.81k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  5.81k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 5.81k, False: 0]
  ------------------
  148|  5.81k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  5.81k|#endif
  150|       |
  151|  5.81k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  5.81k|    pthread_condattr_destroy(&attr);
  153|  5.81k|    return ret;
  154|  5.81k|}
thread_pool.c:mp_thread_set_name:
  219|  4.31k|{
  220|  4.31k|#if HAVE_GLIBC_THREAD_NAME
  221|  4.31k|    if (pthread_setname_np(pthread_self(), name) == ERANGE) {
  ------------------
  |  Branch (221:9): [True: 0, False: 4.31k]
  ------------------
  222|      0|        char tname[16] = {0}; // glibc-checked kernel limit
  223|      0|        strncpy(tname, name, sizeof(tname) - 1);
  224|      0|        pthread_setname_np(pthread_self(), tname);
  225|      0|    }
  226|       |#elif HAVE_BSD_THREAD_NAME
  227|       |    pthread_set_name_np(pthread_self(), name);
  228|       |#elif HAVE_MAC_THREAD_NAME
  229|       |    pthread_setname_np(name);
  230|       |#endif
  231|  4.31k|}
thread_pool.c:mp_cond_wait:
  175|  4.53k|{
  176|  4.53k|    mp_assert(cond);
  ------------------
  |  |   41|  4.53k|#define mp_assert assert
  ------------------
  177|  4.53k|    return pthread_cond_wait(&cond->cond, mutex);
  178|  4.53k|}
thread_pool.c:mp_cond_signal:
  169|  4.53k|{
  170|  4.53k|    mp_assert(cond);
  ------------------
  |  |   41|  4.53k|#define mp_assert assert
  ------------------
  171|  4.53k|    return pthread_cond_signal(&cond->cond);
  172|  4.53k|}
thread_tools.c:mp_cond_destroy:
  157|  53.1k|{
  158|  53.1k|    mp_assert(cond);
  ------------------
  |  |   41|  53.1k|#define mp_assert assert
  ------------------
  159|  53.1k|    return pthread_cond_destroy(&cond->cond);
  160|  53.1k|}
thread_tools.c:mp_cond_signal:
  169|  16.1k|{
  170|  16.1k|    mp_assert(cond);
  ------------------
  |  |   41|  16.1k|#define mp_assert assert
  ------------------
  171|  16.1k|    return pthread_cond_signal(&cond->cond);
  172|  16.1k|}
thread_tools.c:mp_mutex_init:
  110|  36.9k|{
  111|  36.9k|#ifndef NDEBUG
  112|  36.9k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  36.9k|    int ret = 0;
  118|  36.9k|    pthread_mutexattr_t attr;
  119|  36.9k|    ret = pthread_mutexattr_init(&attr);
  120|  36.9k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 36.9k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  36.9k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  36.9k|    ret = pthread_mutex_init(mutex, &attr);
  125|  36.9k|    pthread_mutexattr_destroy(&attr);
  126|  36.9k|    mp_assert(!ret);
  ------------------
  |  |   41|  36.9k|#define mp_assert assert
  ------------------
  127|  36.9k|    return ret;
  128|  36.9k|}
thread_tools.c:mp_cond_init:
  136|  36.9k|{
  137|  36.9k|    mp_assert(cond);
  ------------------
  |  |   41|  36.9k|#define mp_assert assert
  ------------------
  138|       |
  139|  36.9k|    int ret = 0;
  140|  36.9k|    pthread_condattr_t attr;
  141|  36.9k|    ret = pthread_condattr_init(&attr);
  142|  36.9k|    if (ret)
  ------------------
  |  Branch (142:9): [True: 0, False: 36.9k]
  ------------------
  143|      0|        return ret;
  144|       |
  145|  36.9k|    cond->clk_id = CLOCK_REALTIME;
  146|  36.9k|#if HAVE_PTHREAD_CONDATTR_SETCLOCK
  147|  36.9k|    if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
  ------------------
  |  Branch (147:9): [True: 36.9k, False: 0]
  ------------------
  148|  36.9k|        cond->clk_id = CLOCK_MONOTONIC;
  149|  36.9k|#endif
  150|       |
  151|  36.9k|    ret = pthread_cond_init(&cond->cond, &attr);
  152|  36.9k|    pthread_condattr_destroy(&attr);
  153|  36.9k|    return ret;
  154|  36.9k|}
thread_tools.c:mp_cond_broadcast:
  163|   109k|{
  164|   109k|    mp_assert(cond);
  ------------------
  |  |   41|   109k|#define mp_assert assert
  ------------------
  165|   109k|    return pthread_cond_broadcast(&cond->cond);
  166|   109k|}
m_config_core.c:mp_mutex_init:
  110|  5.81k|{
  111|  5.81k|#ifndef NDEBUG
  112|  5.81k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  5.81k|    int ret = 0;
  118|  5.81k|    pthread_mutexattr_t attr;
  119|  5.81k|    ret = pthread_mutexattr_init(&attr);
  120|  5.81k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 5.81k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  5.81k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  5.81k|    ret = pthread_mutex_init(mutex, &attr);
  125|  5.81k|    pthread_mutexattr_destroy(&attr);
  126|  5.81k|    mp_assert(!ret);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  127|  5.81k|    return ret;
  128|  5.81k|}
vd_lavc.c:mp_mutex_init:
  110|  7.59k|{
  111|  7.59k|#ifndef NDEBUG
  112|  7.59k|    int mutex_type = PTHREAD_MUTEX_ERRORCHECK;
  113|       |#else
  114|       |    int mutex_type = PTHREAD_MUTEX_DEFAULT;
  115|       |#endif
  116|       |
  117|  7.59k|    int ret = 0;
  118|  7.59k|    pthread_mutexattr_t attr;
  119|  7.59k|    ret = pthread_mutexattr_init(&attr);
  120|  7.59k|    if (ret != 0)
  ------------------
  |  Branch (120:9): [True: 0, False: 7.59k]
  ------------------
  121|      0|        return ret;
  122|       |
  123|  7.59k|    pthread_mutexattr_settype(&attr, mutex_type);
  124|  7.59k|    ret = pthread_mutex_init(mutex, &attr);
  125|  7.59k|    pthread_mutexattr_destroy(&attr);
  126|  7.59k|    mp_assert(!ret);
  ------------------
  |  |   41|  7.59k|#define mp_assert assert
  ------------------
  127|  7.59k|    return ret;
  128|  7.59k|}

mp_raw_time_ns:
   41|  25.9M|{
   42|  25.9M|    struct timespec tp = {0};
   43|  25.9M|    clock_gettime(clk_id, &tp);
   44|  25.9M|    return MP_TIME_S_TO_NS(tp.tv_sec) + tp.tv_nsec;
  ------------------
  |  |   59|  25.9M|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
   45|  25.9M|}
mp_raw_time_init:
   48|      1|{
   49|      1|    static const clockid_t clock_ids[] = {
   50|      1|#ifdef CLOCK_MONOTONIC_RAW
   51|      1|        CLOCK_MONOTONIC_RAW,
   52|      1|#endif
   53|      1|        CLOCK_MONOTONIC,
   54|      1|    };
   55|       |
   56|      1|    struct timespec tp;
   57|      1|    for (int i = 0; i < MP_ARRAY_SIZE(clock_ids); ++i) {
  ------------------
  |  |   48|      1|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (57:21): [True: 1, False: 0]
  ------------------
   58|      1|        clk_id = clock_ids[i];
   59|      1|        if (!clock_gettime(clk_id, &tp))
  ------------------
  |  Branch (59:13): [True: 1, False: 0]
  ------------------
   60|      1|            return;
   61|      1|    }
   62|      0|    fputs("No clock source available!\n", stderr);
   63|      0|    abort();
   64|      1|}

mp_time_init:
   39|  5.81k|{
   40|  5.81k|    mp_exec_once(&timer_init_once, do_timer_init);
  ------------------
  |  |  206|  5.81k|#define mp_exec_once pthread_once
  ------------------
   41|  5.81k|}
mp_time_ns:
   44|  25.9M|{
   45|  25.9M|    return mp_time_ns_from_raw_time(mp_raw_time_ns());
   46|  25.9M|}
mp_time_ns_from_raw_time:
   49|  25.9M|{
   50|  25.9M|    return raw_time - raw_time_offset;
   51|  25.9M|}
mp_time_sec:
   54|   583k|{
   55|   583k|    return mp_time_ns() / 1e9;
   56|   583k|}
mp_time_ns_add:
   59|   831k|{
   60|   831k|    mp_assert(time_ns > 0); // mp_time_ns() returns strictly positive values
  ------------------
  |  |   41|   831k|#define mp_assert assert
  ------------------
   61|   831k|    double t = MPCLAMP(timeout_sec * 1e9, -0x1p63, 0x1p63);
  ------------------
  |  |   45|   831k|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 831k]
  |  |  |  Branch (45:56): [True: 215k, False: 616k]
  |  |  ------------------
  ------------------
   62|   831k|    int64_t ti = t == 0x1p63 ? INT64_MAX : (int64_t)t;
  ------------------
  |  Branch (62:18): [True: 215k, False: 616k]
  ------------------
   63|   831k|    if (ti > INT64_MAX - time_ns)
  ------------------
  |  Branch (63:9): [True: 215k, False: 616k]
  ------------------
   64|   215k|        return INT64_MAX;
   65|   616k|    if (ti <= -time_ns)
  ------------------
  |  Branch (65:9): [True: 0, False: 616k]
  ------------------
   66|      0|        return 1;
   67|   616k|    return time_ns + ti;
   68|   616k|}
timer.c:do_timer_init:
   32|      1|{
   33|      1|    mp_raw_time_init();
   34|      1|    raw_time_offset = mp_raw_time_ns();
   35|      1|    mp_assert(raw_time_offset > 0);
  ------------------
  |  |   41|      1|#define mp_assert assert
  ------------------
   36|      1|}

audio_get_gain:
  174|  2.70k|{
  175|  2.70k|    struct MPOpts *opts = mpctx->opts;
  176|  2.70k|    float gain = MPMAX(opts->softvol_volume / 100.0, 0);
  ------------------
  |  |   43|  2.70k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 2.70k, False: 0]
  |  |  ------------------
  ------------------
  177|  2.70k|    gain = pow(gain, 3);
  178|  2.70k|    gain *= compute_replaygain(mpctx);
  179|  2.70k|    gain *= db_gain(opts->softvol_gain);
  180|  2.70k|    if (opts->softvol_mute)
  ------------------
  |  Branch (180:9): [True: 0, False: 2.70k]
  ------------------
  181|      0|        gain = 0.0;
  182|  2.70k|    return gain;
  183|  2.70k|}
audio_update_volume:
  187|  8.53k|{
  188|  8.53k|    struct ao_chain *ao_c = mpctx->ao_chain;
  189|  8.53k|    if (!ao_c || !ao_c->ao)
  ------------------
  |  Branch (189:9): [True: 5.81k, False: 2.72k]
  |  Branch (189:18): [True: 16, False: 2.70k]
  ------------------
  190|  5.82k|        return;
  191|       |
  192|  2.70k|    float gain = audio_get_gain(mpctx);
  193|  2.70k|    ao_set_gain(ao_c->ao, gain);
  194|  2.70k|}
update_playback_speed:
  198|  76.5k|{
  199|  76.5k|    mpctx->audio_speed = mpctx->opts->playback_speed * mpctx->speed_factor_a;
  200|  76.5k|    mpctx->video_speed = mpctx->opts->playback_speed * mpctx->speed_factor_v;
  201|       |
  202|  76.5k|    update_speed_filters(mpctx);
  203|  76.5k|}
reset_audio_state:
  231|  96.5k|{
  232|  96.5k|    if (mpctx->ao_chain) {
  ------------------
  |  Branch (232:9): [True: 1.81k, False: 94.7k]
  ------------------
  233|  1.81k|        ao_chain_reset_state(mpctx->ao_chain);
  234|  1.81k|        struct track *t = mpctx->ao_chain->track;
  235|  1.81k|        if (t && t->dec)
  ------------------
  |  Branch (235:13): [True: 1.81k, False: 0]
  |  Branch (235:18): [True: 1.81k, False: 0]
  ------------------
  236|  1.81k|            mp_decoder_wrapper_set_play_dir(t->dec, mpctx->play_dir);
  237|  1.81k|    }
  238|  96.5k|    mpctx->audio_status = mpctx->ao_chain ? STATUS_SYNCING : STATUS_EOF;
  ------------------
  |  Branch (238:27): [True: 1.81k, False: 94.7k]
  ------------------
  239|  96.5k|    mpctx->delay = 0;
  240|  96.5k|    mpctx->logged_async_diff = -1;
  241|  96.5k|}
uninit_audio_out:
  244|  16.6k|{
  245|  16.6k|    struct ao_chain *ao_c = mpctx->ao_chain;
  246|  16.6k|    if (ao_c) {
  ------------------
  |  Branch (246:9): [True: 1.35k, False: 15.3k]
  ------------------
  247|  1.35k|        ao_c->ao_queue = NULL;
  248|  1.35k|        TA_FREEP(&ao_c->queue_filter);
  ------------------
  |  |   81|  1.35k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  1.35k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  249|  1.35k|        ao_c->ao = NULL;
  250|  1.35k|    }
  251|  16.6k|    if (mpctx->ao) {
  ------------------
  |  Branch (251:9): [True: 1.34k, False: 15.3k]
  ------------------
  252|       |        // Note: with gapless_audio, stop_play is not correctly set
  253|  1.34k|        if ((mpctx->opts->gapless_audio || mpctx->stop_play == AT_END_OF_FILE) &&
  ------------------
  |  Branch (253:14): [True: 1.34k, False: 0]
  |  Branch (253:44): [True: 0, False: 0]
  ------------------
  254|  1.34k|            ao_is_playing(mpctx->ao) && !get_internal_paused(mpctx))
  ------------------
  |  Branch (254:13): [True: 733, False: 615]
  |  Branch (254:41): [True: 733, False: 0]
  ------------------
  255|    733|        {
  256|    733|            MP_VERBOSE(mpctx, "draining left over audio\n");
  ------------------
  |  |   88|    733|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    733|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  257|    733|            ao_drain(mpctx->ao);
  258|    733|        }
  259|  1.34k|        ao_uninit(mpctx->ao);
  260|       |
  261|  1.34k|        mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
  262|  1.34k|    }
  263|  16.6k|    mpctx->ao = NULL;
  264|  16.6k|    TA_FREEP(&mpctx->ao_filter_fmt);
  ------------------
  |  |   81|  16.6k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  16.6k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  265|  16.6k|}
uninit_audio_chain:
  288|  95.0k|{
  289|  95.0k|    if (mpctx->ao_chain) {
  ------------------
  |  Branch (289:9): [True: 1.95k, False: 93.0k]
  ------------------
  290|  1.95k|        ao_chain_uninit(mpctx->ao_chain);
  291|  1.95k|        mpctx->ao_chain = NULL;
  292|       |
  293|  1.95k|        mpctx->audio_status = STATUS_EOF;
  294|       |
  295|  1.95k|        mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
  296|  1.95k|    }
  297|  95.0k|}
init_audio_decoder:
  521|  1.95k|{
  522|  1.95k|    mp_assert(!track->dec);
  ------------------
  |  |   41|  1.95k|#define mp_assert assert
  ------------------
  523|  1.95k|    if (!track->stream)
  ------------------
  |  Branch (523:9): [True: 0, False: 1.95k]
  ------------------
  524|      0|        goto init_error;
  525|       |
  526|  1.95k|    track->dec = mp_decoder_wrapper_create(mpctx->filter_root, track->stream);
  527|  1.95k|    if (!track->dec)
  ------------------
  |  Branch (527:9): [True: 0, False: 1.95k]
  ------------------
  528|      0|        goto init_error;
  529|       |
  530|  1.95k|    if (track->ao_c)
  ------------------
  |  Branch (530:9): [True: 1.95k, False: 0]
  ------------------
  531|  1.95k|        mp_decoder_wrapper_set_spdif_flag(track->dec, true);
  532|       |
  533|  1.95k|    if (!mp_decoder_wrapper_reinit(track->dec))
  ------------------
  |  Branch (533:9): [True: 138, False: 1.81k]
  ------------------
  534|    138|        goto init_error;
  535|       |
  536|  1.81k|    return 1;
  537|       |
  538|    138|init_error:
  539|    138|    if (track->sink)
  ------------------
  |  Branch (539:9): [True: 0, False: 138]
  ------------------
  540|      0|        mp_pin_disconnect(track->sink);
  541|    138|    track->sink = NULL;
  542|    138|    error_on_track(mpctx, track);
  543|    138|    return 0;
  544|  1.95k|}
reinit_audio_chain:
  547|  4.67k|{
  548|  4.67k|    struct track *track = NULL;
  549|  4.67k|    track = mpctx->current_track[0][STREAM_AUDIO];
  550|  4.67k|    if (!track || !track->stream) {
  ------------------
  |  Branch (550:9): [True: 2.72k, False: 1.95k]
  |  Branch (550:19): [True: 0, False: 1.95k]
  ------------------
  551|  2.72k|        if (!mpctx->encode_lavc_ctx)
  ------------------
  |  Branch (551:13): [True: 2.72k, False: 0]
  ------------------
  552|  2.72k|            uninit_audio_out(mpctx);
  553|  2.72k|        error_on_track(mpctx, track);
  554|  2.72k|        return;
  555|  2.72k|    }
  556|  1.95k|    reinit_audio_chain_src(mpctx, track);
  557|  1.95k|}
reinit_audio_chain_src:
  566|  1.95k|{
  567|  1.95k|    mp_assert(!mpctx->ao_chain);
  ------------------
  |  |   41|  1.95k|#define mp_assert assert
  ------------------
  568|       |
  569|  1.95k|    mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
  570|       |
  571|  1.95k|    struct ao_chain *ao_c = talloc_zero(NULL, struct ao_chain);
  ------------------
  |  |   27|  1.95k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  1.95k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  1.95k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  572|  1.95k|    mpctx->ao_chain = ao_c;
  573|  1.95k|    ao_c->mpctx = mpctx;
  574|  1.95k|    ao_c->log = mpctx->log;
  575|  1.95k|    ao_c->filter =
  576|  1.95k|        mp_output_chain_create(mpctx->filter_root, MP_OUTPUT_CHAIN_AUDIO);
  577|  1.95k|    ao_c->spdif_passthrough = true;
  578|  1.95k|    ao_c->last_out_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.95k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  579|  1.95k|    ao_c->delay = mpctx->opts->audio_delay;
  580|       |
  581|  1.95k|    ao_c->ao_filter = mp_filter_create(mpctx->filter_root, &ao_filter);
  582|  1.95k|    if (!ao_c->filter || !ao_c->ao_filter)
  ------------------
  |  Branch (582:9): [True: 0, False: 1.95k]
  |  Branch (582:26): [True: 0, False: 1.95k]
  ------------------
  583|      0|        goto init_error;
  584|  1.95k|    ao_c->ao_filter->priv = ao_c;
  585|       |
  586|  1.95k|    mp_filter_add_pin(ao_c->ao_filter, MP_PIN_IN, "in");
  587|  1.95k|    mp_pin_connect(ao_c->ao_filter->pins[0], ao_c->filter->f->pins[1]);
  588|       |
  589|  1.95k|    if (track) {
  ------------------
  |  Branch (589:9): [True: 1.95k, False: 0]
  ------------------
  590|  1.95k|        ao_c->track = track;
  591|  1.95k|        track->ao_c = ao_c;
  592|  1.95k|        if (!init_audio_decoder(mpctx, track))
  ------------------
  |  Branch (592:13): [True: 138, False: 1.81k]
  ------------------
  593|    138|            goto init_error;
  594|  1.81k|        ao_c->dec_src = track->dec->f->pins[0];
  595|  1.81k|        mp_pin_connect(ao_c->filter->f->pins[0], ao_c->dec_src);
  596|  1.81k|    }
  597|       |
  598|  1.81k|    reset_audio_state(mpctx);
  599|       |
  600|  1.81k|    if (recreate_audio_filters(mpctx) < 0)
  ------------------
  |  Branch (600:9): [True: 0, False: 1.81k]
  ------------------
  601|      0|        goto init_error;
  602|       |
  603|  1.81k|    if (mpctx->ao)
  ------------------
  |  Branch (603:9): [True: 16, False: 1.79k]
  ------------------
  604|     16|        audio_update_volume(mpctx);
  605|       |
  606|  1.81k|    mp_wakeup_core(mpctx);
  607|  1.81k|    return;
  608|       |
  609|    138|init_error:
  610|    138|    uninit_audio_chain(mpctx);
  611|    138|    uninit_audio_out(mpctx);
  612|    138|    error_on_track(mpctx, track);
  613|    138|}
written_audio_pts:
  618|  10.2k|{
  619|  10.2k|    return mpctx->ao_chain ? mpctx->ao_chain->last_out_pts : MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.74k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (619:12): [True: 8.46k, False: 1.74k]
  ------------------
  620|  10.2k|}
playing_audio_pts:
  625|  10.2k|{
  626|  10.2k|    double pts = written_audio_pts(mpctx);
  627|  10.2k|    if (pts == MP_NOPTS_VALUE || !mpctx->ao)
  ------------------
  |  |   38|  20.4k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (627:9): [True: 4.95k, False: 5.25k]
  |  Branch (627:34): [True: 0, False: 5.25k]
  ------------------
  628|  4.95k|        return pts;
  629|  5.25k|    return pts - mpctx->audio_speed * ao_get_delay(mpctx->ao);
  630|  10.2k|}
reload_audio_output:
  766|  5.81k|{
  767|  5.81k|    if (!mpctx->ao)
  ------------------
  |  Branch (767:9): [True: 5.81k, False: 0]
  ------------------
  768|  5.81k|        return;
  769|       |
  770|      0|    ao_reset(mpctx->ao);
  771|      0|    uninit_audio_out(mpctx);
  772|      0|    reinit_audio_filters(mpctx); // mostly to issue refresh seek
  773|       |
  774|      0|    struct ao_chain *ao_c = mpctx->ao_chain;
  775|       |
  776|      0|    if (ao_c) {
  ------------------
  |  Branch (776:9): [True: 0, False: 0]
  ------------------
  777|      0|        reset_audio_state(mpctx);
  778|      0|        mp_output_chain_reset_harder(ao_c->filter);
  779|      0|    }
  780|       |
  781|       |    // Whether we can use spdif might have changed. If we failed to use spdif
  782|       |    // in the previous initialization, try it with spdif again (we'll fallback
  783|       |    // to PCM again if necessary).
  784|      0|    if (ao_c && ao_c->track) {
  ------------------
  |  Branch (784:9): [True: 0, False: 0]
  |  Branch (784:17): [True: 0, False: 0]
  ------------------
  785|      0|        struct mp_decoder_wrapper *dec = ao_c->track->dec;
  786|      0|        if (dec && ao_c->spdif_failed) {
  ------------------
  |  Branch (786:13): [True: 0, False: 0]
  |  Branch (786:20): [True: 0, False: 0]
  ------------------
  787|      0|            ao_c->spdif_passthrough = true;
  788|      0|            ao_c->spdif_failed = false;
  789|      0|            mp_decoder_wrapper_set_spdif_flag(ao_c->track->dec, true);
  790|      0|            if (!mp_decoder_wrapper_reinit(dec)) {
  ------------------
  |  Branch (790:17): [True: 0, False: 0]
  ------------------
  791|      0|                MP_ERR(mpctx, "Error reinitializing audio.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  792|      0|                error_on_track(mpctx, ao_c->track);
  793|      0|            }
  794|      0|        }
  795|      0|    }
  796|       |
  797|      0|    mp_wakeup_core(mpctx);
  798|      0|}
audio_start_ao:
  833|  4.85k|{
  834|  4.85k|    struct ao_chain *ao_c = mpctx->ao_chain;
  835|  4.85k|    if (!ao_c || !ao_c->ao || mpctx->audio_status != STATUS_READY)
  ------------------
  |  Branch (835:9): [True: 0, False: 4.85k]
  |  Branch (835:18): [True: 836, False: 4.01k]
  |  Branch (835:31): [True: 3.28k, False: 732]
  ------------------
  836|  4.12k|        return;
  837|    732|    double pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|    732|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  838|    732|    if (!get_sync_pts(mpctx, &pts))
  ------------------
  |  Branch (838:9): [True: 0, False: 732]
  ------------------
  839|      0|        return;
  840|    732|    double apts = playing_audio_pts(mpctx);
  841|    732|    if (pts != MP_NOPTS_VALUE && apts != MP_NOPTS_VALUE && pts < apts &&
  ------------------
  |  |   38|  1.46k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                  if (pts != MP_NOPTS_VALUE && apts != MP_NOPTS_VALUE && pts < apts &&
  ------------------
  |  |   38|    732|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (841:9): [True: 0, False: 732]
  |  Branch (841:34): [True: 0, False: 0]
  |  Branch (841:60): [True: 0, False: 0]
  ------------------
  842|    732|        mpctx->video_status != STATUS_EOF)
  ------------------
  |  Branch (842:9): [True: 0, False: 0]
  ------------------
  843|      0|    {
  844|      0|        double diff = (apts - pts) / mpctx->opts->playback_speed;
  845|      0|        if (!get_internal_paused(mpctx))
  ------------------
  |  Branch (845:13): [True: 0, False: 0]
  ------------------
  846|      0|            mp_set_timeout(mpctx, diff);
  847|      0|        if (mpctx->logged_async_diff != diff) {
  ------------------
  |  Branch (847:13): [True: 0, False: 0]
  ------------------
  848|      0|            MP_VERBOSE(mpctx, "delaying audio start %f vs. %f, diff=%f\n",
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  849|      0|                       apts, pts, diff);
  850|      0|            mpctx->logged_async_diff = diff;
  851|      0|            ao_c->delaying_audio_start = true;
  852|      0|        }
  853|      0|        return;
  854|      0|    }
  855|       |
  856|    732|    MP_VERBOSE(mpctx, "starting audio playback\n");
  ------------------
  |  |   88|    732|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    732|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  857|    732|    ao_c->delaying_audio_start = false;
  858|    732|    ao_start(ao_c->ao);
  859|    732|    mpctx->audio_status = STATUS_PLAYING;
  860|    732|    if (ao_c->out_eof) {
  ------------------
  |  Branch (860:9): [True: 247, False: 485]
  ------------------
  861|    247|        mpctx->audio_status = STATUS_DRAINING;
  862|    247|        MP_VERBOSE(mpctx, "audio draining\n");
  ------------------
  |  |   88|    247|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    247|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  863|    247|    }
  864|    732|    ao_c->underrun = false;
  865|    732|    mpctx->logged_async_diff = -1;
  866|    732|    mp_wakeup_core(mpctx);
  867|    732|}
fill_audio_out_buffers:
  870|  93.3k|{
  871|  93.3k|    struct MPOpts *opts = mpctx->opts;
  872|       |
  873|  93.3k|    if (mpctx->ao && ao_query_and_reset_events(mpctx->ao, AO_EVENT_RELOAD))
  ------------------
  |  Branch (873:9): [True: 4.42k, False: 88.8k]
  |  Branch (873:22): [True: 0, False: 4.42k]
  ------------------
  874|      0|        reload_audio_output(mpctx);
  875|       |
  876|  93.3k|    if (mpctx->ao && ao_query_and_reset_events(mpctx->ao,
  ------------------
  |  Branch (876:9): [True: 4.42k, False: 88.8k]
  |  Branch (876:22): [True: 0, False: 4.42k]
  ------------------
  877|  4.42k|                                               AO_EVENT_INITIAL_UNBLOCK))
  878|      0|        ao_unblock(mpctx->ao);
  879|       |
  880|  93.3k|    update_throttle(mpctx);
  881|       |
  882|  93.3k|    struct ao_chain *ao_c = mpctx->ao_chain;
  883|  93.3k|    if (!ao_c)
  ------------------
  |  Branch (883:9): [True: 77.3k, False: 15.9k]
  ------------------
  884|  77.3k|        return;
  885|       |
  886|  15.9k|    if (ao_c->filter->failed_output_conversion) {
  ------------------
  |  Branch (886:9): [True: 0, False: 15.9k]
  ------------------
  887|      0|        error_on_track(mpctx, ao_c->track);
  888|      0|        return;
  889|      0|    }
  890|       |
  891|  15.9k|    if (ao_c->filter->ao_needs_update) {
  ------------------
  |  Branch (891:9): [True: 1.42k, False: 14.5k]
  ------------------
  892|  1.42k|        if (reinit_audio_filters_and_output(mpctx) < 0)
  ------------------
  |  Branch (892:13): [True: 3, False: 1.42k]
  ------------------
  893|      3|            return;
  894|  1.42k|    }
  895|       |
  896|  15.9k|    if (mpctx->vo_chain && ao_c->track && ao_c->track->dec &&
  ------------------
  |  Branch (896:9): [True: 3.43k, False: 12.5k]
  |  Branch (896:28): [True: 3.43k, False: 0]
  |  Branch (896:43): [True: 3.43k, False: 0]
  ------------------
  897|  15.9k|        mp_decoder_wrapper_get_pts_reset(ao_c->track->dec))
  ------------------
  |  Branch (897:9): [True: 0, False: 3.43k]
  ------------------
  898|      0|    {
  899|      0|        MP_WARN(mpctx, "Reset playback due to audio timestamp reset.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  900|      0|        reset_playback_state(mpctx);
  901|      0|        mp_wakeup_core(mpctx);
  902|      0|    }
  903|       |
  904|  15.9k|    if (mpctx->audio_status == STATUS_SYNCING) {
  ------------------
  |  Branch (904:9): [True: 11.5k, False: 4.43k]
  ------------------
  905|  11.5k|        double pts;
  906|  11.5k|        bool ok = get_sync_pts(mpctx, &pts);
  907|       |
  908|       |        // If the AO is still playing from the previous file (due to gapless),
  909|       |        // but if video is active, this may not work if audio starts later than
  910|       |        // video, and gapless has no advantages anyway. So block doing anything
  911|       |        // until the old audio is fully played.
  912|       |        // (Buggy if AO underruns.)
  913|  11.5k|        if (mpctx->ao && ao_is_playing(mpctx->ao) &&
  ------------------
  |  Branch (913:13): [True: 1.78k, False: 9.74k]
  |  Branch (913:26): [True: 9, False: 1.77k]
  ------------------
  914|  11.5k|            mpctx->video_status != STATUS_EOF) {
  ------------------
  |  Branch (914:13): [True: 0, False: 9]
  ------------------
  915|      0|            MP_VERBOSE(mpctx, "blocked, waiting for old audio to play\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  916|      0|            ok = false;
  917|      0|        }
  918|       |
  919|  11.5k|        if (ao_c->start_pts_known != ok || ao_c->start_pts != pts) {
  ------------------
  |  Branch (919:13): [True: 934, False: 10.5k]
  |  Branch (919:44): [True: 0, False: 10.5k]
  ------------------
  920|    934|            ao_c->start_pts_known = ok;
  921|    934|            ao_c->start_pts = pts;
  922|    934|            mp_filter_wakeup(ao_c->ao_filter);
  923|    934|        }
  924|       |
  925|  11.5k|        if (ao_c->ao && mp_async_queue_is_full(ao_c->ao_queue)) {
  ------------------
  |  Branch (925:13): [True: 1.75k, False: 9.78k]
  |  Branch (925:25): [True: 421, False: 1.33k]
  ------------------
  926|    421|            mpctx->audio_status = STATUS_READY;
  927|    421|            mp_wakeup_core(mpctx);
  928|    421|            MP_VERBOSE(mpctx, "audio ready\n");
  ------------------
  |  |   88|    421|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    421|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  929|  11.1k|        } else if (ao_c->out_eof) {
  ------------------
  |  Branch (929:20): [True: 245, False: 10.8k]
  ------------------
  930|       |            // Force playback start early.
  931|    245|            mpctx->audio_status = STATUS_READY;
  932|    245|            mp_wakeup_core(mpctx);
  933|    245|            MP_VERBOSE(mpctx, "audio ready (and EOF)\n");
  ------------------
  |  |   88|    245|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    245|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  934|    245|        }
  935|  11.5k|    }
  936|       |
  937|  15.9k|    if (ao_c->ao && !ao_is_playing(ao_c->ao) && !ao_c->underrun &&
  ------------------
  |  Branch (937:9): [True: 5.10k, False: 10.8k]
  |  Branch (937:21): [True: 2.12k, False: 2.97k]
  |  Branch (937:49): [True: 2.12k, False: 0]
  ------------------
  938|  15.9k|        (mpctx->audio_status == STATUS_PLAYING ||
  ------------------
  |  Branch (938:10): [True: 310, False: 1.81k]
  ------------------
  939|  2.12k|         mpctx->audio_status == STATUS_DRAINING))
  ------------------
  |  Branch (939:10): [True: 7, False: 1.80k]
  ------------------
  940|    317|    {
  941|       |        // Should be playing, but somehow isn't.
  942|       |
  943|    317|        if (ao_c->out_eof && !mp_async_queue_get_frames(ao_c->ao_queue)) {
  ------------------
  |  Branch (943:13): [True: 317, False: 0]
  |  Branch (943:30): [True: 317, False: 0]
  ------------------
  944|    317|            MP_VERBOSE(mpctx, "AO signaled EOF (while in state %s)\n",
  ------------------
  |  |   88|    317|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    317|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  945|    317|                       mp_status_str(mpctx->audio_status));
  946|    317|            mpctx->audio_status = STATUS_EOF;
  947|    317|            mp_wakeup_core(mpctx);
  948|       |            // stops untimed AOs, stops pull AOs from streaming silence
  949|    317|            ao_reset(ao_c->ao);
  950|    317|        } else {
  951|      0|            if (!ao_c->ao_underrun) {
  ------------------
  |  Branch (951:17): [True: 0, False: 0]
  ------------------
  952|      0|                MP_WARN(mpctx, "Audio device underrun detected.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  953|      0|                ao_c->ao_underrun = true;
  954|      0|                mp_wakeup_core(mpctx);
  955|      0|                ao_c->underrun = true;
  956|      0|            }
  957|       |
  958|       |            // Wait until buffers are filled before recovering underrun.
  959|      0|            if (ao_c->out_eof || mp_async_queue_is_full(ao_c->ao_queue)) {
  ------------------
  |  Branch (959:17): [True: 0, False: 0]
  |  Branch (959:34): [True: 0, False: 0]
  ------------------
  960|      0|                MP_VERBOSE(mpctx, "restarting audio after underrun\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  961|      0|                ao_start(mpctx->ao_chain->ao);
  962|      0|                ao_c->ao_underrun = false;
  963|      0|                ao_c->underrun = false;
  964|      0|                mp_wakeup_core(mpctx);
  965|      0|            }
  966|      0|        }
  967|    317|    }
  968|       |
  969|  15.9k|    if (mpctx->audio_status == STATUS_PLAYING && ao_c->out_eof) {
  ------------------
  |  Branch (969:9): [True: 2.73k, False: 13.2k]
  |  Branch (969:50): [True: 175, False: 2.55k]
  ------------------
  970|    175|        mpctx->audio_status = STATUS_DRAINING;
  971|    175|        MP_VERBOSE(mpctx, "audio draining\n");
  ------------------
  |  |   88|    175|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    175|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  972|    175|        mp_wakeup_core(mpctx);
  973|    175|    }
  974|       |
  975|  15.9k|    if (mpctx->audio_status == STATUS_DRAINING) {
  ------------------
  |  Branch (975:9): [True: 1.49k, False: 14.4k]
  ------------------
  976|       |        // Wait until the AO has played all queued data. In the gapless case,
  977|       |        // we trigger EOF immediately, and let it play asynchronously.
  978|  1.49k|        if (!ao_c->ao || (!ao_is_playing(ao_c->ao) || opts->gapless_audio))
  ------------------
  |  Branch (978:13): [True: 1.07k, False: 415]
  |  Branch (978:27): [True: 42, False: 373]
  |  Branch (978:55): [True: 373, False: 0]
  ------------------
  979|  1.49k|        {
  980|  1.49k|            MP_VERBOSE(mpctx, "audio EOF reached\n");
  ------------------
  |  |   88|  1.49k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.49k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  981|  1.49k|            mpctx->audio_status = STATUS_EOF;
  982|  1.49k|            mp_wakeup_core(mpctx);
  983|  1.49k|        }
  984|  1.49k|    }
  985|       |
  986|  15.9k|    if (mpctx->restart_complete)
  ------------------
  |  Branch (986:9): [True: 4.12k, False: 11.8k]
  ------------------
  987|  4.12k|        audio_start_ao(mpctx); // in case it got delayed
  988|  15.9k|}
clear_audio_output_buffers:
  992|  91.9k|{
  993|  91.9k|    if (mpctx->ao)
  ------------------
  |  Branch (993:9): [True: 87, False: 91.8k]
  ------------------
  994|     87|        ao_reset(mpctx->ao);
  995|  91.9k|}
audio.c:recreate_audio_filters:
   89|  1.81k|{
   90|  1.81k|    struct ao_chain *ao_c = mpctx->ao_chain;
   91|  1.81k|    mp_assert(ao_c);
  ------------------
  |  |   41|  1.81k|#define mp_assert assert
  ------------------
   92|       |
   93|  1.81k|    if (!mp_output_chain_update_filters(ao_c->filter, mpctx->opts->af_settings))
  ------------------
  |  Branch (93:9): [True: 0, False: 1.81k]
  ------------------
   94|      0|        goto fail;
   95|       |
   96|  1.81k|    update_speed_filters(mpctx);
   97|       |
   98|  1.81k|    mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
   99|       |
  100|  1.81k|    return 0;
  101|       |
  102|      0|fail:
  103|      0|    MP_ERR(mpctx, "Audio filter initialized failed!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  104|      0|    return -1;
  105|  1.81k|}
audio.c:compute_replaygain:
  133|  2.70k|{
  134|  2.70k|    struct MPOpts *opts = mpctx->opts;
  135|       |
  136|  2.70k|    float rgain = 1.0;
  137|       |
  138|  2.70k|    struct replaygain_data *rg = NULL;
  139|  2.70k|    struct track *track = mpctx->current_track[0][STREAM_AUDIO];
  140|  2.70k|    if (track)
  ------------------
  |  Branch (140:9): [True: 2.70k, False: 0]
  ------------------
  141|  2.70k|        rg = track->stream->codec->replaygain_data;
  142|  2.70k|    if (opts->rgain_mode && rg) {
  ------------------
  |  Branch (142:9): [True: 0, False: 2.70k]
  |  Branch (142:29): [True: 0, False: 0]
  ------------------
  143|      0|        MP_VERBOSE(mpctx, "Replaygain: Track=%f/%f Album=%f/%f\n",
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  144|      0|                   rg->track_gain, rg->track_peak,
  145|      0|                   rg->album_gain, rg->album_peak);
  146|       |
  147|      0|        float gain, peak;
  148|      0|        if (opts->rgain_mode == 1) {
  ------------------
  |  Branch (148:13): [True: 0, False: 0]
  ------------------
  149|      0|            gain = rg->track_gain;
  150|      0|            peak = rg->track_peak;
  151|      0|        } else {
  152|      0|            gain = rg->album_gain;
  153|      0|            peak = rg->album_peak;
  154|      0|        }
  155|       |
  156|      0|        gain += opts->rgain_preamp;
  157|      0|        rgain = db_gain(gain);
  158|       |
  159|      0|        MP_VERBOSE(mpctx, "Applying replay-gain: %f\n", rgain);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  160|       |
  161|      0|        if (!opts->rgain_clip) { // clipping prevention
  ------------------
  |  Branch (161:13): [True: 0, False: 0]
  ------------------
  162|      0|            rgain = MPMIN(rgain, 1.0 / peak);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  163|      0|            MP_VERBOSE(mpctx, "...with clipping prevention: %f\n", rgain);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  164|      0|        }
  165|  2.70k|    } else if (opts->rgain_fallback) {
  ------------------
  |  Branch (165:16): [True: 0, False: 2.70k]
  ------------------
  166|      0|        rgain = db_gain(opts->rgain_fallback);
  167|      0|        MP_VERBOSE(mpctx, "Applying fallback gain: %f\n", rgain);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  168|      0|    }
  169|       |
  170|  2.70k|    return rgain;
  171|  2.70k|}
audio.c:db_gain:
  128|  2.70k|{
  129|  2.70k|    return pow(10.0, db/20.0);
  130|  2.70k|}
audio.c:update_speed_filters:
   52|  78.3k|{
   53|  78.3k|    struct ao_chain *ao_c = mpctx->ao_chain;
   54|  78.3k|    if (!ao_c)
  ------------------
  |  Branch (54:9): [True: 76.5k, False: 1.82k]
  ------------------
   55|  76.5k|        return;
   56|       |
   57|  1.82k|    double pitch = mpctx->opts->playback_pitch;
   58|  1.82k|    double speed = mpctx->opts->playback_speed;
   59|  1.82k|    double resample = mpctx->speed_factor_a;
   60|  1.82k|    double drop = 1.0;
   61|       |
   62|  1.82k|    if (!mpctx->opts->pitch_correction) {
  ------------------
  |  Branch (62:9): [True: 0, False: 1.82k]
  ------------------
   63|      0|        resample *= speed;
   64|      0|        speed = 1.0;
   65|      0|    }
   66|       |
   67|  1.82k|    int video_sync = mpctx->display_sync_active ?
  ------------------
  |  Branch (67:22): [True: 0, False: 1.82k]
  ------------------
   68|  1.82k|        mpctx->video_out->opts->video_sync : VS_NONE;
   69|  1.82k|    switch (video_sync) {
   70|      0|        case VS_DISP_ADROP:
  ------------------
  |  Branch (70:9): [True: 0, False: 1.82k]
  ------------------
   71|      0|            drop *= speed * resample / pitch;
   72|      0|            resample = pitch;
   73|      0|            speed = 1.0;
   74|      0|            break;
   75|      0|        case VS_DISP_TEMPO:
  ------------------
  |  Branch (75:9): [True: 0, False: 1.82k]
  ------------------
   76|      0|            speed = mpctx->audio_speed / pitch;
   77|      0|            resample = pitch;
   78|      0|            break;
   79|  1.82k|        default:
  ------------------
  |  Branch (79:9): [True: 1.82k, False: 0]
  ------------------
   80|  1.82k|            resample *= pitch;
   81|  1.82k|            speed /= pitch;
   82|  1.82k|            break;
   83|  1.82k|    }
   84|       |
   85|  1.82k|    mp_output_chain_set_audio_speed(ao_c->filter, speed, resample, drop);
   86|  1.82k|}
audio.c:ao_chain_reset_state:
  220|  1.81k|{
  221|  1.81k|    ao_c->last_out_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.81k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  222|  1.81k|    ao_c->out_eof = false;
  223|  1.81k|    ao_c->start_pts_known = false;
  224|  1.81k|    ao_c->start_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.81k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  225|  1.81k|    ao_c->untimed_throttle = false;
  226|  1.81k|    ao_c->underrun = false;
  227|  1.81k|    ao_c->delaying_audio_start = false;
  228|  1.81k|}
audio.c:ao_chain_uninit:
  268|  1.95k|{
  269|  1.95k|    struct track *track = ao_c->track;
  270|  1.95k|    if (track) {
  ------------------
  |  Branch (270:9): [True: 1.95k, False: 0]
  ------------------
  271|  1.95k|        mp_assert(track->ao_c == ao_c);
  ------------------
  |  |   41|  1.95k|#define mp_assert assert
  ------------------
  272|  1.95k|        track->ao_c = NULL;
  273|  1.95k|        if (ao_c->dec_src)
  ------------------
  |  Branch (273:13): [True: 1.81k, False: 138]
  ------------------
  274|  1.95k|            mp_assert(track->dec->f->pins[0] == ao_c->dec_src);
  ------------------
  |  |   41|  1.95k|#define mp_assert assert
  ------------------
  275|  1.95k|        talloc_free(track->dec->f);
  ------------------
  |  |   47|  1.95k|#define talloc_free                     ta_free
  ------------------
  276|  1.95k|        track->dec = NULL;
  277|  1.95k|    }
  278|       |
  279|  1.95k|    if (ao_c->filter_src)
  ------------------
  |  Branch (279:9): [True: 0, False: 1.95k]
  ------------------
  280|      0|        mp_pin_disconnect(ao_c->filter_src);
  281|       |
  282|  1.95k|    talloc_free(ao_c->filter->f);
  ------------------
  |  |   47|  1.95k|#define talloc_free                     ta_free
  ------------------
  283|  1.95k|    talloc_free(ao_c->ao_filter);
  ------------------
  |  |   47|  1.95k|#define talloc_free                     ta_free
  ------------------
  284|  1.95k|    talloc_free(ao_c);
  ------------------
  |  |   47|  1.95k|#define talloc_free                     ta_free
  ------------------
  285|  1.95k|}
audio.c:ao_process:
  649|   754k|{
  650|   754k|    struct ao_chain *ao_c = f->priv;
  651|   754k|    struct MPContext *mpctx = ao_c->mpctx;
  652|       |
  653|   754k|    if (!ao_c->queue_filter) {
  ------------------
  |  Branch (653:9): [True: 2.89k, False: 751k]
  ------------------
  654|       |        // This will eventually lead to the creation of the AO + queue, due
  655|       |        // to how f_output_chain and AO management works.
  656|  2.89k|        mp_pin_out_request_data(f->ppins[0]);
  657|       |        // Check for EOF with no data case, which is a mess because everything
  658|       |        // hates us.
  659|  2.89k|        struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  660|  2.89k|        if (frame.type == MP_FRAME_EOF) {
  ------------------
  |  Branch (660:13): [True: 1.07k, False: 1.81k]
  ------------------
  661|  1.07k|            MP_VERBOSE(mpctx, "got EOF with no data before it\n");
  ------------------
  |  |   88|  1.07k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.07k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  662|  1.07k|            ao_c->out_eof = true;
  663|  1.07k|            mpctx->audio_status = STATUS_DRAINING;
  664|  1.07k|            mp_wakeup_core(mpctx);
  665|  1.81k|        } else if (frame.type) {
  ------------------
  |  Branch (665:20): [True: 0, False: 1.81k]
  ------------------
  666|      0|            mp_pin_out_unread(f->ppins[0], frame);
  667|      0|        }
  668|  2.89k|        return;
  669|  2.89k|    }
  670|       |
  671|       |    // Due to mp_async_queue_set_notifier() this function is called when the
  672|       |    // queue becomes full. This affects state changes in the normal playloop,
  673|       |    // so wake it up. But avoid redundant wakeups during normal playback.
  674|   751k|    if (mpctx->audio_status != STATUS_PLAYING &&
  ------------------
  |  Branch (674:9): [True: 21.9k, False: 729k]
  ------------------
  675|   751k|        mp_async_queue_is_full(ao_c->ao_queue))
  ------------------
  |  Branch (675:9): [True: 421, False: 21.5k]
  ------------------
  676|    421|        mp_wakeup_core(mpctx);
  677|       |
  678|   751k|    if (mpctx->audio_status == STATUS_SYNCING && !ao_c->start_pts_known)
  ------------------
  |  Branch (678:9): [True: 21.9k, False: 729k]
  |  Branch (678:50): [True: 0, False: 21.9k]
  ------------------
  679|      0|        return;
  680|       |
  681|   751k|    if (ao_c->untimed_throttle)
  ------------------
  |  Branch (681:9): [True: 0, False: 751k]
  ------------------
  682|      0|        return;
  683|       |
  684|   751k|    if (!mp_pin_can_transfer_data(ao_c->queue_filter->pins[0], f->ppins[0]))
  ------------------
  |  Branch (684:9): [True: 377k, False: 374k]
  ------------------
  685|   377k|        return;
  686|       |
  687|   374k|    struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
  688|   374k|    if (frame.type == MP_FRAME_AUDIO) {
  ------------------
  |  Branch (688:9): [True: 373k, False: 732]
  ------------------
  689|   373k|        struct mp_aframe *af = frame.data;
  690|       |
  691|   373k|        double endpts = get_play_end_pts(mpctx);
  692|   373k|        if (endpts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   373k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (692:13): [True: 0, False: 373k]
  ------------------
  693|      0|            endpts *= mpctx->play_dir;
  694|       |            // Avoid decoding and discarding the entire rest of the file.
  695|      0|            if (mp_aframe_get_pts(af) >= endpts) {
  ------------------
  |  Branch (695:17): [True: 0, False: 0]
  ------------------
  696|      0|                mp_pin_out_unread(f->ppins[0], frame);
  697|      0|                if (!ao_c->out_eof) {
  ------------------
  |  Branch (697:21): [True: 0, False: 0]
  ------------------
  698|      0|                    ao_c->out_eof = true;
  699|      0|                    mp_pin_in_write(ao_c->queue_filter->pins[0], MP_EOF_FRAME);
  ------------------
  |  |   59|      0|#define MP_EOF_FRAME MAKE_FRAME(MP_FRAME_EOF, 0)
  |  |  ------------------
  |  |  |  |   57|      0|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  |  |  ------------------
  ------------------
  700|      0|                }
  701|      0|                return;
  702|      0|            }
  703|      0|        }
  704|   373k|        double startpts = mpctx->audio_status == STATUS_SYNCING ?
  ------------------
  |  Branch (704:27): [True: 10.5k, False: 363k]
  ------------------
  705|   363k|                                            ao_c->start_pts : MP_NOPTS_VALUE;
  ------------------
  |  |   38|   363k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  706|   373k|        mp_aframe_clip_timestamps(af, startpts, endpts);
  707|       |
  708|   373k|        int samples = mp_aframe_get_size(af);
  709|   373k|        if (!samples) {
  ------------------
  |  Branch (709:13): [True: 0, False: 373k]
  ------------------
  710|      0|            mp_filter_internal_mark_progress(f);
  711|      0|            mp_frame_unref(&frame);
  712|      0|            return;
  713|      0|        }
  714|       |
  715|   373k|        ao_c->out_eof = false;
  716|       |
  717|   373k|        if (mpctx->audio_status == STATUS_DRAINING ||
  ------------------
  |  Branch (717:13): [True: 0, False: 373k]
  ------------------
  718|   373k|            mpctx->audio_status == STATUS_EOF)
  ------------------
  |  Branch (718:13): [True: 0, False: 373k]
  ------------------
  719|      0|        {
  720|       |            // If a new frame comes decoder/filter EOF, we should preferably
  721|       |            // call get_sync_pts() again, which (at least in obscure situations)
  722|       |            // may require us to wait a while until the sync PTS is known. Our
  723|       |            // code sucks and can't deal with that, so jump through a hoop to
  724|       |            // get things done in the correct order.
  725|      0|            mp_pin_out_unread(f->ppins[0], frame);
  726|      0|            ao_c->start_pts_known = false;
  727|      0|            mpctx->audio_status = STATUS_SYNCING;
  728|      0|            mp_wakeup_core(mpctx);
  729|      0|            MP_VERBOSE(mpctx, "new audio frame after EOF\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  730|      0|            return;
  731|      0|        }
  732|       |
  733|   373k|        mpctx->shown_aframes += samples;
  734|   373k|        double real_samplerate = mp_aframe_get_rate(af) / mpctx->audio_speed;
  735|   373k|        if (mpctx->video_status != STATUS_EOF)
  ------------------
  |  Branch (735:13): [True: 0, False: 373k]
  ------------------
  736|      0|            mpctx->delay += samples / real_samplerate;
  737|   373k|        ao_c->last_out_pts = mp_aframe_end_pts(af);
  738|   373k|        update_throttle(mpctx);
  739|       |
  740|       |        // Gapless case: the AO is still playing from previous file. It makes
  741|       |        // no sense to wait, and in fact the "full queue" event we're waiting
  742|       |        // for may never happen, so start immediately.
  743|       |        // If the new audio starts "later" (big video sync offset), transfer
  744|       |        // of data is stopped somewhere else.
  745|   373k|        if (mpctx->audio_status == STATUS_SYNCING && ao_is_playing(ao_c->ao)) {
  ------------------
  |  Branch (745:13): [True: 10.5k, False: 363k]
  |  Branch (745:54): [True: 4, False: 10.5k]
  ------------------
  746|      4|            mpctx->audio_status = STATUS_READY;
  747|      4|            mp_wakeup_core(mpctx);
  748|      4|            MP_VERBOSE(mpctx, "previous audio still playing; continuing\n");
  ------------------
  |  |   88|      4|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      4|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  749|      4|        }
  750|       |
  751|   373k|        mp_pin_in_write(ao_c->queue_filter->pins[0], frame);
  752|   373k|    } else if (frame.type == MP_FRAME_EOF) {
  ------------------
  |  Branch (752:16): [True: 732, False: 0]
  ------------------
  753|    732|        MP_VERBOSE(mpctx, "audio filter EOF\n");
  ------------------
  |  |   88|    732|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    732|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  754|       |
  755|    732|        ao_c->out_eof = true;
  756|    732|        mp_wakeup_core(mpctx);
  757|       |
  758|    732|        mp_pin_in_write(ao_c->queue_filter->pins[0], frame);
  759|    732|        mp_filter_internal_mark_progress(f);
  760|    732|    } else {
  761|      0|        mp_frame_unref(&frame);
  762|      0|    }
  763|   374k|}
audio.c:get_sync_pts:
  803|  12.2k|{
  804|  12.2k|    struct MPOpts *opts = mpctx->opts;
  805|       |
  806|  12.2k|    *pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  12.2k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  807|       |
  808|  12.2k|    if (!opts->initial_audio_sync)
  ------------------
  |  Branch (808:9): [True: 0, False: 12.2k]
  ------------------
  809|      0|        return true;
  810|       |
  811|  12.2k|    bool sync_to_video = mpctx->vo_chain && mpctx->video_status != STATUS_EOF &&
  ------------------
  |  Branch (811:26): [True: 2.55k, False: 9.71k]
  |  Branch (811:45): [True: 2.54k, False: 5]
  ------------------
  812|  12.2k|                         !mpctx->vo_chain->is_sparse;
  ------------------
  |  Branch (812:26): [True: 2.54k, False: 0]
  ------------------
  813|       |
  814|  12.2k|    if (sync_to_video) {
  ------------------
  |  Branch (814:9): [True: 2.54k, False: 9.71k]
  ------------------
  815|  2.54k|        if (mpctx->video_status < STATUS_READY)
  ------------------
  |  Branch (815:13): [True: 2.54k, False: 0]
  ------------------
  816|  2.54k|            return false; // wait until we know a video PTS
  817|      0|        if (mpctx->video_pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (817:13): [True: 0, False: 0]
  ------------------
  818|      0|            *pts = mpctx->video_pts - opts->audio_delay;
  819|  9.71k|    } else if (mpctx->hrseek_active) {
  ------------------
  |  Branch (819:16): [True: 0, False: 9.71k]
  ------------------
  820|      0|        *pts = mpctx->hrseek_pts;
  821|  9.71k|    } else {
  822|       |        // If audio-only is enabled mid-stream during playback, sync accordingly.
  823|  9.71k|        *pts = mpctx->playback_pts;
  824|  9.71k|    }
  825|       |
  826|  9.71k|    return true;
  827|  12.2k|}
audio.c:update_throttle:
  635|   466k|{
  636|   466k|    struct ao_chain *ao_c = mpctx->ao_chain;
  637|   466k|    bool new_throttle = mpctx->audio_status == STATUS_PLAYING &&
  ------------------
  |  Branch (637:25): [True: 366k, False: 100k]
  ------------------
  638|   466k|                        mpctx->delay > 0 && ao_c && ao_c->ao &&
  ------------------
  |  Branch (638:25): [True: 0, False: 366k]
  |  Branch (638:45): [True: 0, False: 0]
  |  Branch (638:53): [True: 0, False: 0]
  ------------------
  639|   466k|                        ao_untimed(ao_c->ao) &&
  ------------------
  |  Branch (639:25): [True: 0, False: 0]
  ------------------
  640|   466k|                        mpctx->video_status != STATUS_EOF;
  ------------------
  |  Branch (640:25): [True: 0, False: 0]
  ------------------
  641|   466k|    if (ao_c && new_throttle != ao_c->untimed_throttle) {
  ------------------
  |  Branch (641:9): [True: 389k, False: 77.3k]
  |  Branch (641:17): [True: 0, False: 389k]
  ------------------
  642|      0|        ao_c->untimed_throttle = new_throttle;
  643|      0|        mp_wakeup_core(mpctx);
  644|      0|        mp_filter_wakeup(ao_c->ao_filter);
  645|      0|    }
  646|   466k|}
audio.c:reinit_audio_filters_and_output:
  359|  1.42k|{
  360|  1.42k|    struct MPOpts *opts = mpctx->opts;
  361|  1.42k|    struct ao_chain *ao_c = mpctx->ao_chain;
  362|  1.42k|    mp_assert(ao_c);
  ------------------
  |  |   41|  1.42k|#define mp_assert assert
  ------------------
  363|  1.42k|    struct track *track = ao_c->track;
  364|       |
  365|  1.42k|    mp_assert(ao_c->filter->ao_needs_update);
  ------------------
  |  |   41|  1.42k|#define mp_assert assert
  ------------------
  366|       |
  367|       |    // The "ideal" filter output format
  368|  1.42k|    struct mp_aframe *out_fmt = mp_aframe_new_ref(ao_c->filter->output_aformat);
  369|  1.42k|    MP_HANDLE_OOM(out_fmt);
  ------------------
  |  |  176|  1.42k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  1.42k|        void *oom_p_ = (x);     \
  |  |  178|  1.42k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 1.42k]
  |  |  ------------------
  |  |  179|  1.42k|            abort();            \
  |  |  180|  1.42k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  370|       |
  371|  1.42k|    if (!mp_aframe_config_is_valid(out_fmt)) {
  ------------------
  |  Branch (371:9): [True: 0, False: 1.42k]
  ------------------
  372|      0|        talloc_free(out_fmt);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  373|      0|        goto init_error;
  374|      0|    }
  375|       |
  376|  1.42k|    if (af_fmt_is_pcm(mp_aframe_get_format(out_fmt))) {
  ------------------
  |  Branch (376:9): [True: 1.42k, False: 0]
  ------------------
  377|  1.42k|        if (opts->force_srate)
  ------------------
  |  Branch (377:13): [True: 0, False: 1.42k]
  ------------------
  378|      0|            mp_aframe_set_rate(out_fmt, opts->force_srate);
  379|  1.42k|        if (opts->audio_output_format)
  ------------------
  |  Branch (379:13): [True: 0, False: 1.42k]
  ------------------
  380|      0|            mp_aframe_set_format(out_fmt, opts->audio_output_format);
  381|  1.42k|        if (opts->audio_output_channels.num_chmaps == 1)
  ------------------
  |  Branch (381:13): [True: 0, False: 1.42k]
  ------------------
  382|      0|            mp_aframe_set_chmap(out_fmt, &opts->audio_output_channels.chmaps[0]);
  383|  1.42k|    }
  384|       |
  385|       |    // Weak gapless audio: if the filter output format is the same as the
  386|       |    // previous one, keep the AO and don't reinit anything.
  387|       |    // Strong gapless: always keep the AO
  388|  1.42k|    if ((mpctx->ao_filter_fmt && mpctx->ao && opts->gapless_audio < 0 &&
  ------------------
  |  Branch (388:10): [True: 705, False: 721]
  |  Branch (388:34): [True: 705, False: 0]
  |  Branch (388:47): [True: 705, False: 0]
  ------------------
  389|  1.42k|         keep_weak_gapless_format(mpctx->ao_filter_fmt, out_fmt)) ||
  ------------------
  |  Branch (389:10): [True: 13, False: 692]
  ------------------
  390|  1.42k|        (mpctx->ao && opts->gapless_audio > 0))
  ------------------
  |  Branch (390:10): [True: 692, False: 721]
  |  Branch (390:23): [True: 0, False: 692]
  ------------------
  391|     13|    {
  392|     13|        ao_chain_set_ao(ao_c, mpctx->ao);
  393|     13|        talloc_free(out_fmt);
  ------------------
  |  |   47|     13|#define talloc_free                     ta_free
  ------------------
  394|     13|        return 0;
  395|     13|    }
  396|       |
  397|       |    // Format change during syncing. Force playback start early, then wait.
  398|  1.41k|    if (ao_c->ao_queue && mp_async_queue_get_frames(ao_c->ao_queue) &&
  ------------------
  |  Branch (398:9): [True: 691, False: 722]
  |  Branch (398:27): [True: 131, False: 560]
  ------------------
  399|  1.41k|        mpctx->audio_status == STATUS_SYNCING)
  ------------------
  |  Branch (399:9): [True: 62, False: 69]
  ------------------
  400|     62|    {
  401|     62|        mpctx->audio_status = STATUS_READY;
  402|     62|        mp_wakeup_core(mpctx);
  403|     62|        talloc_free(out_fmt);
  ------------------
  |  |   47|     62|#define talloc_free                     ta_free
  ------------------
  404|     62|        return 0;
  405|     62|    }
  406|  1.35k|    if (mpctx->audio_status == STATUS_READY) {
  ------------------
  |  Branch (406:9): [True: 0, False: 1.35k]
  ------------------
  407|      0|        talloc_free(out_fmt);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  408|      0|        return 0;
  409|      0|    }
  410|       |
  411|  1.35k|    uninit_audio_out(mpctx);
  412|       |
  413|  1.35k|    int out_rate = mp_aframe_get_rate(out_fmt);
  414|  1.35k|    int out_format = mp_aframe_get_format(out_fmt);
  415|  1.35k|    struct mp_chmap out_channels = {0};
  416|  1.35k|    mp_aframe_get_chmap(out_fmt, &out_channels);
  417|       |
  418|  1.35k|    int ao_flags = 0;
  419|  1.35k|    bool spdif_fallback = af_fmt_is_spdif(out_format) &&
  ------------------
  |  Branch (419:27): [True: 0, False: 1.35k]
  ------------------
  420|  1.35k|                          ao_c->spdif_passthrough;
  ------------------
  |  Branch (420:27): [True: 0, False: 0]
  ------------------
  421|       |
  422|  1.35k|    if (opts->ao_null_fallback && !spdif_fallback)
  ------------------
  |  Branch (422:9): [True: 0, False: 1.35k]
  |  Branch (422:35): [True: 0, False: 0]
  ------------------
  423|      0|        ao_flags |= AO_INIT_NULL_FALLBACK;
  424|       |
  425|  1.35k|    if (opts->audio_stream_silence)
  ------------------
  |  Branch (425:9): [True: 0, False: 1.35k]
  ------------------
  426|      0|        ao_flags |= AO_INIT_STREAM_SILENCE;
  427|       |
  428|  1.35k|    if (opts->audio_exclusive)
  ------------------
  |  Branch (428:9): [True: 0, False: 1.35k]
  ------------------
  429|      0|        ao_flags |= AO_INIT_EXCLUSIVE;
  430|       |
  431|  1.35k|    if (af_fmt_is_pcm(out_format)) {
  ------------------
  |  Branch (431:9): [True: 1.35k, False: 0]
  ------------------
  432|  1.35k|        if (!opts->audio_output_channels.set ||
  ------------------
  |  Branch (432:13): [True: 0, False: 1.35k]
  ------------------
  433|  1.35k|            opts->audio_output_channels.auto_safe)
  ------------------
  |  Branch (433:13): [True: 1.35k, False: 0]
  ------------------
  434|  1.35k|            ao_flags |= AO_INIT_SAFE_MULTICHANNEL_ONLY;
  435|       |
  436|  1.35k|        mp_chmap_sel_list(&out_channels,
  437|  1.35k|                          opts->audio_output_channels.chmaps,
  438|  1.35k|                          opts->audio_output_channels.num_chmaps);
  439|  1.35k|    }
  440|       |
  441|  1.35k|    if (!has_video_track(mpctx))
  ------------------
  |  Branch (441:9): [True: 1.34k, False: 5]
  ------------------
  442|  1.34k|        ao_flags |= AO_INIT_MEDIA_ROLE_MUSIC;
  443|       |
  444|  1.35k|    mpctx->ao_filter_fmt = out_fmt;
  445|       |
  446|  1.35k|    mpctx->ao = ao_init_best(mpctx->global, ao_flags, mp_wakeup_core_cb,
  447|  1.35k|                             mpctx, mpctx->encode_lavc_ctx, out_rate,
  448|  1.35k|                             out_format, out_channels);
  449|       |
  450|  1.35k|    int ao_rate = 0;
  451|  1.35k|    int ao_format = 0;
  452|  1.35k|    struct mp_chmap ao_channels = {0};
  453|  1.35k|    if (mpctx->ao)
  ------------------
  |  Branch (453:9): [True: 1.34k, False: 3]
  ------------------
  454|  1.34k|        ao_get_format(mpctx->ao, &ao_rate, &ao_format, &ao_channels);
  455|       |
  456|       |    // Verify passthrough format was not changed.
  457|  1.35k|    if (mpctx->ao && af_fmt_is_spdif(out_format)) {
  ------------------
  |  Branch (457:9): [True: 1.34k, False: 3]
  |  Branch (457:22): [True: 0, False: 1.34k]
  ------------------
  458|      0|        if (out_rate != ao_rate || out_format != ao_format ||
  ------------------
  |  Branch (458:13): [True: 0, False: 0]
  |  Branch (458:36): [True: 0, False: 0]
  ------------------
  459|      0|            !mp_chmap_equals(&out_channels, &ao_channels))
  ------------------
  |  Branch (459:13): [True: 0, False: 0]
  ------------------
  460|      0|        {
  461|      0|            MP_ERR(mpctx, "Passthrough format unsupported.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  462|      0|            ao_uninit(mpctx->ao);
  463|      0|            mpctx->ao = NULL;
  464|      0|        }
  465|      0|    }
  466|       |
  467|  1.35k|    if (!mpctx->ao) {
  ------------------
  |  Branch (467:9): [True: 3, False: 1.34k]
  ------------------
  468|       |        // If spdif was used, try to fallback to PCM.
  469|      3|        if (spdif_fallback && ao_c->track && ao_c->track->dec) {
  ------------------
  |  Branch (469:13): [True: 0, False: 3]
  |  Branch (469:31): [True: 0, False: 0]
  |  Branch (469:46): [True: 0, False: 0]
  ------------------
  470|      0|            MP_VERBOSE(mpctx, "Falling back to PCM output.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  471|      0|            ao_c->spdif_passthrough = false;
  472|      0|            ao_c->spdif_failed = true;
  473|      0|            mp_decoder_wrapper_set_spdif_flag(ao_c->track->dec, false);
  474|      0|            if (!mp_decoder_wrapper_reinit(ao_c->track->dec))
  ------------------
  |  Branch (474:17): [True: 0, False: 0]
  ------------------
  475|      0|                goto init_error;
  476|      0|            reset_audio_state(mpctx);
  477|      0|            mp_output_chain_reset_harder(ao_c->filter);
  478|      0|            mp_wakeup_core(mpctx); // reinit with new format next time
  479|      0|            return 0;
  480|      0|        }
  481|       |
  482|      3|        MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n");
  ------------------
  |  |   85|      3|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      3|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  483|      3|        mpctx->error_playing = MPV_ERROR_AO_INIT_FAILED;
  484|      3|        goto init_error;
  485|      3|    }
  486|       |
  487|  1.34k|    char tmp[192];
  488|  1.34k|    MP_INFO(mpctx, "AO: [%s] %s\n", ao_get_name(mpctx->ao),
  ------------------
  |  |   87|  1.34k|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.34k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  489|  1.34k|            audio_config_to_str_buf(tmp, sizeof(tmp), ao_rate, ao_format,
  490|  1.34k|                                    ao_channels));
  491|  1.34k|    MP_VERBOSE(mpctx, "AO: Description: %s\n", ao_get_description(mpctx->ao));
  ------------------
  |  |   88|  1.34k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.34k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  492|  1.34k|    update_window_title(mpctx, true);
  493|       |
  494|  1.34k|    ao_c->ao_resume_time =
  495|  1.34k|        opts->audio_wait_open > 0 ? mp_time_sec() + opts->audio_wait_open : 0;
  ------------------
  |  Branch (495:9): [True: 0, False: 1.34k]
  ------------------
  496|       |
  497|  1.34k|    bool eof = mpctx->audio_status == STATUS_EOF;
  498|  1.34k|    ao_set_paused(mpctx->ao, get_internal_paused(mpctx), eof);
  499|       |
  500|  1.34k|    ao_chain_set_ao(ao_c, mpctx->ao);
  501|       |
  502|  1.34k|    audio_update_volume(mpctx);
  503|       |
  504|       |    // Almost nonsensical hack to deal with certain format change scenarios.
  505|  1.34k|    if (mpctx->audio_status == STATUS_PLAYING)
  ------------------
  |  Branch (505:9): [True: 629, False: 719]
  ------------------
  506|    629|        ao_start(mpctx->ao);
  507|       |
  508|  1.34k|    mp_wakeup_core(mpctx);
  509|  1.34k|    mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
  510|       |
  511|  1.34k|    return 0;
  512|       |
  513|      3|init_error:
  514|      3|    uninit_audio_chain(mpctx);
  515|      3|    uninit_audio_out(mpctx);
  516|      3|    error_on_track(mpctx, track);
  517|      3|    return -1;
  518|  1.35k|}
audio.c:keep_weak_gapless_format:
  314|    705|{
  315|    705|    bool res = false;
  316|    705|    struct mp_aframe *new_mod = mp_aframe_new_ref(new);
  317|    705|    MP_HANDLE_OOM(new_mod);
  ------------------
  |  |  176|    705|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|    705|        void *oom_p_ = (x);     \
  |  |  178|    705|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 705]
  |  |  ------------------
  |  |  179|    705|            abort();            \
  |  |  180|    705|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  318|       |
  319|       |    // If the sample formats are compatible (== libswresample generally can
  320|       |    // convert them), keep the AO. On other changes, recreate it.
  321|       |
  322|    705|    int old_fmt = mp_aframe_get_format(old);
  323|    705|    int new_fmt = mp_aframe_get_format(new);
  324|       |
  325|    705|    if (af_format_conversion_score(old_fmt, new_fmt) == INT_MIN)
  ------------------
  |  Branch (325:9): [True: 0, False: 705]
  ------------------
  326|      0|        goto done; // completely incompatible formats
  327|       |
  328|    705|    if (!mp_aframe_set_format(new_mod, old_fmt))
  ------------------
  |  Branch (328:9): [True: 0, False: 705]
  ------------------
  329|      0|        goto done;
  330|       |
  331|    705|    res = mp_aframe_config_equals(old, new_mod);
  332|       |
  333|    705|done:
  334|    705|    talloc_free(new_mod);
  ------------------
  |  |   47|    705|#define talloc_free                     ta_free
  ------------------
  335|    705|    return res;
  336|    705|}
audio.c:ao_chain_set_ao:
  339|  1.36k|{
  340|  1.36k|    if (ao_c->ao != ao) {
  ------------------
  |  Branch (340:9): [True: 1.36k, False: 0]
  ------------------
  341|  1.36k|        mp_assert(!ao_c->ao);
  ------------------
  |  |   41|  1.36k|#define mp_assert assert
  ------------------
  342|  1.36k|        ao_c->ao = ao;
  343|  1.36k|        ao_c->ao_queue = ao_get_queue(ao_c->ao);
  344|  1.36k|        ao_c->queue_filter = mp_async_queue_create_filter(ao_c->ao_filter,
  345|  1.36k|                                                          MP_PIN_IN, ao_c->ao_queue);
  346|  1.36k|        mp_async_queue_set_notifier(ao_c->queue_filter, ao_c->ao_filter);
  347|       |        // Make sure filtering never stops with frames stuck in access filter.
  348|  1.36k|        mp_filter_set_high_priority(ao_c->queue_filter, true);
  349|  1.36k|        audio_update_volume(ao_c->mpctx);
  350|  1.36k|    }
  351|       |
  352|  1.36k|    if (ao_c->filter->ao_needs_update)
  ------------------
  |  Branch (352:9): [True: 1.36k, False: 0]
  ------------------
  353|  1.36k|        mp_output_chain_set_ao(ao_c->filter, ao_c->ao);
  354|       |
  355|  1.36k|    mp_filter_wakeup(ao_c->ao_filter);
  356|  1.36k|}
audio.c:has_video_track:
  206|  1.35k|{
  207|  1.35k|    if (mpctx->vo_chain && mpctx->vo_chain->is_coverart)
  ------------------
  |  Branch (207:9): [True: 5, False: 1.34k]
  |  Branch (207:28): [True: 0, False: 5]
  ------------------
  208|      0|        return false;
  209|       |
  210|  2.70k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (210:21): [True: 1.35k, False: 1.34k]
  ------------------
  211|  1.35k|        struct track *track = mpctx->tracks[n];
  212|  1.35k|        if (track->type == STREAM_VIDEO && !track->attached_picture && !track->image)
  ------------------
  |  Branch (212:13): [True: 5, False: 1.35k]
  |  Branch (212:44): [True: 5, False: 0]
  |  Branch (212:72): [True: 5, False: 0]
  ------------------
  213|      5|            return true;
  214|  1.35k|    }
  215|       |
  216|  1.34k|    return false;
  217|  1.35k|}
audio.c:audio_config_to_str_buf:
  301|  1.34k|{
  302|  1.34k|    char ch[128];
  303|  1.34k|    mp_chmap_to_str_buf(ch, sizeof(ch), &channels);
  304|  1.34k|    char *hr_ch = mp_chmap_to_str_hr(&channels);
  ------------------
  |  |  137|  1.34k|#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_(m, MP_NUM_CHANNELS * 4)
  |  |  ------------------
  |  |  |  |  136|  1.34k|#define mp_chmap_to_str_hr_(m, sz) mp_chmap_to_str_hr_buf((char[sz]){0}, sz, (m))
  |  |  ------------------
  ------------------
  305|  1.34k|    if (strcmp(hr_ch, ch) != 0)
  ------------------
  |  Branch (305:9): [True: 44, False: 1.30k]
  ------------------
  306|     44|        mp_snprintf_cat(ch, sizeof(ch), " (%s)", hr_ch);
  307|  1.34k|    snprintf(buf, buf_sz, "%dHz %s %dch %s", rate,
  308|  1.34k|             ch, channels.num, af_fmt_to_str(format));
  309|  1.34k|    return buf;
  310|  1.34k|}

mp_clients_init:
  180|  5.81k|{
  181|  5.81k|    mpctx->clients = talloc_ptrtype(NULL, mpctx->clients);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  182|  5.81k|    *mpctx->clients = (struct mp_client_api) {
  183|  5.81k|        .mpctx = mpctx,
  184|  5.81k|    };
  185|  5.81k|    mpctx->global->client_api = mpctx->clients;
  186|  5.81k|    mp_mutex_init(&mpctx->clients->lock);
  187|  5.81k|}
mp_clients_destroy:
  190|  5.81k|{
  191|  5.81k|    if (!mpctx->clients)
  ------------------
  |  Branch (191:9): [True: 0, False: 5.81k]
  ------------------
  192|      0|        return;
  193|  5.81k|    mp_assert(mpctx->clients->num_clients == 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  194|       |
  195|       |    // The API user is supposed to call mpv_render_context_free(). It's simply
  196|       |    // not allowed not to do this.
  197|  5.81k|    if (mpctx->clients->render_context) {
  ------------------
  |  Branch (197:9): [True: 0, False: 5.81k]
  ------------------
  198|      0|        MP_FATAL(mpctx, "Broken API use: mpv_render_context_free() not called.\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  199|      0|        abort();
  200|      0|    }
  201|       |
  202|  5.81k|    mp_mutex_destroy(&mpctx->clients->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  203|  5.81k|    talloc_free(mpctx->clients);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  204|  5.81k|    mpctx->clients = NULL;
  205|  5.81k|}
mp_clients_all_initialized:
  210|  5.81k|{
  211|  5.81k|    bool all_ok = true;
  212|  5.81k|    mp_mutex_lock(&mpctx->clients->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  213|  11.6k|    for (int n = 0; n < mpctx->clients->num_clients; n++) {
  ------------------
  |  Branch (213:21): [True: 5.81k, False: 5.81k]
  ------------------
  214|  5.81k|        struct mpv_handle *ctx = mpctx->clients->clients[n];
  215|  5.81k|        mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  216|  5.81k|        all_ok &= ctx->fuzzy_initialized;
  217|  5.81k|        mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  218|  5.81k|    }
  219|  5.81k|    mp_mutex_unlock(&mpctx->clients->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  220|  5.81k|    return all_ok;
  221|  5.81k|}
mp_new_client:
  261|  5.81k|{
  262|  5.81k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  263|       |
  264|  5.81k|    char nname[MAX_CLIENT_NAME];
  265|  5.81k|    for (int n = 1; n < 1000; n++) {
  ------------------
  |  Branch (265:21): [True: 5.81k, False: 0]
  ------------------
  266|  5.81k|        if (!name)
  ------------------
  |  Branch (266:13): [True: 0, False: 5.81k]
  ------------------
  267|      0|            name = "client";
  268|  5.81k|        snprintf(nname, sizeof(nname) - 3, "%s", name); // - space for number
  269|  29.0k|        for (int i = 0; nname[i]; i++)
  ------------------
  |  Branch (269:25): [True: 23.2k, False: 5.81k]
  ------------------
  270|  23.2k|            nname[i] = mp_isalnum(nname[i]) ? nname[i] : '_';
  ------------------
  |  Branch (270:24): [True: 23.2k, False: 0]
  ------------------
  271|  5.81k|        if (n > 1)
  ------------------
  |  Branch (271:13): [True: 0, False: 5.81k]
  ------------------
  272|      0|            mp_snprintf_cat(nname, sizeof(nname), "%d", n);
  273|  5.81k|        if (!find_client(clients, nname))
  ------------------
  |  Branch (273:13): [True: 5.81k, False: 0]
  ------------------
  274|  5.81k|            break;
  275|      0|        nname[0] = '\0';
  276|      0|    }
  277|       |
  278|  5.81k|    if (!nname[0] || clients->shutting_down) {
  ------------------
  |  Branch (278:9): [True: 0, False: 5.81k]
  |  Branch (278:22): [True: 0, False: 5.81k]
  ------------------
  279|      0|        mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  280|      0|        return NULL;
  281|      0|    }
  282|       |
  283|  5.81k|    int num_events = 1000;
  284|       |
  285|  5.81k|    struct mpv_handle *client = talloc_ptrtype(NULL, client);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  286|  5.81k|    *client = (struct mpv_handle){
  287|  5.81k|        .log = mp_log_new(client, clients->mpctx->log, nname),
  288|  5.81k|        .mpctx = clients->mpctx,
  289|  5.81k|        .clients = clients,
  290|  5.81k|        .id = ++(clients->id_alloc),
  291|  5.81k|        .cur_event = talloc_zero(client, struct mpv_event),
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  292|  5.81k|        .events = talloc_array(client, mpv_event, num_events),
  ------------------
  |  |   29|  5.81k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  5.81k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  293|  5.81k|        .max_events = num_events,
  294|  5.81k|        .event_mask = (1ULL << INTERNAL_EVENT_BASE) - 1, // exclude internal events
  295|  5.81k|        .wakeup_pipe = {-1, -1},
  296|  5.81k|    };
  297|  5.81k|    mp_mutex_init(&client->lock);
  298|  5.81k|    mp_mutex_init(&client->wakeup_lock);
  299|  5.81k|    mp_cond_init(&client->wakeup);
  300|       |
  301|  5.81k|    snprintf(client->name, sizeof(client->name), "%s", nname);
  302|       |
  303|  5.81k|    clients->clients_list_change_ts += 1;
  304|  5.81k|    MP_TARRAY_APPEND(clients, clients->clients, clients->num_clients, client);
  ------------------
  |  |  105|  5.81k|    do {                                            \
  |  |  106|  5.81k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.81k|    do {                                            \
  |  |  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  5.81k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  5.81k|        (idxvar)++;                                 \
  |  |  109|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  305|       |
  306|  5.81k|    if (clients->num_clients == 1 && !clients->mpctx->is_cli)
  ------------------
  |  Branch (306:9): [True: 5.81k, False: 0]
  |  Branch (306:38): [True: 5.81k, False: 0]
  ------------------
  307|  5.81k|        client->fuzzy_initialized = true;
  308|       |
  309|  5.81k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  310|       |
  311|  5.81k|    mpv_request_event(client, MPV_EVENT_TICK, 0);
  312|       |
  313|  5.81k|    return client;
  314|  5.81k|}
mpv_wait_async_requests:
  393|  5.81k|{
  394|  5.81k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  395|  5.81k|    while (ctx->reserved_events || ctx->async_counter)
  ------------------
  |  Branch (395:12): [True: 0, False: 5.81k]
  |  Branch (395:36): [True: 0, False: 5.81k]
  ------------------
  396|      0|        wait_wakeup(ctx, INT64_MAX);
  397|  5.81k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  398|  5.81k|}
mpv_terminate_destroy:
  537|  5.81k|{
  538|  5.81k|    mp_destroy_client(ctx, true);
  539|  5.81k|}
mp_shutdown_clients:
  544|  11.6k|{
  545|  11.6k|    struct mp_client_api *clients = mpctx->clients;
  546|       |
  547|       |    // Forcefully abort async work after 2 seconds of waiting.
  548|  11.6k|    double abort_time = mp_time_sec() + 2;
  549|       |
  550|  11.6k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  11.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  551|       |
  552|       |    // Prevent that new clients can appear.
  553|  11.6k|    clients->shutting_down = true;
  554|       |
  555|       |    // Wait until we can terminate.
  556|  12.9k|    while (clients->num_clients || mpctx->outstanding_async ||
  ------------------
  |  Branch (556:12): [True: 176, False: 12.7k]
  |  Branch (556:36): [True: 0, False: 12.7k]
  ------------------
  557|  12.9k|           !(mpctx->is_cli || clients->terminate_core_thread))
  ------------------
  |  Branch (557:14): [True: 0, False: 12.7k]
  |  Branch (557:31): [True: 11.6k, False: 1.13k]
  ------------------
  558|  1.30k|    {
  559|  1.30k|        mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  1.30k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  560|       |
  561|  1.30k|        double left = abort_time - mp_time_sec();
  562|  1.30k|        if (left >= 0) {
  ------------------
  |  Branch (562:13): [True: 1.30k, False: 0]
  ------------------
  563|  1.30k|            mp_set_timeout(mpctx, left);
  564|  1.30k|        } else {
  565|       |            // Forcefully abort any ongoing async work. This is quite rude and
  566|       |            // probably not what everyone wants, so it happens only after a
  567|       |            // timeout.
  568|      0|            abort_async(mpctx, NULL, 0, 0);
  569|      0|        }
  570|       |
  571|  1.30k|        mp_client_broadcast_event(mpctx, MPV_EVENT_SHUTDOWN, NULL);
  572|  1.30k|        mp_wait_events(mpctx);
  573|       |
  574|  1.30k|        mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  1.30k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  575|  1.30k|    }
  576|       |
  577|  11.6k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  11.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  578|  11.6k|}
mpv_create:
  610|  5.81k|{
  611|  5.81k|    struct MPContext *mpctx = mp_create();
  612|  5.81k|    if (!mpctx)
  ------------------
  |  Branch (612:9): [True: 0, False: 5.81k]
  ------------------
  613|      0|        return NULL;
  614|       |
  615|  5.81k|    m_config_set_profile(mpctx->mconfig, "libmpv", 0);
  616|       |
  617|  5.81k|    mpv_handle *ctx = mp_new_client(mpctx->clients, "main");
  618|  5.81k|    if (!ctx) {
  ------------------
  |  Branch (618:9): [True: 0, False: 5.81k]
  ------------------
  619|      0|        mp_destroy(mpctx);
  620|      0|        return NULL;
  621|      0|    }
  622|       |
  623|  5.81k|    if (mp_thread_create(&mpctx->core_thread, core_thread, mpctx) != 0) {
  ------------------
  |  |  211|  5.81k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  ------------------
  |  Branch (623:9): [True: 0, False: 5.81k]
  ------------------
  624|      0|        ctx->clients->have_terminator = true; // avoid blocking
  625|      0|        mpv_terminate_destroy(ctx);
  626|      0|        mp_destroy(mpctx);
  627|      0|        return NULL;
  628|      0|    }
  629|       |
  630|  5.81k|    return ctx;
  631|  5.81k|}
mpv_initialize_opts:
  657|  5.81k|{
  658|  5.81k|    lock_core(ctx);
  659|  5.81k|    int res = mp_initialize(ctx->mpctx, options) ? MPV_ERROR_INVALID_PARAMETER : 0;
  ------------------
  |  Branch (659:15): [True: 0, False: 5.81k]
  ------------------
  660|  5.81k|    mp_wakeup_core(ctx->mpctx);
  661|  5.81k|    unlock_core(ctx);
  662|  5.81k|    return res;
  663|  5.81k|}
mpv_initialize:
  666|  5.81k|{
  667|  5.81k|    return mpv_initialize_opts(ctx, NULL);
  668|  5.81k|}
mp_client_broadcast_event:
  768|   459k|{
  769|   459k|    struct mp_client_api *clients = mpctx->clients;
  770|       |
  771|   459k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|   459k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  772|       |
  773|   918k|    for (int n = 0; n < clients->num_clients; n++) {
  ------------------
  |  Branch (773:21): [True: 458k, False: 459k]
  ------------------
  774|   458k|        struct mpv_event event_data = {
  775|   458k|            .event_id = event,
  776|   458k|            .data = data,
  777|   458k|        };
  778|   458k|        send_event(clients->clients[n], &event_data, true);
  779|   458k|    }
  780|       |
  781|   459k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|   459k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  782|   459k|}
mpv_request_event:
  852|  5.81k|{
  853|  5.81k|    if (!mpv_event_name(event) || enable < 0 || enable > 1)
  ------------------
  |  Branch (853:9): [True: 0, False: 5.81k]
  |  Branch (853:35): [True: 0, False: 5.81k]
  |  Branch (853:49): [True: 0, False: 5.81k]
  ------------------
  854|      0|        return MPV_ERROR_INVALID_PARAMETER;
  855|  5.81k|    if (event == MPV_EVENT_SHUTDOWN && !enable)
  ------------------
  |  Branch (855:9): [True: 0, False: 5.81k]
  |  Branch (855:40): [True: 0, False: 0]
  ------------------
  856|      0|        return MPV_ERROR_INVALID_PARAMETER;
  857|  5.81k|    mp_assert(event < (int)INTERNAL_EVENT_BASE); // excluded above; they have no name
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  858|  5.81k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  859|  5.81k|    uint64_t bit = 1ULL << event;
  860|  5.81k|    ctx->event_mask = enable ? ctx->event_mask | bit : ctx->event_mask & ~bit;
  ------------------
  |  Branch (860:23): [True: 0, False: 5.81k]
  ------------------
  861|  5.81k|    if (enable && event < MP_ARRAY_SIZE(deprecated_events) &&
  ------------------
  |  |   48|  5.81k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (861:9): [True: 0, False: 5.81k]
  |  Branch (861:19): [True: 0, False: 0]
  ------------------
  862|  5.81k|        deprecated_events[event])
  ------------------
  |  Branch (862:9): [True: 0, False: 0]
  ------------------
  863|      0|    {
  864|      0|        MP_WARN(ctx, "The '%s' event is deprecated and will be removed.\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  865|      0|                mpv_event_name(event));
  866|      0|    }
  867|  5.81k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  868|  5.81k|    return 0;
  869|  5.81k|}
mpv_wait_event:
  893|   234k|{
  894|   234k|    mpv_event *event = ctx->cur_event;
  895|       |
  896|   234k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|   234k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  897|       |
  898|   234k|    if (!ctx->fuzzy_initialized)
  ------------------
  |  Branch (898:9): [True: 0, False: 234k]
  ------------------
  899|      0|        mp_wakeup_core(ctx->clients->mpctx);
  900|   234k|    ctx->fuzzy_initialized = true;
  901|       |
  902|   234k|    if (timeout < 0)
  ------------------
  |  Branch (902:9): [True: 208k, False: 26.0k]
  ------------------
  903|   208k|        timeout = 1e20;
  904|       |
  905|   234k|    int64_t deadline = mp_time_ns_add(mp_time_ns(), timeout);
  906|       |
  907|   234k|    *event = (mpv_event){0};
  908|   234k|    talloc_free_children(event);
  ------------------
  |  |   46|   234k|#define talloc_free_children            ta_free_children
  ------------------
  909|       |
  910|   332k|    while (1) {
  ------------------
  |  Branch (910:12): [Folded - Ignored]
  ------------------
  911|   332k|        if (ctx->queued_wakeup)
  ------------------
  |  Branch (911:13): [True: 0, False: 332k]
  ------------------
  912|      0|            deadline = 0;
  913|       |        // Recover from overflow.
  914|   332k|        if (ctx->choked && !ctx->num_events) {
  ------------------
  |  Branch (914:13): [True: 0, False: 332k]
  |  Branch (914:28): [True: 0, False: 0]
  ------------------
  915|      0|            ctx->choked = false;
  916|      0|            event->event_id = MPV_EVENT_QUEUE_OVERFLOW;
  917|      0|            break;
  918|      0|        }
  919|   332k|        struct mpv_event *ev =
  920|   332k|            ctx->num_events ? &ctx->events[ctx->first_event] : NULL;
  ------------------
  |  Branch (920:13): [True: 234k, False: 98.2k]
  ------------------
  921|   332k|        if (ev && ev->event_id == MPV_EVENT_HOOK) {
  ------------------
  |  Branch (921:13): [True: 234k, False: 98.2k]
  |  Branch (921:19): [True: 0, False: 234k]
  ------------------
  922|       |            // Give old property notifications priority over hooks. This is a
  923|       |            // guarantee given to clients to simplify their logic. New property
  924|       |            // changes after this are treated normally, so
  925|      0|            if (!ctx->hook_pending) {
  ------------------
  |  Branch (925:17): [True: 0, False: 0]
  ------------------
  926|      0|                ctx->hook_pending = true;
  927|      0|                set_wait_for_hook_flags(ctx);
  928|      0|            }
  929|      0|            if (check_for_for_hook_flags(ctx)) {
  ------------------
  |  Branch (929:17): [True: 0, False: 0]
  ------------------
  930|      0|                ev = NULL; // delay
  931|      0|            } else {
  932|      0|                ctx->hook_pending = false;
  933|      0|            }
  934|      0|        }
  935|   332k|        if (ev) {
  ------------------
  |  Branch (935:13): [True: 234k, False: 98.2k]
  ------------------
  936|   234k|            *event = *ev;
  937|   234k|            ctx->first_event = (ctx->first_event + 1) % ctx->max_events;
  938|   234k|            ctx->num_events--;
  939|   234k|            talloc_steal(event, event->data);
  ------------------
  |  |   38|   234k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|   234k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  940|   234k|            break;
  941|   234k|        }
  942|       |        // If there's a changed property, generate change event (never queued).
  943|  98.2k|        if (gen_property_change_event(ctx))
  ------------------
  |  Branch (943:13): [True: 0, False: 98.2k]
  ------------------
  944|      0|            break;
  945|       |        // Pop item from message queue, and return as event.
  946|  98.2k|        if (gen_log_message_event(ctx))
  ------------------
  |  Branch (946:13): [True: 0, False: 98.2k]
  ------------------
  947|      0|            break;
  948|  98.2k|        int r = wait_wakeup(ctx, deadline);
  949|  98.2k|        if (r == ETIMEDOUT)
  ------------------
  |  Branch (949:13): [True: 0, False: 98.2k]
  ------------------
  950|      0|            break;
  951|  98.2k|    }
  952|   234k|    ctx->queued_wakeup = false;
  953|       |
  954|   234k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|   234k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  955|       |
  956|   234k|    return event;
  957|   234k|}
mpv_free_node_contents:
 1018|  11.6k|{
 1019|  11.6k|    static const struct m_option type = { .type = CONF_TYPE_NODE };
  ------------------
  |  |  241|  11.6k|#define CONF_TYPE_NODE          (&m_option_type_node)
  ------------------
 1020|  11.6k|    m_option_free(&type, node);
 1021|  11.6k|}
mpv_set_option:
 1025|  40.6k|{
 1026|  40.6k|    const struct m_option *type = get_mp_type(format);
 1027|  40.6k|    if (!type)
  ------------------
  |  Branch (1027:9): [True: 0, False: 40.6k]
  ------------------
 1028|      0|        return MPV_ERROR_OPTION_FORMAT;
 1029|  40.6k|    struct mpv_node tmp;
 1030|  40.6k|    if (format != MPV_FORMAT_NODE) {
  ------------------
  |  Branch (1030:9): [True: 40.6k, False: 0]
  ------------------
 1031|  40.6k|        tmp.format = format;
 1032|  40.6k|        memcpy(&tmp.u, data, type->type->size);
 1033|  40.6k|        data = &tmp;
 1034|  40.6k|    }
 1035|  40.6k|    lock_core(ctx);
 1036|  40.6k|    int err = m_config_set_option_node(ctx->mpctx->mconfig, bstr0(name), data, 0);
 1037|  40.6k|    unlock_core(ctx);
 1038|  40.6k|    switch (err) {
 1039|      0|    case M_OPT_MISSING_PARAM:
  ------------------
  |  |  520|      0|#define M_OPT_MISSING_PARAM     -2
  ------------------
  |  Branch (1039:5): [True: 0, False: 40.6k]
  ------------------
 1040|      0|    case M_OPT_INVALID:
  ------------------
  |  |  523|      0|#define M_OPT_INVALID           -3
  ------------------
  |  Branch (1040:5): [True: 0, False: 40.6k]
  ------------------
 1041|      0|        return MPV_ERROR_OPTION_ERROR;
 1042|      0|    case M_OPT_OUT_OF_RANGE:
  ------------------
  |  |  527|      0|#define M_OPT_OUT_OF_RANGE      -4
  ------------------
  |  Branch (1042:5): [True: 0, False: 40.6k]
  ------------------
 1043|      0|        return MPV_ERROR_OPTION_FORMAT;
 1044|      0|    case M_OPT_UNKNOWN:
  ------------------
  |  |  517|      0|#define M_OPT_UNKNOWN           -1
  ------------------
  |  Branch (1044:5): [True: 0, False: 40.6k]
  ------------------
 1045|      0|        return MPV_ERROR_OPTION_NOT_FOUND;
 1046|  40.6k|    default:
  ------------------
  |  Branch (1046:5): [True: 40.6k, False: 0]
  ------------------
 1047|  40.6k|        if (err >= 0)
  ------------------
  |  Branch (1047:13): [True: 40.6k, False: 0]
  ------------------
 1048|  40.6k|            return 0;
 1049|      0|        return MPV_ERROR_OPTION_ERROR;
 1050|  40.6k|    }
 1051|  40.6k|}
mpv_set_option_string:
 1054|  40.6k|{
 1055|  40.6k|    return mpv_set_option(ctx, name, MPV_FORMAT_STRING, &data);
 1056|  40.6k|}
mpv_command:
 1145|  11.6k|{
 1146|  11.6k|    return run_client_command(ctx, mp_input_parse_cmd_strv(ctx->log, args), NULL);
 1147|  11.6k|}
mp_client_property_change:
 1620|  15.6k|{
 1621|  15.6k|    struct mp_client_api *clients = mpctx->clients;
 1622|  15.6k|    int id = mp_get_property_id(mpctx, name);
 1623|  15.6k|    bool any_pending = false;
 1624|       |
 1625|  15.6k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  15.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1626|       |
 1627|  31.3k|    for (int n = 0; n < clients->num_clients; n++) {
  ------------------
  |  Branch (1627:21): [True: 15.6k, False: 15.6k]
  ------------------
 1628|  15.6k|        struct mpv_handle *client = clients->clients[n];
 1629|  15.6k|        mp_mutex_lock(&client->lock);
  ------------------
  |  |  131|  15.6k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1630|  15.6k|        for (int i = 0; i < client->num_properties; i++) {
  ------------------
  |  Branch (1630:25): [True: 0, False: 15.6k]
  ------------------
 1631|      0|            if (client->properties[i]->id == id &&
  ------------------
  |  Branch (1631:17): [True: 0, False: 0]
  ------------------
 1632|      0|                property_shared_prefix(name, client->properties[i]->name)) {
  ------------------
  |  Branch (1632:17): [True: 0, False: 0]
  ------------------
 1633|      0|                client->properties[i]->change_ts += 1;
 1634|      0|                client->has_pending_properties = true;
 1635|      0|                any_pending = true;
 1636|      0|            }
 1637|      0|        }
 1638|  15.6k|        mp_mutex_unlock(&client->lock);
  ------------------
  |  |  133|  15.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1639|  15.6k|    }
 1640|       |
 1641|  15.6k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  15.6k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1642|       |
 1643|       |    // If we're inside mp_dispatch_queue_process(), this will cause the playloop
 1644|       |    // to be re-run (to get mp_client_send_property_changes() called). If we're
 1645|       |    // inside the normal playloop, this does nothing, but the latter function
 1646|       |    // will be called at the end of the playloop anyway.
 1647|  15.6k|    if (any_pending)
  ------------------
  |  Branch (1647:9): [True: 0, False: 15.6k]
  ------------------
 1648|      0|        mp_dispatch_adjust_timeout(mpctx->dispatch, 0);
 1649|  15.6k|}
mp_client_send_property_changes:
 1754|   138k|{
 1755|   138k|    struct mp_client_api *clients = mpctx->clients;
 1756|       |
 1757|   138k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|   138k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1758|   138k|    uint64_t cur_ts = clients->clients_list_change_ts;
 1759|       |
 1760|   275k|    for (int n = 0; n < clients->num_clients; n++) {
  ------------------
  |  Branch (1760:21): [True: 137k, False: 138k]
  ------------------
 1761|   137k|        struct mpv_handle *ctx = clients->clients[n];
 1762|       |
 1763|   137k|        mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|   137k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1764|   137k|        if (!ctx->has_pending_properties || ctx->destroying) {
  ------------------
  |  Branch (1764:13): [True: 137k, False: 0]
  |  Branch (1764:45): [True: 0, False: 0]
  ------------------
 1765|   137k|            mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|   137k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1766|   137k|            continue;
 1767|   137k|        }
 1768|       |        // Keep ctx->lock locked (unlock order does not matter).
 1769|      0|        mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1770|      0|        send_client_property_changes(ctx);
 1771|      0|        mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1772|      0|        mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1773|      0|        if (cur_ts != clients->clients_list_change_ts) {
  ------------------
  |  Branch (1773:13): [True: 0, False: 0]
  ------------------
 1774|       |            // List changed; need to start over. Do it in the next iteration.
 1775|      0|            mp_wakeup_core(mpctx);
 1776|      0|            break;
 1777|      0|        }
 1778|      0|    }
 1779|       |
 1780|   138k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|   138k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1781|   138k|}
mpv_error_string:
 2087|  94.7k|{
 2088|  94.7k|    error = -error;
 2089|  94.7k|    if (error < 0)
  ------------------
  |  Branch (2089:9): [True: 0, False: 94.7k]
  ------------------
 2090|      0|        error = 0;
 2091|  94.7k|    const char *name = NULL;
 2092|  94.7k|    if (error < MP_ARRAY_SIZE(err_table))
  ------------------
  |  |   48|  94.7k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (2092:9): [True: 94.7k, False: 0]
  ------------------
 2093|  94.7k|        name = err_table[error];
 2094|  94.7k|    return name ? name : "unknown error";
  ------------------
  |  Branch (2094:12): [True: 94.7k, False: 0]
  ------------------
 2095|  94.7k|}
mpv_event_name:
 2120|  5.81k|{
 2121|  5.81k|    if ((unsigned)event >= MP_ARRAY_SIZE(event_table))
  ------------------
  |  |   48|  5.81k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (2121:9): [True: 0, False: 5.81k]
  ------------------
 2122|      0|        return NULL;
 2123|  5.81k|    return event_table[event];
 2124|  5.81k|}
mp_streamcb_lookup:
 2232|     17|{
 2233|     17|    struct mp_client_api *clients = g->client_api;
 2234|     17|    bool found = false;
 2235|     17|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|     17|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 2236|     17|    for (int n = 0; n < clients->num_custom_protocols; n++) {
  ------------------
  |  Branch (2236:21): [True: 0, False: 17]
  ------------------
 2237|      0|        struct mp_custom_protocol *proto = &clients->custom_protocols[n];
 2238|      0|        if (strcmp(proto->protocol, protocol) == 0) {
  ------------------
  |  Branch (2238:13): [True: 0, False: 0]
  ------------------
 2239|      0|            *out_user_data = proto->user_data;
 2240|      0|            *out_fn = proto->open_fn;
 2241|      0|            found = true;
 2242|      0|            break;
 2243|      0|        }
 2244|      0|    }
 2245|     17|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|     17|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 2246|     17|    return found;
 2247|     17|}
client.c:find_client:
  234|  5.81k|{
  235|  5.81k|    if (name[0] == '@') {
  ------------------
  |  Branch (235:9): [True: 0, False: 5.81k]
  ------------------
  236|      0|        char *end;
  237|      0|        errno = 0;
  238|      0|        long long int id = strtoll(name + 1, &end, 10);
  239|      0|        if (errno || end[0])
  ------------------
  |  Branch (239:22): [True: 0, False: 0]
  ------------------
  240|      0|            return NULL;
  241|      0|        return find_client_id(clients, id);
  242|      0|    }
  243|       |
  244|  5.81k|    for (int n = 0; n < clients->num_clients; n++) {
  ------------------
  |  Branch (244:21): [True: 0, False: 5.81k]
  ------------------
  245|      0|        if (strcmp(clients->clients[n]->name, name) == 0)
  ------------------
  |  Branch (245:13): [True: 0, False: 0]
  ------------------
  246|      0|            return clients->clients[n];
  247|      0|    }
  248|       |
  249|  5.81k|    return NULL;
  250|  5.81k|}
client.c:wait_wakeup:
  359|  98.2k|{
  360|  98.2k|    int r = 0;
  361|  98.2k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|  98.2k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  362|  98.2k|    mp_mutex_lock(&ctx->wakeup_lock);
  ------------------
  |  |  131|  98.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  363|  98.2k|    if (!ctx->need_wakeup)
  ------------------
  |  Branch (363:9): [True: 77.4k, False: 20.7k]
  ------------------
  364|  77.4k|        r = mp_cond_timedwait_until(&ctx->wakeup, &ctx->wakeup_lock, end);
  365|  98.2k|    if (r == 0)
  ------------------
  |  Branch (365:9): [True: 98.2k, False: 0]
  ------------------
  366|  98.2k|        ctx->need_wakeup = false;
  367|  98.2k|    mp_mutex_unlock(&ctx->wakeup_lock);
  ------------------
  |  |  133|  98.2k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  368|  98.2k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|  98.2k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  369|  98.2k|    return r;
  370|  98.2k|}
client.c:mp_destroy_client:
  425|  5.81k|{
  426|  5.81k|    if (!ctx)
  ------------------
  |  Branch (426:9): [True: 0, False: 5.81k]
  ------------------
  427|      0|        return;
  428|       |
  429|  5.81k|    struct MPContext *mpctx = ctx->mpctx;
  430|  5.81k|    struct mp_client_api *clients = ctx->clients;
  431|       |
  432|  5.81k|    MP_DBG(ctx, "Destroying client handle...\n");
  ------------------
  |  |   89|  5.81k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.81k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  433|       |
  434|  5.81k|    if (terminate)
  ------------------
  |  Branch (434:9): [True: 5.81k, False: 0]
  ------------------
  435|  5.81k|        mpv_command(ctx, (const char*[]){"quit", NULL});
  436|       |
  437|  5.81k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  438|       |
  439|  5.81k|    ctx->destroying = true;
  440|       |
  441|  5.81k|    for (int n = 0; n < ctx->num_properties; n++)
  ------------------
  |  Branch (441:21): [True: 0, False: 5.81k]
  ------------------
  442|      0|        prop_unref(ctx->properties[n]);
  443|  5.81k|    ctx->num_properties = 0;
  444|  5.81k|    ctx->properties_change_ts += 1;
  445|       |
  446|  5.81k|    prop_unref(ctx->cur_property);
  447|  5.81k|    ctx->cur_property = NULL;
  448|       |
  449|  5.81k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  450|       |
  451|  5.81k|    abort_async(mpctx, ctx, 0, 0);
  452|       |
  453|       |    // reserved_events equals the number of asynchronous requests that weren't
  454|       |    // yet replied. In order to avoid that trying to reply to a removed client
  455|       |    // causes a crash, block until all asynchronous requests were served.
  456|  5.81k|    mpv_wait_async_requests(ctx);
  457|       |
  458|  5.81k|    osd_set_external_remove_owner(mpctx->osd, ctx);
  459|  5.81k|    mp_input_remove_sections_by_owner(mpctx->input, ctx->name);
  460|       |
  461|  5.81k|    mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  462|       |
  463|  5.81k|    for (int n = 0; n < clients->num_clients; n++) {
  ------------------
  |  Branch (463:21): [True: 5.81k, False: 0]
  ------------------
  464|  5.81k|        if (clients->clients[n] == ctx) {
  ------------------
  |  Branch (464:13): [True: 5.81k, False: 0]
  ------------------
  465|  5.81k|            clients->clients_list_change_ts += 1;
  466|  5.81k|            MP_TARRAY_REMOVE_AT(clients->clients, clients->num_clients, n);
  ------------------
  |  |  143|  5.81k|    do {                                            \
  |  |  144|  5.81k|        size_t at_ = (at);                          \
  |  |  145|  5.81k|        assert(at_ <= (idxvar));                    \
  |  |  146|  5.81k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  5.81k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  5.81k|        (idxvar)--;                                 \
  |  |  149|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  467|  5.96k|            while (ctx->num_events) {
  ------------------
  |  Branch (467:20): [True: 155, False: 5.81k]
  ------------------
  468|    155|                talloc_free(ctx->events[ctx->first_event].data);
  ------------------
  |  |   47|    155|#define talloc_free                     ta_free
  ------------------
  469|    155|                ctx->first_event = (ctx->first_event + 1) % ctx->max_events;
  470|    155|                ctx->num_events--;
  471|    155|            }
  472|  5.81k|            mp_msg_log_buffer_destroy(ctx->messages);
  473|  5.81k|            mp_cond_destroy(&ctx->wakeup);
  474|  5.81k|            mp_mutex_destroy(&ctx->wakeup_lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  475|  5.81k|            mp_mutex_destroy(&ctx->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  476|  5.81k|            if (ctx->wakeup_pipe[0] != -1) {
  ------------------
  |  Branch (476:17): [True: 0, False: 5.81k]
  ------------------
  477|      0|                close(ctx->wakeup_pipe[0]);
  478|      0|                close(ctx->wakeup_pipe[1]);
  479|      0|            }
  480|  5.81k|            talloc_free(ctx);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  481|  5.81k|            ctx = NULL;
  482|  5.81k|            break;
  483|  5.81k|        }
  484|  5.81k|    }
  485|  5.81k|    mp_assert(!ctx);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  486|       |
  487|  5.81k|    if (mpctx->is_cli) {
  ------------------
  |  Branch (487:9): [True: 0, False: 5.81k]
  ------------------
  488|      0|        terminate = false;
  489|  5.81k|    } else {
  490|       |        // If the last strong mpv_handle got destroyed, destroy the core.
  491|  5.81k|        bool has_strong_ref = false;
  492|  5.81k|        for (int n = 0; n < clients->num_clients; n++)
  ------------------
  |  Branch (492:25): [True: 0, False: 5.81k]
  ------------------
  493|      0|            has_strong_ref |= !clients->clients[n]->is_weak;
  494|  5.81k|        if (!has_strong_ref)
  ------------------
  |  Branch (494:13): [True: 5.81k, False: 0]
  ------------------
  495|  5.81k|            terminate = true;
  496|       |
  497|       |        // Reserve the right to destroy mpctx for us.
  498|  5.81k|        if (clients->have_terminator)
  ------------------
  |  Branch (498:13): [True: 0, False: 5.81k]
  ------------------
  499|      0|            terminate = false;
  500|  5.81k|        clients->have_terminator |= terminate;
  501|  5.81k|    }
  502|       |
  503|       |    // mp_shutdown_clients() sleeps to avoid wasting CPU.
  504|       |    // mp_hook_test_completion() also relies on this a bit.
  505|  5.81k|    mp_wakeup_core(mpctx);
  506|       |
  507|  5.81k|    mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  508|       |
  509|       |    // Note that even if num_clients==0, having set have_terminator keeps mpctx
  510|       |    // and the core thread alive.
  511|  5.81k|    if (terminate) {
  ------------------
  |  Branch (511:9): [True: 5.81k, False: 0]
  ------------------
  512|       |        // Make sure the core stops playing files etc. Being able to lock the
  513|       |        // dispatch queue requires that the core thread is still active.
  514|  5.81k|        mp_dispatch_lock(mpctx->dispatch);
  515|  5.81k|        mpctx->stop_play = PT_QUIT;
  516|  5.81k|        mp_dispatch_unlock(mpctx->dispatch);
  517|       |
  518|       |        // Ask the core thread to stop.
  519|  5.81k|        mp_mutex_lock(&clients->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  520|  5.81k|        clients->terminate_core_thread = true;
  521|  5.81k|        mp_mutex_unlock(&clients->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  522|  5.81k|        mp_wakeup_core(mpctx);
  523|       |
  524|       |        // Blocking wait for all clients and core thread to terminate.
  525|  5.81k|        mp_thread_join(mpctx->core_thread);
  ------------------
  |  |  212|  5.81k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  526|       |
  527|  5.81k|        mp_destroy(mpctx);
  528|  5.81k|    }
  529|  5.81k|}
client.c:abort_async:
  405|  5.81k|{
  406|  5.81k|    mp_mutex_lock(&mpctx->abort_lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  407|       |
  408|       |    // Destroy all => ensure any newly appearing work is aborted immediately.
  409|  5.81k|    if (ctx == NULL)
  ------------------
  |  Branch (409:9): [True: 0, False: 5.81k]
  ------------------
  410|      0|        mpctx->abort_all = true;
  411|       |
  412|  5.81k|    for (int n = 0; n < mpctx->num_abort_list; n++) {
  ------------------
  |  Branch (412:21): [True: 0, False: 5.81k]
  ------------------
  413|      0|        struct mp_abort_entry *abort = mpctx->abort_list[n];
  414|      0|        if (!ctx || (abort->client == ctx && (!type ||
  ------------------
  |  Branch (414:13): [True: 0, False: 0]
  |  Branch (414:22): [True: 0, False: 0]
  |  Branch (414:47): [True: 0, False: 0]
  ------------------
  415|      0|            (abort->client_work_type == type && abort->client_work_id == id))))
  ------------------
  |  Branch (415:14): [True: 0, False: 0]
  |  Branch (415:49): [True: 0, False: 0]
  ------------------
  416|      0|        {
  417|      0|            mp_abort_trigger_locked(mpctx, abort);
  418|      0|        }
  419|      0|    }
  420|       |
  421|  5.81k|    mp_mutex_unlock(&mpctx->abort_lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  422|  5.81k|}
client.c:core_thread:
  590|  5.81k|{
  591|  5.81k|    struct MPContext *mpctx = p;
  592|       |
  593|  5.81k|    mp_thread_set_name("core");
  594|       |
  595|  12.5k|    while (!mpctx->initialized && mpctx->stop_play != PT_QUIT)
  ------------------
  |  Branch (595:12): [True: 6.70k, False: 5.81k]
  |  Branch (595:35): [True: 6.70k, False: 0]
  ------------------
  596|  6.70k|        mp_idle(mpctx);
  597|       |
  598|  5.81k|    if (mpctx->initialized)
  ------------------
  |  Branch (598:9): [True: 5.81k, False: 0]
  ------------------
  599|  5.81k|        mp_play_files(mpctx);
  600|       |
  601|       |    // This actually waits until all clients are gone before actually
  602|       |    // destroying mpctx. Actual destruction is done by whatever destroys
  603|       |    // the last mpv_handle.
  604|  5.81k|    mp_shutdown_clients(mpctx);
  605|       |
  606|  5.81k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  5.81k|#define MP_THREAD_RETURN() return NULL
  ------------------
  607|  5.81k|}
client.c:lock_core:
  383|  58.1k|{
  384|  58.1k|    mp_dispatch_lock(ctx->mpctx->dispatch);
  385|  58.1k|}
client.c:unlock_core:
  388|  58.1k|{
  389|  58.1k|    mp_dispatch_unlock(ctx->mpctx->dispatch);
  390|  58.1k|}
client.c:send_event:
  731|   458k|{
  732|   458k|    mp_mutex_lock(&ctx->lock);
  ------------------
  |  |  131|   458k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  733|   458k|    uint64_t mask = 1ULL << event->event_id;
  734|   458k|    if (ctx->property_event_masks & mask)
  ------------------
  |  Branch (734:9): [True: 0, False: 458k]
  ------------------
  735|      0|        notify_property_events(ctx, event->event_id);
  736|   458k|    int r;
  737|   458k|    if (!(ctx->event_mask & mask)) {
  ------------------
  |  Branch (737:9): [True: 223k, False: 234k]
  ------------------
  738|   223k|        r = 0;
  739|   234k|    } else if (ctx->choked) {
  ------------------
  |  Branch (739:16): [True: 0, False: 234k]
  ------------------
  740|      0|        r = -1;
  741|   234k|    } else {
  742|   234k|        r = append_event(ctx, *event, copy);
  743|   234k|        if (r < 0) {
  ------------------
  |  Branch (743:13): [True: 0, False: 234k]
  ------------------
  744|      0|            MP_ERR(ctx, "Too many events queued.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  745|      0|            ctx->choked = true;
  746|      0|        }
  747|   234k|    }
  748|   458k|    mp_mutex_unlock(&ctx->lock);
  ------------------
  |  |  133|   458k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  749|   458k|    return r;
  750|   458k|}
client.c:append_event:
  717|   234k|{
  718|   234k|    if (ctx->num_events + ctx->reserved_events >= ctx->max_events)
  ------------------
  |  Branch (718:9): [True: 0, False: 234k]
  ------------------
  719|      0|        return -1;
  720|   234k|    if (copy)
  ------------------
  |  Branch (720:9): [True: 234k, False: 0]
  ------------------
  721|   234k|        dup_event_data(&event);
  722|   234k|    ctx->events[(ctx->first_event + ctx->num_events) % ctx->max_events] = event;
  723|   234k|    ctx->num_events++;
  724|   234k|    wakeup_client(ctx);
  725|   234k|    if (event.event_id == MPV_EVENT_SHUTDOWN)
  ------------------
  |  Branch (725:9): [True: 155, False: 234k]
  ------------------
  726|    155|        ctx->event_mask &= ctx->event_mask & ~(1ULL << MPV_EVENT_SHUTDOWN);
  727|   234k|    return 0;
  728|   234k|}
client.c:dup_event_data:
  673|   234k|{
  674|   234k|    switch (ev->event_id) {
  675|      0|    case MPV_EVENT_CLIENT_MESSAGE: {
  ------------------
  |  Branch (675:5): [True: 0, False: 234k]
  ------------------
  676|      0|        struct mpv_event_client_message *src = ev->data;
  677|      0|        struct mpv_event_client_message *msg =
  678|      0|            talloc_zero(NULL, struct mpv_event_client_message);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  679|      0|        for (int n = 0; n < src->num_args; n++) {
  ------------------
  |  Branch (679:25): [True: 0, False: 0]
  ------------------
  680|      0|            MP_TARRAY_APPEND(msg, msg->args, msg->num_args,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  681|      0|                             talloc_strdup(msg, src->args[n]));
  682|      0|        }
  683|      0|        ev->data = msg;
  684|      0|        break;
  685|      0|    }
  686|  94.7k|    case MPV_EVENT_START_FILE:
  ------------------
  |  Branch (686:5): [True: 94.7k, False: 139k]
  ------------------
  687|  94.7k|        ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_start_file));
  ------------------
  |  |   49|  94.7k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  94.7k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  94.7k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  94.7k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  94.7k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  688|  94.7k|        break;
  689|  94.7k|    case MPV_EVENT_END_FILE:
  ------------------
  |  Branch (689:5): [True: 94.7k, False: 139k]
  ------------------
  690|  94.7k|        ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_end_file));
  ------------------
  |  |   49|  94.7k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  94.7k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  94.7k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  94.7k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  94.7k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  691|  94.7k|        break;
  692|  45.2k|    default:
  ------------------
  |  Branch (692:5): [True: 45.2k, False: 189k]
  ------------------
  693|       |        // Doesn't use events with memory allocation.
  694|  45.2k|        if (ev->data)
  ------------------
  |  Branch (694:13): [True: 0, False: 45.2k]
  ------------------
  695|      0|            abort();
  696|   234k|    }
  697|   234k|}
client.c:wakeup_client:
  344|   234k|{
  345|   234k|    mp_mutex_lock(&ctx->wakeup_lock);
  ------------------
  |  |  131|   234k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  346|   234k|    if (!ctx->need_wakeup) {
  ------------------
  |  Branch (346:9): [True: 98.4k, False: 136k]
  ------------------
  347|  98.4k|        ctx->need_wakeup = true;
  348|  98.4k|        mp_cond_broadcast(&ctx->wakeup);
  349|  98.4k|        if (ctx->wakeup_cb)
  ------------------
  |  Branch (349:13): [True: 0, False: 98.4k]
  ------------------
  350|      0|            ctx->wakeup_cb(ctx->wakeup_cb_ctx);
  351|  98.4k|        if (ctx->wakeup_pipe[0] != -1)
  ------------------
  |  Branch (351:13): [True: 0, False: 98.4k]
  ------------------
  352|      0|            (void)write(ctx->wakeup_pipe[1], &(char){0}, 1);
  353|  98.4k|    }
  354|   234k|    mp_mutex_unlock(&ctx->wakeup_lock);
  ------------------
  |  |  133|   234k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  355|   234k|}
client.c:get_mp_type:
  977|  40.6k|{
  978|  40.6k|    if ((unsigned)format >= MP_ARRAY_SIZE(type_conv))
  ------------------
  |  |   48|  40.6k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (978:9): [True: 0, False: 40.6k]
  ------------------
  979|      0|        return NULL;
  980|  40.6k|    if (!type_conv[format].type)
  ------------------
  |  Branch (980:9): [True: 0, False: 40.6k]
  ------------------
  981|      0|        return NULL;
  982|  40.6k|    return &type_conv[format];
  983|  40.6k|}
client.c:run_client_command:
 1106|  11.6k|{
 1107|  11.6k|    if (!cmd)
  ------------------
  |  Branch (1107:9): [True: 0, False: 11.6k]
  ------------------
 1108|      0|        return MPV_ERROR_INVALID_PARAMETER;
 1109|  11.6k|    if (!ctx->mpctx->initialized) {
  ------------------
  |  Branch (1109:9): [True: 0, False: 11.6k]
  ------------------
 1110|      0|        talloc_free(cmd);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1111|      0|        return MPV_ERROR_UNINITIALIZED;
 1112|      0|    }
 1113|       |
 1114|  11.6k|    cmd->sender = ctx->name;
 1115|       |
 1116|  11.6k|    struct cmd_request req = {
 1117|  11.6k|        .mpctx = ctx->mpctx,
 1118|  11.6k|        .cmd = cmd,
 1119|  11.6k|        .res = res,
 1120|  11.6k|        .completion = MP_WAITER_INITIALIZER,
  ------------------
  |  |   19|  11.6k|#define MP_WAITER_INITIALIZER { \
  |  |   20|  11.6k|    .lock = MP_STATIC_MUTEX_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  106|  11.6k|#define MP_STATIC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
  |  |  ------------------
  |  |   21|  11.6k|    .wakeup = MP_STATIC_COND_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  105|  11.6k|#define MP_STATIC_COND_INITIALIZER { .cond = PTHREAD_COND_INITIALIZER, .clk_id = CLOCK_REALTIME }
  |  |  ------------------
  |  |   22|  11.6k|    }
  ------------------
 1121|  11.6k|    };
 1122|       |
 1123|  11.6k|    bool async = cmd->flags & MP_ASYNC_CMD;
 1124|       |
 1125|  11.6k|    lock_core(ctx);
 1126|  11.6k|    if (async) {
  ------------------
  |  Branch (1126:9): [True: 0, False: 11.6k]
  ------------------
 1127|      0|        run_command(ctx->mpctx, cmd, NULL, NULL, NULL);
 1128|  11.6k|    } else {
 1129|  11.6k|        struct mp_abort_entry *abort = NULL;
 1130|  11.6k|        if (cmd->def->can_abort) {
  ------------------
  |  Branch (1130:13): [True: 0, False: 11.6k]
  ------------------
 1131|      0|            abort = talloc_zero(NULL, struct mp_abort_entry);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1132|      0|            abort->client = ctx;
 1133|      0|        }
 1134|  11.6k|        run_command(ctx->mpctx, cmd, abort, cmd_complete, &req);
 1135|  11.6k|    }
 1136|  11.6k|    unlock_core(ctx);
 1137|       |
 1138|  11.6k|    if (!async)
  ------------------
  |  Branch (1138:9): [True: 11.6k, False: 0]
  ------------------
 1139|  11.6k|        mp_waiter_wait(&req.completion);
 1140|       |
 1141|  11.6k|    return req.status;
 1142|  11.6k|}
client.c:cmd_complete:
 1092|  11.6k|{
 1093|  11.6k|    struct cmd_request *req = cmd->on_completion_priv;
 1094|       |
 1095|  11.6k|    req->status = cmd->success ? 0 : MPV_ERROR_COMMAND;
  ------------------
  |  Branch (1095:19): [True: 11.6k, False: 0]
  ------------------
 1096|  11.6k|    if (req->res) {
  ------------------
  |  Branch (1096:9): [True: 0, False: 11.6k]
  ------------------
 1097|      0|        *req->res = cmd->result;
 1098|      0|        cmd->result = (mpv_node){0};
 1099|      0|    }
 1100|       |
 1101|       |    // Unblock the waiting thread (especially for async commands).
 1102|  11.6k|    mp_waiter_wakeup(&req->completion, 0);
 1103|  11.6k|}
client.c:prop_unref:
  169|  5.81k|{
  170|  5.81k|    if (!prop)
  ------------------
  |  Branch (170:9): [True: 5.81k, False: 0]
  ------------------
  171|  5.81k|        return;
  172|       |
  173|      0|    mp_assert(prop->refcount > 0);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  174|      0|    prop->refcount -= 1;
  175|      0|    if (!prop->refcount)
  ------------------
  |  Branch (175:9): [True: 0, False: 0]
  ------------------
  176|      0|        talloc_free(prop);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  177|      0|}
client.c:gen_property_change_event:
 1786|  98.2k|{
 1787|  98.2k|    if (!ctx->mpctx->initialized)
  ------------------
  |  Branch (1787:9): [True: 0, False: 98.2k]
  ------------------
 1788|      0|        return false;
 1789|       |
 1790|  98.2k|    while (1) {
  ------------------
  |  Branch (1790:12): [Folded - Ignored]
  ------------------
 1791|  98.2k|        if (ctx->cur_property_index >= ctx->num_properties) {
  ------------------
  |  Branch (1791:13): [True: 98.2k, False: 0]
  ------------------
 1792|  98.2k|            ctx->new_property_events &= ctx->num_properties > 0;
 1793|  98.2k|            if (!ctx->new_property_events)
  ------------------
  |  Branch (1793:17): [True: 98.2k, False: 0]
  ------------------
 1794|  98.2k|                break;
 1795|      0|            ctx->new_property_events = false;
 1796|      0|            ctx->cur_property_index = 0;
 1797|      0|        }
 1798|       |
 1799|      0|        struct observe_property *prop = ctx->properties[ctx->cur_property_index++];
 1800|       |
 1801|      0|        if (prop->value_ts == prop->change_ts &&    // not a stale value?
  ------------------
  |  Branch (1801:13): [True: 0, False: 0]
  ------------------
 1802|      0|            prop->value_ret_ts != prop->value_ts)   // other value than last time?
  ------------------
  |  Branch (1802:13): [True: 0, False: 0]
  ------------------
 1803|      0|        {
 1804|      0|            prop->value_ret_ts = prop->value_ts;
 1805|      0|            prop->waiting_for_hook = false;
 1806|      0|            prop_unref(ctx->cur_property);
 1807|      0|            ctx->cur_property = prop;
 1808|      0|            prop->refcount += 1;
 1809|       |
 1810|      0|            if (prop->value_valid)
  ------------------
  |  Branch (1810:17): [True: 0, False: 0]
  ------------------
 1811|      0|                m_option_copy(prop->type, &prop->value_ret, &prop->value);
 1812|       |
 1813|      0|            ctx->cur_property_event = (struct mpv_event_property){
 1814|      0|                .name = prop->name,
 1815|      0|                .format = prop->value_valid ? prop->format : 0,
  ------------------
  |  Branch (1815:27): [True: 0, False: 0]
  ------------------
 1816|      0|                .data = prop->value_valid ? &prop->value_ret : NULL,
  ------------------
  |  Branch (1816:25): [True: 0, False: 0]
  ------------------
 1817|      0|            };
 1818|      0|            *ctx->cur_event = (struct mpv_event){
 1819|      0|                .event_id = MPV_EVENT_PROPERTY_CHANGE,
 1820|      0|                .reply_userdata = prop->reply_id,
 1821|      0|                .data = &ctx->cur_property_event,
 1822|      0|            };
 1823|      0|            return true;
 1824|      0|        }
 1825|      0|    }
 1826|       |
 1827|  98.2k|    return false;
 1828|  98.2k|}
client.c:gen_log_message_event:
 1908|  98.2k|{
 1909|  98.2k|    if (ctx->messages) {
  ------------------
  |  Branch (1909:9): [True: 0, False: 98.2k]
  ------------------
 1910|      0|        struct mp_log_buffer_entry *msg =
 1911|      0|            mp_msg_log_buffer_read(ctx->messages);
 1912|      0|        if (msg) {
  ------------------
  |  Branch (1912:13): [True: 0, False: 0]
  ------------------
 1913|      0|            struct mpv_event_log_message *cmsg =
 1914|      0|                talloc_ptrtype(ctx->cur_event, cmsg);
  ------------------
  |  |   34|      0|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|      0|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1915|      0|            talloc_steal(cmsg, msg);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 1916|      0|            *cmsg = (struct mpv_event_log_message){
 1917|      0|                .prefix = msg->prefix,
 1918|      0|                .level = mp_log_levels[msg->level],
 1919|      0|                .log_level = mp_mpv_log_levels[msg->level],
 1920|      0|                .text = msg->text,
 1921|      0|            };
 1922|      0|            *ctx->cur_event = (struct mpv_event){
 1923|      0|                .event_id = MPV_EVENT_LOG_MESSAGE,
 1924|      0|                .data = cmsg,
 1925|      0|            };
 1926|      0|            return true;
 1927|      0|        }
 1928|      0|    }
 1929|  98.2k|    return false;
 1930|  98.2k|}

clipboard-vo.c:init:
   29|  5.81k|{
   30|  5.81k|    struct clipboard_vo_priv *priv = talloc_ptrtype(cl, priv);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   31|  5.81k|    priv->mpctx = params->mpctx;
   32|  5.81k|    priv->log = mp_log_new(priv, cl->log, "vo"),
   33|  5.81k|    cl->priv = priv;
   34|  5.81k|    return CLIPBOARD_SUCCESS;
   35|  5.81k|}

mp_clipboard_create:
   91|  5.81k|{
   92|  5.81k|    struct clipboard_ctx *cl = talloc_ptrtype(NULL, cl);
  ------------------
  |  |   34|  5.81k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.81k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   93|  5.81k|    *cl = (struct clipboard_ctx) {
   94|  5.81k|        .log = mp_log_new(cl, global->log, "clipboard"),
   95|  5.81k|        .monitor = params->flags & CLIPBOARD_INIT_ENABLE_MONITORING,
  ------------------
  |  |   27|  5.81k|#define CLIPBOARD_INIT_ENABLE_MONITORING (1 << 0)
  ------------------
   96|  5.81k|    };
   97|       |
   98|  23.2k|    for (int n = 0; params->backends && params->backends[n].name; n++) {
  ------------------
  |  Branch (98:21): [True: 23.2k, False: 0]
  |  Branch (98:41): [True: 23.2k, False: 0]
  ------------------
   99|  23.2k|        if (!params->backends[n].enabled)
  ------------------
  |  Branch (99:13): [True: 0, False: 23.2k]
  ------------------
  100|      0|            continue;
  101|  40.6k|        for (int i = 0; i < MP_ARRAY_SIZE(clipboard_backend_list); i++) {
  ------------------
  |  |   48|  40.6k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (101:25): [True: 23.2k, False: 17.4k]
  ------------------
  102|  23.2k|            const struct clipboard_backend *backend = clipboard_backend_list[i];
  103|  23.2k|            if (strcmp(params->backends[n].name, backend->name))
  ------------------
  |  Branch (103:17): [True: 17.4k, False: 5.81k]
  ------------------
  104|  17.4k|                continue;
  105|  5.81k|            if (backend->init(cl, params) != CLIPBOARD_SUCCESS)
  ------------------
  |  Branch (105:17): [True: 0, False: 5.81k]
  ------------------
  106|      0|                break;
  107|  5.81k|            cl->backend = backend;
  108|  5.81k|            goto success;
  109|  5.81k|        }
  110|  23.2k|    }
  111|       |
  112|      0|    MP_WARN(cl, "Failed to initialize any clipboard backend.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  113|      0|    talloc_free(cl);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  114|      0|    return NULL;
  115|  5.81k|success:
  116|  5.81k|    MP_VERBOSE(cl, "Initialized %s clipboard backend.\n", cl->backend->name);
  ------------------
  |  |   88|  5.81k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.81k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  117|  5.81k|    return cl;
  118|  5.81k|}
mp_clipboard_destroy:
  121|  11.6k|{
  122|  11.6k|    if (cl && cl->backend->uninit)
  ------------------
  |  Branch (122:9): [True: 5.81k, False: 5.81k]
  |  Branch (122:15): [True: 0, False: 5.81k]
  ------------------
  123|      0|        cl->backend->uninit(cl);
  124|  11.6k|    talloc_free(cl);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
  125|  11.6k|}
mp_clipboard_data_changed:
  128|   140k|{
  129|   140k|    if (cl && cl->backend->data_changed && cl->monitor)
  ------------------
  |  Branch (129:9): [True: 133k, False: 6.70k]
  |  Branch (129:15): [True: 0, False: 133k]
  |  Branch (129:44): [True: 0, False: 0]
  ------------------
  130|      0|        return cl->backend->data_changed(cl);
  131|   140k|    return false;
  132|   140k|}
reinit_clipboard:
  156|  5.81k|{
  157|  5.81k|    mp_clipboard_destroy(mpctx->clipboard);
  158|  5.81k|    mpctx->clipboard = NULL;
  159|       |
  160|  5.81k|    struct clipboard_opts *opts = mp_get_config_group(NULL, mpctx->global, &clipboard_conf);
  161|  5.81k|    if (opts->backends && opts->backends[0].name) {
  ------------------
  |  Branch (161:9): [True: 5.81k, False: 0]
  |  Branch (161:27): [True: 5.81k, False: 0]
  ------------------
  162|  5.81k|        struct clipboard_init_params params = {
  163|  5.81k|            .mpctx = mpctx,
  164|  5.81k|            .flags = opts->monitor ? CLIPBOARD_INIT_ENABLE_MONITORING : 0,
  ------------------
  |  |   27|      0|#define CLIPBOARD_INIT_ENABLE_MONITORING (1 << 0)
  ------------------
  |  Branch (164:22): [True: 0, False: 5.81k]
  ------------------
  165|  5.81k|            .backends = opts->backends,
  166|  5.81k|        };
  167|  5.81k|        mpctx->clipboard = mp_clipboard_create(&params, mpctx->global);
  168|  5.81k|    }
  169|  5.81k|    talloc_free(opts);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  170|  5.81k|}
clipboard.c:get_desc:
   50|  11.6k|{
   51|  11.6k|    if (index >= MP_ARRAY_SIZE(clipboard_backend_list))
  ------------------
  |  |   48|  11.6k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (51:9): [True: 5.81k, False: 5.81k]
  ------------------
   52|  5.81k|        return false;
   53|  5.81k|    const struct clipboard_backend *backend = clipboard_backend_list[index];
   54|  5.81k|    *dst = (struct m_obj_desc) {
   55|  5.81k|        .name = backend->name,
   56|  5.81k|        .description = backend->desc,
   57|  5.81k|    };
   58|  5.81k|    return true;
   59|  11.6k|}

mp_hook_test_completion:
  194|   298k|{
  195|   298k|    struct command_ctx *cmd = mpctx->command_ctx;
  196|   298k|    for (int n = 0; n < cmd->num_hooks; n++) {
  ------------------
  |  Branch (196:21): [True: 0, False: 298k]
  ------------------
  197|      0|        struct hook_handler *h = cmd->hooks[n];
  198|      0|        if (h->active && strcmp(h->type, type) == 0) {
  ------------------
  |  Branch (198:13): [True: 0, False: 0]
  |  Branch (198:26): [True: 0, False: 0]
  ------------------
  199|      0|            if (!mp_client_id_exists(mpctx, h->client_id)) {
  ------------------
  |  Branch (199:17): [True: 0, False: 0]
  ------------------
  200|      0|                MP_WARN(mpctx, "client removed during hook handling\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  201|       |                // Trigger completion of this hook and continue with the next one.
  202|      0|                mp_hook_continue(mpctx, h->client_id, h->seq);
  203|      0|                hook_remove(mpctx, h);
  204|      0|            }
  205|      0|            return false;
  206|      0|        }
  207|      0|    }
  208|   298k|    return true;
  209|   298k|}
mp_hook_start:
  259|   298k|{
  260|   298k|    run_next_hook_handler(mpctx, type, 0);
  261|   298k|}
mp_get_property_id:
 4572|  15.6k|{
 4573|  15.6k|    struct command_ctx *ctx = mpctx->command_ctx;
 4574|   566k|    for (int n = 0; ctx->properties[n].name; n++) {
  ------------------
  |  Branch (4574:21): [True: 566k, False: 0]
  ------------------
 4575|   566k|        if (match_property(ctx->properties[n].name, name))
  ------------------
  |  Branch (4575:13): [True: 15.6k, False: 550k]
  ------------------
 4576|  15.6k|            return n;
 4577|   566k|    }
 4578|      0|    return -1;
 4579|  15.6k|}
mp_property_expand_string:
 4626|  77.3k|{
 4627|  77.3k|    struct command_ctx *ctx = mpctx->command_ctx;
 4628|  77.3k|    return m_properties_expand_string(ctx->properties, str, mpctx);
 4629|  77.3k|}
mp_cmd_ctx_complete:
 5395|  11.6k|{
 5396|  11.6k|    cmd->completed = true;
 5397|  11.6k|    if (!cmd->success)
  ------------------
  |  Branch (5397:9): [True: 0, False: 11.6k]
  ------------------
 5398|      0|        mpv_free_node_contents(&cmd->result);
 5399|  11.6k|    if (cmd->on_completion)
  ------------------
  |  Branch (5399:9): [True: 11.6k, False: 0]
  ------------------
 5400|  11.6k|        cmd->on_completion(cmd);
 5401|  11.6k|    if (cmd->abort)
  ------------------
  |  Branch (5401:9): [True: 0, False: 11.6k]
  ------------------
 5402|      0|        mp_abort_remove(cmd->mpctx, cmd->abort);
 5403|  11.6k|    mpv_free_node_contents(&cmd->result);
 5404|  11.6k|    talloc_free(cmd);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
 5405|  11.6k|}
run_command:
 5442|  11.6k|{
 5443|  11.6k|    struct mp_cmd_ctx *ctx = talloc(NULL, struct mp_cmd_ctx);
  ------------------
  |  |   26|  11.6k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  11.6k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  11.6k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5444|  11.6k|    *ctx = (struct mp_cmd_ctx){
 5445|  11.6k|        .mpctx = mpctx,
 5446|  11.6k|        .cmd = talloc_steal(ctx, cmd),
  ------------------
  |  |   38|  11.6k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  11.6k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 5447|  11.6k|        .args = cmd->args,
 5448|  11.6k|        .num_args = cmd->nargs,
 5449|  11.6k|        .priv = cmd->def->priv,
 5450|  11.6k|        .abort = talloc_steal(ctx, abort),
  ------------------
  |  |   38|  11.6k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  11.6k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 5451|  11.6k|        .success = true,
 5452|  11.6k|        .completed = true,
 5453|  11.6k|        .on_completion = on_completion,
 5454|  11.6k|        .on_completion_priv = on_completion_priv,
 5455|  11.6k|    };
 5456|       |
 5457|  11.6k|    if (!ctx->abort && cmd->def->can_abort)
  ------------------
  |  Branch (5457:9): [True: 11.6k, False: 0]
  |  Branch (5457:24): [True: 0, False: 11.6k]
  ------------------
 5458|      0|        ctx->abort = talloc_zero(ctx, struct mp_abort_entry);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5459|       |
 5460|  11.6k|    mp_assert(cmd->def->can_abort == !!ctx->abort);
  ------------------
  |  |   41|  11.6k|#define mp_assert assert
  ------------------
 5461|       |
 5462|  11.6k|    if (ctx->abort) {
  ------------------
  |  Branch (5462:9): [True: 0, False: 11.6k]
  ------------------
 5463|      0|        ctx->abort->coupled_to_playback |= cmd->def->abort_on_playback_end;
 5464|      0|        mp_abort_add(mpctx, ctx->abort);
 5465|      0|    }
 5466|       |
 5467|  11.6k|    struct MPOpts *opts = mpctx->opts;
 5468|  11.6k|    ctx->on_osd = cmd->flags & MP_ON_OSD_FLAGS;
 5469|  11.6k|    bool auto_osd = ctx->on_osd == MP_ON_OSD_AUTO;
 5470|  11.6k|    ctx->msg_osd = auto_osd || (ctx->on_osd & MP_ON_OSD_MSG);
  ------------------
  |  Branch (5470:20): [True: 0, False: 11.6k]
  |  Branch (5470:32): [True: 0, False: 11.6k]
  ------------------
 5471|  11.6k|    ctx->bar_osd = auto_osd || (ctx->on_osd & MP_ON_OSD_BAR);
  ------------------
  |  Branch (5471:20): [True: 0, False: 11.6k]
  |  Branch (5471:32): [True: 0, False: 11.6k]
  ------------------
 5472|  11.6k|    ctx->seek_msg_osd = auto_osd ? opts->osd_on_seek & 2 : ctx->msg_osd;
  ------------------
  |  Branch (5472:25): [True: 0, False: 11.6k]
  ------------------
 5473|  11.6k|    ctx->seek_bar_osd = auto_osd ? opts->osd_on_seek & 1 : ctx->bar_osd;
  ------------------
  |  Branch (5473:25): [True: 0, False: 11.6k]
  ------------------
 5474|       |
 5475|  11.6k|    bool noise = cmd->def->is_noisy || cmd->mouse_move;
  ------------------
  |  Branch (5475:18): [True: 0, False: 11.6k]
  |  Branch (5475:40): [True: 0, False: 11.6k]
  ------------------
 5476|  11.6k|    mp_cmd_dump(mpctx->log, noise ? MSGL_TRACE : MSGL_DEBUG, "Run command:", cmd);
  ------------------
  |  Branch (5476:29): [True: 0, False: 11.6k]
  ------------------
 5477|       |
 5478|  11.6k|    if (cmd->flags & MP_EXPAND_PROPERTIES) {
  ------------------
  |  Branch (5478:9): [True: 0, False: 11.6k]
  ------------------
 5479|      0|        for (int n = 0; n < cmd->nargs; n++) {
  ------------------
  |  Branch (5479:25): [True: 0, False: 0]
  ------------------
 5480|      0|            if (cmd->args[n].type->type == CONF_TYPE_STRING) {
  ------------------
  |  |  233|      0|#define CONF_TYPE_STRING        (&m_option_type_string)
  ------------------
  |  Branch (5480:17): [True: 0, False: 0]
  ------------------
 5481|      0|                char *s = mp_property_expand_string(mpctx, cmd->args[n].v.s);
 5482|      0|                if (!s) {
  ------------------
  |  Branch (5482:21): [True: 0, False: 0]
  ------------------
 5483|      0|                    ctx->success = false;
 5484|      0|                    mp_cmd_ctx_complete(ctx);
 5485|      0|                    return;
 5486|      0|                }
 5487|      0|                talloc_free(cmd->args[n].v.s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 5488|      0|                cmd->args[n].v.s = s;
 5489|      0|            }
 5490|      0|        }
 5491|      0|    }
 5492|       |
 5493|  11.6k|    if (cmd->def->spawn_thread) {
  ------------------
  |  Branch (5493:9): [True: 0, False: 11.6k]
  ------------------
 5494|      0|        mpctx->outstanding_async += 1; // prevent that core disappears
 5495|      0|        if (!mp_thread_pool_queue(mpctx->thread_pool,
  ------------------
  |  Branch (5495:13): [True: 0, False: 0]
  ------------------
 5496|      0|                                  run_command_on_worker_thread, ctx))
 5497|      0|        {
 5498|      0|            mpctx->outstanding_async -= 1;
 5499|      0|            ctx->success = false;
 5500|      0|            mp_cmd_ctx_complete(ctx);
 5501|      0|        }
 5502|  11.6k|    } else {
 5503|  11.6k|        bool exec_async = cmd->def->exec_async;
 5504|  11.6k|        cmd->def->handler(ctx);
 5505|  11.6k|        if (!exec_async)
  ------------------
  |  Branch (5505:13): [True: 11.6k, False: 0]
  ------------------
 5506|  11.6k|            mp_cmd_ctx_complete(ctx);
 5507|  11.6k|    }
 5508|  11.6k|}
mp_abort_cache_dumping:
 6926|  94.7k|{
 6927|  94.7k|    struct command_ctx *ctx = mpctx->command_ctx;
 6928|       |
 6929|  94.7k|    if (ctx->cache_dump_cmd)
  ------------------
  |  Branch (6929:9): [True: 0, False: 94.7k]
  ------------------
 6930|      0|        mp_cancel_trigger(ctx->cache_dump_cmd->abort->cancel);
 6931|  94.7k|    cache_dump_poll(mpctx);
 6932|  94.7k|    mp_assert(!ctx->cache_dump_cmd); // synchronous abort, must have worked
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
 6933|  94.7k|}
command_uninit:
 7543|  5.81k|{
 7544|  5.81k|    struct command_ctx *ctx = mpctx->command_ctx;
 7545|       |
 7546|  5.81k|    mp_assert(!ctx->cache_dump_cmd); // closing the demuxer must have aborted it
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
 7547|       |
 7548|  5.81k|    overlay_uninit(mpctx);
 7549|  5.81k|    ao_hotplug_destroy(ctx->hotplug);
 7550|       |
 7551|  5.81k|    m_option_free(&script_props_type, &ctx->script_props);
 7552|       |
 7553|  5.81k|    talloc_free(mpctx->command_ctx);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 7554|  5.81k|    mpctx->command_ctx = NULL;
 7555|  5.81k|}
command_init:
 7563|  5.81k|{
 7564|  5.81k|    struct command_ctx *ctx = talloc(NULL, struct command_ctx);
  ------------------
  |  |   26|  5.81k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7565|  5.81k|    *ctx = (struct command_ctx){
 7566|  5.81k|        .last_seek_pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  5.81k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 7567|  5.81k|    };
 7568|  5.81k|    mpctx->command_ctx = ctx;
 7569|       |
 7570|  5.81k|    int num_base = MP_ARRAY_SIZE(mp_properties_base);
  ------------------
  |  |   48|  5.81k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
 7571|  5.81k|    int num_opts = m_config_get_co_count(mpctx->mconfig);
 7572|  5.81k|    ctx->properties =
 7573|  5.81k|        talloc_zero_array(ctx, struct m_property, num_base + num_opts + 1);
  ------------------
  |  |   30|  5.81k|#define talloc_zero_array               ta_xznew_array
  |  |  ------------------
  |  |  |  |  136|  5.81k|#define ta_xznew_array(...)             ta_oom_g(ta_znew_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7574|  5.81k|    memcpy(ctx->properties, mp_properties_base, sizeof(mp_properties_base));
 7575|       |
 7576|  5.81k|    const char **prop_names = talloc_array(NULL, const char *, num_base);
  ------------------
  |  |   29|  5.81k|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|  5.81k|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7577|  1.07M|    for (int i = 0; i < num_base; ++i)
  ------------------
  |  Branch (7577:21): [True: 1.06M, False: 5.81k]
  ------------------
 7578|  1.06M|        prop_names[i] = mp_properties_base[i].name;
 7579|  5.81k|    qsort(prop_names, num_base, sizeof(const char *), str_compare);
 7580|       |
 7581|  5.81k|    int count = num_base;
 7582|  4.34M|    for (int n = 0; n < num_opts; n++) {
  ------------------
  |  Branch (7582:21): [True: 4.33M, False: 5.81k]
  ------------------
 7583|  4.33M|        struct m_config_option *co = m_config_get_co_index(mpctx->mconfig, n);
 7584|  4.33M|        mp_assert(co->name[0]);
  ------------------
  |  |   41|  4.33M|#define mp_assert assert
  ------------------
 7585|  4.33M|        if (co->opt->flags & M_OPT_NOPROP)
  ------------------
  |  |  465|  4.33M|#define M_OPT_NOPROP            (UINT64_C(1) << 60)
  ------------------
  |  Branch (7585:13): [True: 162k, False: 4.17M]
  ------------------
 7586|   162k|            continue;
 7587|       |
 7588|  4.17M|        struct m_property prop = {
 7589|  4.17M|            .name = co->name,
 7590|  4.17M|            .call = mp_property_generic_option,
 7591|  4.17M|            .is_option = true,
 7592|  4.17M|        };
 7593|       |
 7594|  4.17M|        if (co->opt->type == &m_option_type_alias) {
  ------------------
  |  Branch (7594:13): [True: 133k, False: 4.03M]
  ------------------
 7595|   133k|            char buf[M_CONFIG_MAX_OPT_NAME_LEN];
 7596|   133k|            const char *alias = m_config_shadow_get_alias_from_opt(mpctx->mconfig->shadow, co->opt_id,
 7597|   133k|                                                                   buf, sizeof(buf));
 7598|   133k|            prop.priv = talloc_strdup(ctx, alias);
  ------------------
  |  |   50|   133k|#define talloc_strdup                   ta_xstrdup
  ------------------
 7599|       |
 7600|   133k|            prop.call = co->opt->deprecation_message ?
  ------------------
  |  Branch (7600:25): [True: 40.6k, False: 92.9k]
  ------------------
 7601|  92.9k|                            mp_property_deprecated_alias : mp_property_alias;
 7602|       |
 7603|       |            // Check whether this eventually arrives at a real option. If not,
 7604|       |            // it's some CLI special handling thing. For example, "nosound" is
 7605|       |            // mapped to "no-audio", which has CLI special-handling, and cannot
 7606|       |            // be set as property.
 7607|   133k|            struct m_config_option *co2 = co;
 7608|   267k|            while (co2 && co2->opt->type == &m_option_type_alias) {
  ------------------
  |  Branch (7608:20): [True: 267k, False: 0]
  |  Branch (7608:27): [True: 133k, False: 133k]
  ------------------
 7609|   133k|                const char *co2_alias = m_config_shadow_get_alias_from_opt(mpctx->mconfig->shadow, co2->opt_id,
 7610|   133k|                                                                           buf, sizeof(buf));
 7611|   133k|                co2 = m_config_get_co_raw(mpctx->mconfig, bstr0(co2_alias));
 7612|   133k|            }
 7613|   133k|            if (!co2)
  ------------------
  |  Branch (7613:17): [True: 0, False: 133k]
  ------------------
 7614|      0|                continue;
 7615|   133k|        }
 7616|       |
 7617|       |        // The option might be covered by a manual property already.
 7618|  4.17M|        if (bsearch(&prop.name, prop_names, num_base, sizeof(const char *), str_compare))
  ------------------
  |  Branch (7618:13): [True: 139k, False: 4.03M]
  ------------------
 7619|   139k|            continue;
 7620|       |
 7621|  4.03M|        ctx->properties[count++] = prop;
 7622|  4.03M|    }
 7623|       |
 7624|  5.81k|    node_init(&ctx->mdata, MPV_FORMAT_NODE_ARRAY, NULL);
 7625|  5.81k|    talloc_steal(ctx, ctx->mdata.u.list);
  ------------------
  |  |   38|  5.81k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  5.81k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 7626|       |
 7627|  5.81k|    node_init(&ctx->udata, MPV_FORMAT_NODE_MAP, NULL);
 7628|  5.81k|    talloc_steal(ctx, ctx->udata.u.list);
  ------------------
  |  |   38|  5.81k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  5.81k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 7629|  5.81k|    talloc_free(prop_names);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 7630|  5.81k|}
handle_command_updates:
 7678|   140k|{
 7679|   140k|    struct command_ctx *ctx = mpctx->command_ctx;
 7680|       |
 7681|       |    // This is a bit messy: ao_hotplug wakes up the player, and then we have
 7682|       |    // to recheck the state. Then the client(s) will read the property.
 7683|   140k|    if (ctx->hotplug && ao_hotplug_check_update(ctx->hotplug))
  ------------------
  |  Branch (7683:9): [True: 0, False: 140k]
  |  Branch (7683:25): [True: 0, False: 0]
  ------------------
 7684|      0|        mp_notify_property(mpctx, "audio-device-list");
 7685|       |
 7686|       |    // Depends on polling demuxer wakeup callback notifications.
 7687|   140k|    cache_dump_poll(mpctx);
 7688|   140k|}
run_command_opts:
 7691|  9.45k|{
 7692|  9.45k|    struct MPOpts *opts = mpctx->opts;
 7693|  9.45k|    struct command_ctx *ctx = mpctx->command_ctx;
 7694|       |
 7695|  9.45k|    if (!opts->input_commands || ctx->command_opts_processed)
  ------------------
  |  Branch (7695:9): [True: 9.45k, False: 0]
  |  Branch (7695:34): [True: 0, False: 0]
  ------------------
 7696|  9.45k|        return;
 7697|       |
 7698|       |    // Take easy way out and add these to the input queue.
 7699|      0|    for (int i = 0; opts->input_commands[i]; i++) {
  ------------------
  |  Branch (7699:21): [True: 0, False: 0]
  ------------------
 7700|      0|        struct mp_cmd *cmd = mp_input_parse_cmd(mpctx->input, bstr0(opts->input_commands[i]),
 7701|      0|                                                "the command line");
 7702|      0|        cmd->coalesce = true;
 7703|      0|        mp_input_queue_cmd(mpctx->input, cmd);
 7704|      0|    }
 7705|      0|    ctx->command_opts_processed = true;
 7706|      0|}
mp_notify:
 7709|   458k|{
 7710|       |    // The OSD can implicitly reference some properties.
 7711|   458k|    mpctx->osd_idle_update = true;
 7712|       |
 7713|   458k|    command_event(mpctx, event, arg);
 7714|       |
 7715|   458k|    mp_client_broadcast_event(mpctx, event, arg);
 7716|   458k|}
mp_option_change_callback:
 7748|  5.81k|{
 7749|  5.81k|    struct MPContext *mpctx = ctx;
 7750|  5.81k|    struct MPOpts *opts = mpctx->opts;
 7751|  5.81k|    void *opt_ptr = !co ? NULL : co->data; // NULL on start
  ------------------
  |  Branch (7751:21): [True: 5.81k, False: 0]
  ------------------
 7752|       |
 7753|  5.81k|    if (co)
  ------------------
  |  Branch (7753:9): [True: 0, False: 5.81k]
  ------------------
 7754|      0|        mp_notify_property(mpctx, co->name);
 7755|  5.81k|    if (opt_ptr == &opts->media_title)
  ------------------
  |  Branch (7755:9): [True: 0, False: 5.81k]
  ------------------
 7756|      0|        mp_notify(mpctx, MP_EVENT_METADATA_UPDATE, NULL);
 7757|       |
 7758|  5.81k|    if (self_update)
  ------------------
  |  Branch (7758:9): [True: 0, False: 5.81k]
  ------------------
 7759|      0|        return;
 7760|       |
 7761|       |    // Run these immediately.
 7762|  5.81k|    if (co && !co->coalesce) {
  ------------------
  |  Branch (7762:9): [True: 0, False: 5.81k]
  |  Branch (7762:15): [True: 0, False: 0]
  ------------------
 7763|      0|        struct mp_option_callback callback = {.co = co, .flags = flags};
 7764|      0|        mp_option_run_callback(mpctx, &callback);
 7765|      0|        return;
 7766|      0|    }
 7767|       |
 7768|       |    // Coalesce redundant updates and only keep the newest one.
 7769|  5.81k|    bool drop = false;
 7770|  5.81k|    for (int i = 0; i < mpctx->num_option_callbacks; i++) {
  ------------------
  |  Branch (7770:21): [True: 0, False: 5.81k]
  ------------------
 7771|      0|        if ((mpctx->option_callbacks[i].co && opt_ptr == mpctx->option_callbacks[i].co->data) ||
  ------------------
  |  Branch (7771:14): [True: 0, False: 0]
  |  Branch (7771:47): [True: 0, False: 0]
  ------------------
 7772|      0|            (flags && flags == mpctx->option_callbacks[i].flags))
  ------------------
  |  Branch (7772:14): [True: 0, False: 0]
  |  Branch (7772:23): [True: 0, False: 0]
  ------------------
 7773|      0|            drop = true;
 7774|      0|        if (!drop)
  ------------------
  |  Branch (7774:13): [True: 0, False: 0]
  ------------------
 7775|      0|            continue;
 7776|      0|        if (i < mpctx->num_option_callbacks - 1)
  ------------------
  |  Branch (7776:13): [True: 0, False: 0]
  ------------------
 7777|      0|            mpctx->option_callbacks[i] = mpctx->option_callbacks[i + 1];
 7778|      0|        if (i == mpctx->num_option_callbacks - 1) {
  ------------------
  |  Branch (7778:13): [True: 0, False: 0]
  ------------------
 7779|      0|            mpctx->option_callbacks[i].co = co;
 7780|      0|            mpctx->option_callbacks[i].flags = flags;
 7781|      0|        }
 7782|      0|    }
 7783|       |
 7784|  5.81k|    if (!drop) {
  ------------------
  |  Branch (7784:9): [True: 5.81k, False: 0]
  ------------------
 7785|  5.81k|        struct mp_option_callback callback = {.co = co, .flags = flags};
 7786|  5.81k|        MP_TARRAY_APPEND(mpctx, mpctx->option_callbacks, mpctx->num_option_callbacks, callback);
  ------------------
  |  |  105|  5.81k|    do {                                            \
  |  |  106|  5.81k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.81k|    do {                                            \
  |  |  |  |   97|  5.81k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.81k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.81k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.81k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.81k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.81k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.81k|    do {                                                        \
  |  |  |  |  |  |   89|  5.81k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.81k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.81k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.81k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.81k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.81k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.81k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.81k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  5.81k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  5.81k|        (idxvar)++;                                 \
  |  |  109|  5.81k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 7787|  5.81k|    }
 7788|  5.81k|}
mp_option_run_callback:
 7791|  5.81k|{
 7792|  5.81k|    struct MPOpts *opts = mpctx->opts;
 7793|  5.81k|    struct m_config_option *co = callback->co;
 7794|  5.81k|    void *opt_ptr = co ? co->data : NULL;
  ------------------
  |  Branch (7794:21): [True: 0, False: 5.81k]
  ------------------
 7795|  5.81k|    uint64_t flags = callback->flags;
 7796|       |
 7797|  5.81k|    if (flags & UPDATE_TERM)
  ------------------
  |  |  429|  5.81k|#define UPDATE_TERM             (UINT64_C(1) << 0)   // terminal options
  ------------------
  |  Branch (7797:9): [True: 5.81k, False: 0]
  ------------------
 7798|  5.81k|        mp_update_logging(mpctx, false);
 7799|       |
 7800|  5.81k|    if (flags & (UPDATE_OSD | UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |  431|  5.81k|#define UPDATE_OSD              (UINT64_C(1) << 2)   // related to OSD rendering
  ------------------
                  if (flags & (UPDATE_OSD | UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |  430|  5.81k|#define UPDATE_SUB_FILT         (UINT64_C(1) << 1)   // subtitle filter options
  ------------------
                  if (flags & (UPDATE_OSD | UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |  442|  5.81k|#define UPDATE_SUB_HARD         (UINT64_C(1) << 13)  // subtitle opts. that need full reinit
  ------------------
  |  Branch (7800:9): [True: 5.81k, False: 0]
  ------------------
 7801|  17.4k|        for (int n = 0; n < num_ptracks[STREAM_SUB]; n++) {
  ------------------
  |  Branch (7801:25): [True: 11.6k, False: 5.81k]
  ------------------
 7802|  11.6k|            struct track *track = mpctx->current_track[n][STREAM_SUB];
 7803|  11.6k|            struct dec_sub *sub = track ? track->d_sub : NULL;
  ------------------
  |  Branch (7803:35): [True: 0, False: 11.6k]
  ------------------
 7804|  11.6k|            if (sub) {
  ------------------
  |  Branch (7804:17): [True: 0, False: 11.6k]
  ------------------
 7805|      0|                int ret = sub_control(sub, SD_CTRL_UPDATE_OPTS, &flags);
 7806|      0|                if (ret == CONTROL_OK && flags & (UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |   68|      0|#define CONTROL_OK 1
  ------------------
                              if (ret == CONTROL_OK && flags & (UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |  430|      0|#define UPDATE_SUB_FILT         (UINT64_C(1) << 1)   // subtitle filter options
  ------------------
                              if (ret == CONTROL_OK && flags & (UPDATE_SUB_FILT | UPDATE_SUB_HARD)) {
  ------------------
  |  |  442|      0|#define UPDATE_SUB_HARD         (UINT64_C(1) << 13)  // subtitle opts. that need full reinit
  ------------------
  |  Branch (7806:21): [True: 0, False: 0]
  |  Branch (7806:42): [True: 0, False: 0]
  ------------------
 7807|      0|                    sub_redecode_cached_packets(sub);
 7808|      0|                    sub_reset(sub);
 7809|      0|                    if (track->selected)
  ------------------
  |  Branch (7809:25): [True: 0, False: 0]
  ------------------
 7810|      0|                        reselect_demux_stream(mpctx, track, true);
 7811|      0|                }
 7812|      0|            }
 7813|  11.6k|        }
 7814|       |        // For subs on a still image.
 7815|  5.81k|        redraw_subs(mpctx);
 7816|  5.81k|        osd_changed(mpctx->osd);
 7817|  5.81k|    }
 7818|       |
 7819|  5.81k|    if (flags & UPDATE_BUILTIN_SCRIPTS)
  ------------------
  |  |  432|  5.81k|#define UPDATE_BUILTIN_SCRIPTS  (UINT64_C(1) << 3)   // osc/ytdl/stats
  ------------------
  |  Branch (7819:9): [True: 5.81k, False: 0]
  ------------------
 7820|  5.81k|        mp_load_builtin_scripts(mpctx);
 7821|       |
 7822|  5.81k|    if (flags & UPDATE_IMGPAR) {
  ------------------
  |  |  433|  5.81k|#define UPDATE_IMGPAR           (UINT64_C(1) << 4)   // video image params overrides
  ------------------
  |  Branch (7822:9): [True: 5.81k, False: 0]
  ------------------
 7823|  5.81k|        struct track *track = mpctx->current_track[0][STREAM_VIDEO];
 7824|  5.81k|        if (track && track->dec) {
  ------------------
  |  Branch (7824:13): [True: 0, False: 5.81k]
  |  Branch (7824:22): [True: 0, False: 0]
  ------------------
 7825|      0|            mp_decoder_wrapper_reset_params(track->dec);
 7826|      0|            mp_force_video_refresh(mpctx);
 7827|      0|        }
 7828|  5.81k|    }
 7829|       |
 7830|  5.81k|    if (flags & UPDATE_INPUT)
  ------------------
  |  |  434|  5.81k|#define UPDATE_INPUT            (UINT64_C(1) << 5)   // mostly --input-* options
  ------------------
  |  Branch (7830:9): [True: 5.81k, False: 0]
  ------------------
 7831|  5.81k|        mp_input_update_opts(mpctx->input);
 7832|       |
 7833|  5.81k|    if (flags & UPDATE_CLIPBOARD)
  ------------------
  |  |  446|  5.81k|#define UPDATE_CLIPBOARD        (UINT64_C(1) << 17)  // reinit the clipboard
  ------------------
  |  Branch (7833:9): [True: 5.81k, False: 0]
  ------------------
 7834|  5.81k|        reinit_clipboard(mpctx);
 7835|       |
 7836|  5.81k|    if (flags & UPDATE_SUB_EXTS)
  ------------------
  |  |  443|  5.81k|#define UPDATE_SUB_EXTS         (UINT64_C(1) << 14)  // update internal list of sub exts
  ------------------
  |  Branch (7836:9): [True: 5.81k, False: 0]
  ------------------
 7837|  5.81k|        mp_update_subtitle_exts(mpctx->opts);
 7838|       |
 7839|  5.81k|    if (opt_ptr == &opts->ipc_path || opt_ptr == &opts->ipc_client) {
  ------------------
  |  Branch (7839:9): [True: 0, False: 5.81k]
  |  Branch (7839:39): [True: 0, False: 5.81k]
  ------------------
 7840|      0|        mp_uninit_ipc(mpctx->ipc_ctx);
 7841|      0|        mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global);
 7842|      0|    }
 7843|       |
 7844|  5.81k|    if (flags & UPDATE_VO && mpctx->video_out) {
  ------------------
  |  |  445|  11.6k|#define UPDATE_VO               (UINT64_C(1) << 16)  // reinit the VO
  ------------------
  |  Branch (7844:9): [True: 5.81k, False: 0]
  |  Branch (7844:30): [True: 0, False: 5.81k]
  ------------------
 7845|      0|        struct track *track = mpctx->current_track[0][STREAM_VIDEO];
 7846|      0|        uninit_video_out(mpctx);
 7847|      0|        handle_force_window(mpctx, true);
 7848|      0|        reinit_video_chain(mpctx);
 7849|      0|        if (track)
  ------------------
  |  Branch (7849:13): [True: 0, False: 0]
  ------------------
 7850|      0|            queue_seek(mpctx, MPSEEK_RELATIVE, 0.0, MPSEEK_EXACT, 0);
 7851|       |
 7852|      0|        mp_wakeup_core(mpctx);
 7853|      0|    }
 7854|       |
 7855|  5.81k|    if (flags & UPDATE_AUDIO)
  ------------------
  |  |  435|  5.81k|#define UPDATE_AUDIO            (UINT64_C(1) << 6)   // --audio-channels etc.
  ------------------
  |  Branch (7855:9): [True: 5.81k, False: 0]
  ------------------
 7856|  5.81k|        reload_audio_output(mpctx);
 7857|       |
 7858|  5.81k|    if (flags & UPDATE_PRIORITY)
  ------------------
  |  |  436|  5.81k|#define UPDATE_PRIORITY         (UINT64_C(1) << 7)   // --priority (Windows-only)
  ------------------
  |  Branch (7858:9): [True: 5.81k, False: 0]
  ------------------
 7859|  5.81k|        update_priority(mpctx);
 7860|       |
 7861|  5.81k|    if (flags & UPDATE_SCREENSAVER)
  ------------------
  |  |  437|  5.81k|#define UPDATE_SCREENSAVER      (UINT64_C(1) << 8)   // --stop-screensaver
  ------------------
  |  Branch (7861:9): [True: 5.81k, False: 0]
  ------------------
 7862|  5.81k|        update_screensaver_state(mpctx);
 7863|       |
 7864|  5.81k|    if (flags & UPDATE_VOL)
  ------------------
  |  |  438|  5.81k|#define UPDATE_VOL              (UINT64_C(1) << 9)   // softvol related options
  ------------------
  |  Branch (7864:9): [True: 5.81k, False: 0]
  ------------------
 7865|  5.81k|        audio_update_volume(mpctx);
 7866|       |
 7867|  5.81k|    if (flags & UPDATE_LAVFI_COMPLEX)
  ------------------
  |  |  439|  5.81k|#define UPDATE_LAVFI_COMPLEX    (UINT64_C(1) << 10)  // --lavfi-complex
  ------------------
  |  Branch (7867:9): [True: 5.81k, False: 0]
  ------------------
 7868|  5.81k|        update_lavfi_complex(mpctx);
 7869|       |
 7870|  5.81k|    if (flags & UPDATE_VIDEO) {
  ------------------
  |  |  444|  5.81k|#define UPDATE_VIDEO            (UINT64_C(1) << 15)  // force redraw if needed
  ------------------
  |  Branch (7870:9): [True: 5.81k, False: 0]
  ------------------
 7871|  5.81k|        if (mpctx->video_out) {
  ------------------
  |  Branch (7871:13): [True: 0, False: 5.81k]
  ------------------
 7872|      0|            vo_control(mpctx->video_out, VOCTRL_UPDATE_RENDER_OPTS, NULL);
 7873|      0|            mp_wakeup_core(mpctx);
 7874|      0|        }
 7875|  5.81k|    }
 7876|       |
 7877|  5.81k|    if (flags & UPDATE_HWDEC) {
  ------------------
  |  |  440|  5.81k|#define UPDATE_HWDEC            (UINT64_C(1) << 11)  // --hwdec
  ------------------
  |  Branch (7877:9): [True: 5.81k, False: 0]
  ------------------
 7878|  5.81k|        struct track *track = mpctx->current_track[0][STREAM_VIDEO];
 7879|  5.81k|        struct mp_decoder_wrapper *dec = track ? track->dec : NULL;
  ------------------
  |  Branch (7879:42): [True: 0, False: 5.81k]
  ------------------
 7880|  5.81k|        if (dec) {
  ------------------
  |  Branch (7880:13): [True: 0, False: 5.81k]
  ------------------
 7881|      0|            mp_decoder_wrapper_control(dec, VDCTRL_REINIT, NULL);
 7882|      0|            double last_pts = mpctx->video_pts;
 7883|      0|            if (last_pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (7883:17): [True: 0, False: 0]
  ------------------
 7884|      0|                queue_seek(mpctx, MPSEEK_ABSOLUTE, last_pts, MPSEEK_EXACT, 0);
 7885|      0|        }
 7886|  5.81k|    }
 7887|       |
 7888|  5.81k|    if (flags & UPDATE_DVB_PROG) {
  ------------------
  |  |  441|  5.81k|#define UPDATE_DVB_PROG         (UINT64_C(1) << 12)  // some --dvbin-...
  ------------------
  |  Branch (7888:9): [True: 5.81k, False: 0]
  ------------------
 7889|  5.81k|        if (!mpctx->stop_play)
  ------------------
  |  Branch (7889:13): [True: 0, False: 5.81k]
  ------------------
 7890|      0|            mpctx->stop_play = PT_CURRENT_ENTRY;
 7891|  5.81k|    }
 7892|       |
 7893|  5.81k|    if (flags & UPDATE_DEMUXER)
  ------------------
  |  |  447|  5.81k|#define UPDATE_DEMUXER          (UINT64_C(1) << 18)  // invalidate --prefetch-playlist's data
  ------------------
  |  Branch (7893:9): [True: 5.81k, False: 0]
  ------------------
 7894|  5.81k|        mpctx->demuxer_changed = true;
 7895|       |
 7896|  5.81k|    if (flags & UPDATE_AD && mpctx->ao_chain) {
  ------------------
  |  |  448|  11.6k|#define UPDATE_AD               (UINT64_C(1) << 19)  // reinit audio chain and decoder
  ------------------
  |  Branch (7896:9): [True: 5.81k, False: 0]
  |  Branch (7896:30): [True: 0, False: 5.81k]
  ------------------
 7897|      0|        uninit_audio_chain(mpctx);
 7898|      0|        reinit_audio_chain(mpctx);
 7899|      0|    }
 7900|       |
 7901|  5.81k|    if (flags & UPDATE_VD && mpctx->vo_chain) {
  ------------------
  |  |  449|  11.6k|#define UPDATE_VD               (UINT64_C(1) << 20)  // reinit video chain and decoder
  ------------------
  |  Branch (7901:9): [True: 5.81k, False: 0]
  |  Branch (7901:30): [True: 0, False: 5.81k]
  ------------------
 7902|      0|        struct track *track = mpctx->current_track[0][STREAM_VIDEO];
 7903|      0|        uninit_video_chain(mpctx);
 7904|      0|        reinit_video_chain(mpctx);
 7905|      0|        if (track)
  ------------------
  |  Branch (7905:13): [True: 0, False: 0]
  ------------------
 7906|      0|            queue_seek(mpctx, MPSEEK_RELATIVE, 0.0, MPSEEK_EXACT, 0);
 7907|      0|    }
 7908|       |
 7909|  5.81k|    if (opt_ptr == &opts->vo->android_surface_size) {
  ------------------
  |  Branch (7909:9): [True: 0, False: 5.81k]
  ------------------
 7910|      0|        if (mpctx->video_out)
  ------------------
  |  Branch (7910:13): [True: 0, False: 0]
  ------------------
 7911|      0|            vo_control(mpctx->video_out, VOCTRL_EXTERNAL_RESIZE, NULL);
 7912|      0|    }
 7913|       |
 7914|  5.81k|    if (opt_ptr == &opts->input_commands) {
  ------------------
  |  Branch (7914:9): [True: 0, False: 5.81k]
  ------------------
 7915|      0|        mpctx->command_ctx->command_opts_processed = false;
 7916|      0|        run_command_opts(mpctx);
 7917|      0|    }
 7918|       |
 7919|  5.81k|    if (opt_ptr == &opts->playback_speed || opt_ptr == &opts->playback_pitch) {
  ------------------
  |  Branch (7919:9): [True: 0, False: 5.81k]
  |  Branch (7919:45): [True: 0, False: 5.81k]
  ------------------
 7920|      0|        update_playback_speed(mpctx);
 7921|      0|        mp_wakeup_core(mpctx);
 7922|      0|    }
 7923|       |
 7924|  5.81k|    if (opt_ptr == &opts->play_dir) {
  ------------------
  |  Branch (7924:9): [True: 0, False: 5.81k]
  ------------------
 7925|      0|        if (mpctx->play_dir != opts->play_dir) {
  ------------------
  |  Branch (7925:13): [True: 0, False: 0]
  ------------------
 7926|       |            // The option must be set before we seek if we're at EOF.
 7927|      0|            if (mpctx->stop_play == AT_END_OF_FILE)
  ------------------
  |  Branch (7927:17): [True: 0, False: 0]
  ------------------
 7928|      0|                mpctx->play_dir = opts->play_dir;
 7929|      0|            queue_seek(mpctx, MPSEEK_ABSOLUTE, get_current_time(mpctx),
 7930|      0|                       MPSEEK_EXACT, 0);
 7931|      0|        }
 7932|      0|    }
 7933|       |
 7934|  5.81k|    if (opt_ptr == &opts->edition_id) {
  ------------------
  |  Branch (7934:9): [True: 0, False: 5.81k]
  ------------------
 7935|      0|        struct demuxer *demuxer = mpctx->demuxer;
 7936|      0|        if (mpctx->playback_initialized && demuxer && demuxer->num_editions > 0) {
  ------------------
  |  Branch (7936:13): [True: 0, False: 0]
  |  Branch (7936:44): [True: 0, False: 0]
  |  Branch (7936:55): [True: 0, False: 0]
  ------------------
 7937|      0|            if (opts->edition_id != demuxer->edition) {
  ------------------
  |  Branch (7937:17): [True: 0, False: 0]
  ------------------
 7938|      0|                if (!mpctx->stop_play)
  ------------------
  |  Branch (7938:21): [True: 0, False: 0]
  ------------------
 7939|      0|                    mpctx->stop_play = PT_CURRENT_ENTRY;
 7940|      0|                mp_wakeup_core(mpctx);
 7941|      0|            }
 7942|      0|        }
 7943|      0|    }
 7944|       |
 7945|  5.81k|    if (opt_ptr == &opts->pause)
  ------------------
  |  Branch (7945:9): [True: 0, False: 5.81k]
  ------------------
 7946|      0|        set_pause_state(mpctx, opts->pause);
 7947|       |
 7948|  5.81k|    if (opt_ptr == &opts->audio_delay) {
  ------------------
  |  Branch (7948:9): [True: 0, False: 5.81k]
  ------------------
 7949|      0|        if (mpctx->ao_chain) {
  ------------------
  |  Branch (7949:13): [True: 0, False: 0]
  ------------------
 7950|      0|            mpctx->delay += mpctx->opts->audio_delay - mpctx->ao_chain->delay;
 7951|      0|            mpctx->ao_chain->delay = mpctx->opts->audio_delay;
 7952|      0|        }
 7953|      0|        mp_wakeup_core(mpctx);
 7954|      0|    }
 7955|       |
 7956|  5.81k|    if (opt_ptr == &opts->vo->window_scale)
  ------------------
  |  Branch (7956:9): [True: 0, False: 5.81k]
  ------------------
 7957|      0|        update_window_scale(mpctx);
 7958|       |
 7959|  5.81k|    if (opt_ptr == &opts->vo->hidpi_window_scale)
  ------------------
  |  Branch (7959:9): [True: 0, False: 5.81k]
  ------------------
 7960|      0|        update_hidpi_window_scale(mpctx, opts->vo->hidpi_window_scale);
 7961|       |
 7962|  5.81k|    if (opt_ptr == &opts->cursor_autohide_delay)
  ------------------
  |  Branch (7962:9): [True: 0, False: 5.81k]
  ------------------
 7963|      0|        mpctx->mouse_timer = 0;
 7964|       |
 7965|  5.81k|    if (opt_ptr == &opts->loop_file) {
  ------------------
  |  Branch (7965:9): [True: 0, False: 5.81k]
  ------------------
 7966|      0|        mpctx->remaining_file_loops = opts->loop_file;
 7967|      0|        mp_notify_property(mpctx, "remaining-file-loops");
 7968|      0|    }
 7969|       |
 7970|  5.81k|    if (opt_ptr == &opts->ab_loop[0] || opt_ptr == &opts->ab_loop[1] ||
  ------------------
  |  Branch (7970:9): [True: 0, False: 5.81k]
  |  Branch (7970:41): [True: 0, False: 5.81k]
  ------------------
 7971|  5.81k|        opt_ptr == &opts->ab_loop_count) {
  ------------------
  |  Branch (7971:9): [True: 0, False: 5.81k]
  ------------------
 7972|      0|        mpctx->remaining_ab_loops = opts->ab_loop_count;
 7973|      0|        mp_notify_property(mpctx, "remaining-ab-loops");
 7974|      0|    }
 7975|       |
 7976|  5.81k|    if (opt_ptr == &opts->ab_loop[0] || opt_ptr == &opts->ab_loop[1]) {
  ------------------
  |  Branch (7976:9): [True: 0, False: 5.81k]
  |  Branch (7976:41): [True: 0, False: 5.81k]
  ------------------
 7977|      0|        update_ab_loop_clip(mpctx);
 7978|       |        // Update if visible
 7979|      0|        set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
 7980|      0|        mp_wakeup_core(mpctx);
 7981|      0|    }
 7982|       |
 7983|  5.81k|    if (opt_ptr == &opts->vf_settings)
  ------------------
  |  Branch (7983:9): [True: 0, False: 5.81k]
  ------------------
 7984|      0|        set_filters(mpctx, STREAM_VIDEO, opts->vf_settings);
 7985|       |
 7986|  5.81k|    if (opt_ptr == &opts->af_settings)
  ------------------
  |  Branch (7986:9): [True: 0, False: 5.81k]
  ------------------
 7987|      0|        set_filters(mpctx, STREAM_AUDIO, opts->af_settings);
 7988|       |
 7989|  23.2k|    for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
  ------------------
  |  Branch (7989:24): [True: 17.4k, False: 5.81k]
  ------------------
 7990|  40.6k|        for (int order = 0; order < num_ptracks[type]; order++) {
  ------------------
  |  Branch (7990:29): [True: 23.2k, False: 17.4k]
  ------------------
 7991|  23.2k|            if (opt_ptr == &opts->stream_id[order][type])
  ------------------
  |  Branch (7991:17): [True: 0, False: 23.2k]
  ------------------
 7992|      0|                update_track_switch(mpctx, order, type);
 7993|  23.2k|        }
 7994|  17.4k|    }
 7995|       |
 7996|  5.81k|    if (opt_ptr == &opts->vo->fullscreen && !opts->vo->fullscreen)
  ------------------
  |  Branch (7996:9): [True: 0, False: 5.81k]
  |  Branch (7996:45): [True: 0, False: 0]
  ------------------
 7997|      0|        mpctx->mouse_event_ts--; // Show mouse cursor
 7998|       |
 7999|  5.81k|    if (opt_ptr == &opts->vo->taskbar_progress)
  ------------------
  |  Branch (7999:9): [True: 0, False: 5.81k]
  ------------------
 8000|      0|        update_vo_playback_state(mpctx);
 8001|       |
 8002|  5.81k|    if (opt_ptr == &opts->image_display_duration && mpctx->vo_chain
  ------------------
  |  Branch (8002:9): [True: 0, False: 5.81k]
  |  Branch (8002:53): [True: 0, False: 0]
  ------------------
 8003|  5.81k|        && mpctx->vo_chain->is_sparse && !mpctx->ao_chain
  ------------------
  |  Branch (8003:12): [True: 0, False: 0]
  |  Branch (8003:42): [True: 0, False: 0]
  ------------------
 8004|  5.81k|        && mpctx->video_status == STATUS_DRAINING)
  ------------------
  |  Branch (8004:12): [True: 0, False: 0]
  ------------------
 8005|      0|        mpctx->time_frame = opts->image_display_duration;
 8006|  5.81k|}
mp_notify_property:
 8009|  15.6k|{
 8010|  15.6k|    mp_client_property_change(mpctx, property);
 8011|  15.6k|}
command.c:run_next_hook_handler:
  236|   298k|{
  237|   298k|    struct command_ctx *cmd = mpctx->command_ctx;
  238|       |
  239|   298k|    for (int n = start; n < cmd->num_hooks; n++) {
  ------------------
  |  Branch (239:25): [True: 0, False: 298k]
  ------------------
  240|      0|        struct hook_handler *h = cmd->hooks[n];
  241|      0|        if (strcmp(h->type, type) == 0) {
  ------------------
  |  Branch (241:13): [True: 0, False: 0]
  ------------------
  242|      0|            int ret = invoke_hook_handler(mpctx, h);
  243|       |            // Repeat until the hook is successfully started or none are left.
  244|      0|            if (ret < 0) {
  ------------------
  |  Branch (244:17): [True: 0, False: 0]
  ------------------
  245|      0|                --n;
  246|      0|                continue;
  247|      0|            }
  248|      0|            return ret;
  249|      0|        }
  250|      0|    }
  251|       |
  252|   298k|    mp_wakeup_core(mpctx); // finished hook
  253|   298k|    return 0;
  254|   298k|}
command.c:match_property:
 4541|   566k|{
 4542|   566k|    if (strcmp(a, "*") == 0)
  ------------------
  |  Branch (4542:9): [True: 0, False: 566k]
  ------------------
 4543|      0|        return true;
 4544|       |    // Give options and properties the same ID each, so change notifications
 4545|       |    // work both way.
 4546|   566k|    if (strncmp(a, "options/", 8) == 0)
  ------------------
  |  Branch (4546:9): [True: 0, False: 566k]
  ------------------
 4547|      0|        a += 8;
 4548|   566k|    if (strncmp(b, "options/", 8) == 0)
  ------------------
  |  Branch (4548:9): [True: 0, False: 566k]
  ------------------
 4549|      0|        b += 8;
 4550|   566k|    int len_a = prefix_len(a);
 4551|   566k|    int len_b = prefix_len(b);
 4552|   566k|    return strncmp(a, b, MPMIN(len_a, len_b)) == 0;
  ------------------
  |  |   44|   566k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 135k, False: 430k]
  |  |  ------------------
  ------------------
 4553|   566k|}
command.c:prefix_len:
 4535|  1.13M|{
 4536|  1.13M|    const char *end = strchr(p, '/');
 4537|  1.13M|    return end ? end - p : strlen(p) + 1;
  ------------------
  |  Branch (4537:12): [True: 0, False: 1.13M]
  ------------------
 4538|  1.13M|}
command.c:cache_dump_poll:
 6894|   234k|{
 6895|   234k|    struct command_ctx *ctx = mpctx->command_ctx;
 6896|   234k|    struct mp_cmd_ctx *cmd = ctx->cache_dump_cmd;
 6897|       |
 6898|   234k|    if (!cmd)
  ------------------
  |  Branch (6898:9): [True: 234k, False: 0]
  ------------------
 6899|   234k|        return;
 6900|       |
 6901|       |    // Can't close demuxer without stopping dumping.
 6902|      0|    mp_assert(mpctx->demuxer);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 6903|       |
 6904|      0|    if (mp_cancel_test(cmd->abort->cancel)) {
  ------------------
  |  Branch (6904:9): [True: 0, False: 0]
  ------------------
 6905|       |        // Synchronous abort. In particular, the dump command shall not report
 6906|       |        // completion to the user before the dump target file was closed.
 6907|      0|        demux_cache_dump_set(mpctx->demuxer, 0, 0, NULL);
 6908|      0|        mp_assert(demux_cache_dump_get_status(mpctx->demuxer) <= 0);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 6909|      0|    }
 6910|       |
 6911|      0|    int status = demux_cache_dump_get_status(mpctx->demuxer);
 6912|      0|    if (status <= 0) {
  ------------------
  |  Branch (6912:9): [True: 0, False: 0]
  ------------------
 6913|      0|        if (status < 0) {
  ------------------
  |  Branch (6913:13): [True: 0, False: 0]
  ------------------
 6914|      0|            mp_cmd_msg(cmd, MSGL_ERR, "Cache dumping stopped due to error.");
 6915|      0|            cmd->success = false;
 6916|      0|        } else {
 6917|      0|            mp_cmd_msg(cmd, MSGL_INFO, "Cache dumping successfully ended.");
 6918|      0|            cmd->success = true;
 6919|      0|        }
 6920|      0|        ctx->cache_dump_cmd = NULL;
 6921|      0|        mp_cmd_ctx_complete(cmd);
 6922|      0|    }
 6923|      0|}
command.c:cmd_quit:
 5781|  5.81k|{
 5782|  5.81k|    struct mp_cmd_ctx *cmd = p;
 5783|  5.81k|    struct MPContext *mpctx = cmd->mpctx;
 5784|  5.81k|    bool write_watch_later = *(bool *)cmd->priv;
 5785|  5.81k|    if (write_watch_later || mpctx->opts->position_save_on_quit)
  ------------------
  |  Branch (5785:9): [True: 0, False: 5.81k]
  |  Branch (5785:30): [True: 0, False: 5.81k]
  ------------------
 5786|      0|        mp_write_watch_later_conf(mpctx);
 5787|  5.81k|    mpctx->stop_play = PT_QUIT;
 5788|  5.81k|    mpctx->quit_custom_rc = cmd->args[0].v.i;
 5789|  5.81k|    mpctx->has_quit_custom_rc = true;
 5790|  5.81k|    mp_wakeup_core(mpctx);
 5791|  5.81k|}
command.c:cmd_loadfile:
 6023|  5.81k|{
 6024|  5.81k|    struct mp_cmd_ctx *cmd = p;
 6025|  5.81k|    struct MPContext *mpctx = cmd->mpctx;
 6026|  5.81k|    char *filename = cmd->args[0].v.s;
 6027|  5.81k|    int action_flag = cmd->args[1].v.i;
 6028|  5.81k|    int insert_at_idx = cmd->args[2].v.i;
 6029|       |
 6030|  5.81k|    struct load_action action = get_load_action(mpctx, action_flag);
 6031|       |
 6032|  5.81k|    if (action.type == LOAD_TYPE_REPLACE)
  ------------------
  |  Branch (6032:9): [True: 5.81k, False: 0]
  ------------------
 6033|  5.81k|        playlist_clear(mpctx->playlist);
 6034|       |
 6035|  5.81k|    char *path = mp_get_user_path(NULL, mpctx->global, filename);
 6036|  5.81k|    struct playlist_entry *entry = playlist_entry_new(path);
 6037|  5.81k|    talloc_free(path);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
 6038|  5.81k|    if (cmd->args[3].v.str_list) {
  ------------------
  |  Branch (6038:9): [True: 0, False: 5.81k]
  ------------------
 6039|      0|        char **pairs = cmd->args[3].v.str_list;
 6040|      0|        for (int i = 0; pairs[i] && pairs[i + 1]; i += 2)
  ------------------
  |  Branch (6040:25): [True: 0, False: 0]
  |  Branch (6040:37): [True: 0, False: 0]
  ------------------
 6041|      0|            playlist_entry_add_param(entry, bstr0(pairs[i]), bstr0(pairs[i + 1]));
 6042|      0|    }
 6043|       |
 6044|  5.81k|    struct playlist_entry *at = get_insert_entry(mpctx, &action, insert_at_idx);
 6045|  5.81k|    playlist_insert_at(mpctx->playlist, entry, at);
 6046|       |
 6047|  5.81k|    struct mpv_node *res = &cmd->result;
 6048|  5.81k|    node_init(res, MPV_FORMAT_NODE_MAP, NULL);
 6049|  5.81k|    node_map_add_int64(res, "playlist_entry_id", entry->id);
 6050|       |
 6051|  5.81k|    if (action.type == LOAD_TYPE_REPLACE || (action.play && !mpctx->playlist->current)) {
  ------------------
  |  Branch (6051:9): [True: 5.81k, False: 0]
  |  Branch (6051:46): [True: 0, False: 0]
  |  Branch (6051:61): [True: 0, False: 0]
  ------------------
 6052|  5.81k|        if (mpctx->opts->position_save_on_quit) // requested in issue #1148
  ------------------
  |  Branch (6052:13): [True: 0, False: 5.81k]
  ------------------
 6053|      0|            mp_write_watch_later_conf(mpctx);
 6054|  5.81k|        mp_set_playlist_entry(mpctx, entry);
 6055|  5.81k|    }
 6056|  5.81k|    mp_notify(mpctx, MP_EVENT_CHANGE_PLAYLIST, NULL);
 6057|  5.81k|    mp_wakeup_core(mpctx);
 6058|  5.81k|}
command.c:get_load_action:
 5986|  5.81k|{
 5987|  5.81k|    switch (action_flag) {
 5988|  5.81k|    case 0: // replace
  ------------------
  |  Branch (5988:5): [True: 5.81k, False: 0]
  ------------------
 5989|  5.81k|        return (struct load_action){LOAD_TYPE_REPLACE, .play = true};
 5990|      0|    case 1: // append
  ------------------
  |  Branch (5990:5): [True: 0, False: 5.81k]
  ------------------
 5991|      0|        return (struct load_action){LOAD_TYPE_APPEND, .play = false};
 5992|      0|    case 2: // append-play
  ------------------
  |  Branch (5992:5): [True: 0, False: 5.81k]
  ------------------
 5993|      0|        return (struct load_action){LOAD_TYPE_APPEND, .play = true};
 5994|      0|    case 3: // insert-next
  ------------------
  |  Branch (5994:5): [True: 0, False: 5.81k]
  ------------------
 5995|      0|        return (struct load_action){LOAD_TYPE_INSERT_NEXT, .play = false};
 5996|      0|    case 4: // insert-next-play
  ------------------
  |  Branch (5996:5): [True: 0, False: 5.81k]
  ------------------
 5997|      0|        return (struct load_action){LOAD_TYPE_INSERT_NEXT, .play = true};
 5998|      0|    case 5: // insert-at
  ------------------
  |  Branch (5998:5): [True: 0, False: 5.81k]
  ------------------
 5999|      0|        return (struct load_action){LOAD_TYPE_INSERT_AT, .play = false};
 6000|      0|    case 6: // insert-at-play
  ------------------
  |  Branch (6000:5): [True: 0, False: 5.81k]
  ------------------
 6001|      0|        return (struct load_action){LOAD_TYPE_INSERT_AT, .play = true};
 6002|      0|    default: // default: replace
  ------------------
  |  Branch (6002:5): [True: 0, False: 5.81k]
  ------------------
 6003|      0|        return (struct load_action){LOAD_TYPE_REPLACE, .play = true};
 6004|  5.81k|    }
 6005|  5.81k|}
command.c:get_insert_entry:
 6009|  5.81k|{
 6010|  5.81k|    switch (action->type) {
 6011|      0|    case LOAD_TYPE_INSERT_NEXT:
  ------------------
  |  Branch (6011:5): [True: 0, False: 5.81k]
  ------------------
 6012|      0|        return playlist_get_next(mpctx->playlist, +1);
 6013|      0|    case LOAD_TYPE_INSERT_AT:
  ------------------
  |  Branch (6013:5): [True: 0, False: 5.81k]
  ------------------
 6014|      0|        return playlist_entry_from_index(mpctx->playlist, insert_at_idx);
 6015|  5.81k|    case LOAD_TYPE_REPLACE:
  ------------------
  |  Branch (6015:5): [True: 5.81k, False: 0]
  ------------------
 6016|  5.81k|    case LOAD_TYPE_APPEND:
  ------------------
  |  Branch (6016:5): [True: 0, False: 5.81k]
  ------------------
 6017|  5.81k|    default:
  ------------------
  |  Branch (6017:5): [True: 0, False: 5.81k]
  ------------------
 6018|  5.81k|        return NULL;
 6019|  5.81k|    }
 6020|  5.81k|}
command.c:overlay_uninit:
 5114|  5.81k|{
 5115|  5.81k|    struct command_ctx *cmd = mpctx->command_ctx;
 5116|  5.81k|    if (!mpctx->osd)
  ------------------
  |  Branch (5116:9): [True: 0, False: 5.81k]
  ------------------
 5117|      0|        return;
 5118|  5.81k|    for (int id = 0; id < cmd->num_overlays; id++)
  ------------------
  |  Branch (5118:22): [True: 0, False: 5.81k]
  ------------------
 5119|      0|        replace_overlay(mpctx, id, &(struct overlay){0});
 5120|  5.81k|    osd_set_external2(mpctx->osd, NULL);
 5121|  17.4k|    for (int n = 0; n < 2; n++)
  ------------------
  |  Branch (5121:21): [True: 11.6k, False: 5.81k]
  ------------------
 5122|  11.6k|        mp_image_unrefp(&cmd->overlay_osd[n].packed);
 5123|  5.81k|}
command.c:mp_property_filename:
  521|   540k|{
  522|   540k|    MPContext *mpctx = ctx;
  523|   540k|    if (!mpctx->filename)
  ------------------
  |  Branch (523:9): [True: 0, False: 540k]
  ------------------
  524|      0|        return M_PROPERTY_UNAVAILABLE;
  525|   540k|    char *filename = talloc_strdup(NULL, mpctx->filename);
  ------------------
  |  |   50|   540k|#define talloc_strdup                   ta_xstrdup
  ------------------
  526|   540k|    if (mp_is_url(bstr0(filename)))
  ------------------
  |  Branch (526:9): [True: 540k, False: 0]
  ------------------
  527|   540k|        mp_url_unescape_inplace(filename);
  528|   540k|    char *f = (char *)mp_basename(filename);
  529|   540k|    if (!f[0])
  ------------------
  |  Branch (529:9): [True: 189, False: 540k]
  ------------------
  530|    189|        f = filename;
  531|   540k|    if (action == M_PROPERTY_KEY_ACTION) {
  ------------------
  |  Branch (531:9): [True: 0, False: 540k]
  ------------------
  532|      0|        struct m_property_action_arg *ka = arg;
  533|      0|        if (strcmp(ka->key, "no-ext") == 0) {
  ------------------
  |  Branch (533:13): [True: 0, False: 0]
  ------------------
  534|      0|            action = ka->action;
  535|      0|            arg = ka->arg;
  536|      0|            bstr root;
  537|      0|            if (mp_splitext(f, &root))
  ------------------
  |  Branch (537:17): [True: 0, False: 0]
  ------------------
  538|      0|                f = bstrto0(filename, root);
  539|      0|        }
  540|      0|    }
  541|   540k|    int r = m_property_strdup_ro(action, arg, f);
  542|   540k|    talloc_free(filename);
  ------------------
  |  |   47|   540k|#define talloc_free                     ta_free
  ------------------
  543|   540k|    return r;
  544|   540k|}
command.c:mp_property_media_title:
  588|   541k|{
  589|   541k|    MPContext *mpctx = ctx;
  590|   541k|    const char *name = mp_find_non_filename_media_title(mpctx);
  591|   541k|    if (name && name[0])
  ------------------
  |  Branch (591:9): [True: 945, False: 540k]
  |  Branch (591:17): [True: 945, False: 0]
  ------------------
  592|    945|        return m_property_strdup_ro(action, arg, name);
  593|   540k|    return mp_property_filename(ctx, prop, action, arg);
  594|   541k|}
command.c:str_compare:
 7558|  38.0M|{
 7559|  38.0M|    return strcmp(*(const char **)a, *(const char **)b);
 7560|  38.0M|}
command.c:command_event:
 7633|   458k|{
 7634|   458k|    struct command_ctx *ctx = mpctx->command_ctx;
 7635|       |
 7636|   458k|    if (event == MPV_EVENT_START_FILE) {
  ------------------
  |  Branch (7636:9): [True: 94.7k, False: 363k]
  ------------------
 7637|  94.7k|        ctx->last_seek_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  94.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 7638|  94.7k|        ctx->marked_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  94.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 7639|  94.7k|        ctx->marked_permanent = false;
 7640|  94.7k|    }
 7641|       |
 7642|   458k|    if (event == MPV_EVENT_PLAYBACK_RESTART) {
  ------------------
  |  Branch (7642:9): [True: 2.96k, False: 455k]
  ------------------
 7643|  2.96k|        ctx->last_seek_time = mp_time_sec();
 7644|  2.96k|        run_command_opts(mpctx);
 7645|  2.96k|    }
 7646|       |
 7647|   458k|    if (event == MPV_EVENT_VIDEO_RECONFIG && ctx->hwdec_osd_mode) {
  ------------------
  |  Branch (7647:9): [True: 24.2k, False: 434k]
  |  Branch (7647:46): [True: 0, False: 24.2k]
  ------------------
 7648|      0|        show_property_osd(mpctx, "hwdec", ctx->hwdec_osd_mode);
 7649|      0|        ctx->hwdec_osd_mode = 0;
 7650|      0|    }
 7651|       |
 7652|   458k|    if (event == MPV_EVENT_IDLE)
  ------------------
  |  Branch (7652:9): [True: 6.49k, False: 451k]
  ------------------
 7653|  6.49k|        run_command_opts(mpctx);
 7654|       |
 7655|   458k|    if (event == MPV_EVENT_END_FILE)
  ------------------
  |  Branch (7655:9): [True: 94.7k, False: 363k]
  ------------------
 7656|  94.7k|        mp_msg_flush_status_line(mpctx->log, false);
 7657|       |
 7658|   458k|    if (event == MPV_EVENT_END_FILE || event == MPV_EVENT_FILE_LOADED) {
  ------------------
  |  Branch (7658:9): [True: 94.7k, False: 363k]
  |  Branch (7658:40): [True: 2.96k, False: 360k]
  ------------------
 7659|       |        // Update chapters - does nothing if something else is visible.
 7660|  97.7k|        set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
 7661|  97.7k|    }
 7662|   458k|    if (event == MP_EVENT_WIN_STATE2)
  ------------------
  |  Branch (7662:9): [True: 0, False: 458k]
  ------------------
 7663|      0|        ctx->cached_window_scale = 0;
 7664|       |
 7665|   458k|    if (event == MP_EVENT_METADATA_UPDATE) {
  ------------------
  |  Branch (7665:9): [True: 4.53k, False: 453k]
  ------------------
 7666|  4.53k|        struct playlist_entry *const pe = mpctx->playing;
 7667|  4.53k|        if (pe && !pe->title) {
  ------------------
  |  Branch (7667:13): [True: 4.53k, False: 0]
  |  Branch (7667:19): [True: 4.53k, False: 0]
  ------------------
 7668|  4.53k|            const char *const name = mp_find_non_filename_media_title(mpctx);
 7669|  4.53k|            if (name && name[0]) {
  ------------------
  |  Branch (7669:17): [True: 187, False: 4.35k]
  |  Branch (7669:25): [True: 187, False: 0]
  ------------------
 7670|    187|                pe->title = talloc_strdup(pe, name);
  ------------------
  |  |   50|    187|#define talloc_strdup                   ta_xstrdup
  ------------------
 7671|    187|                mp_notify_property(mpctx, "playlist");
 7672|    187|            }
 7673|  4.53k|        }
 7674|  4.53k|    }
 7675|   458k|}
command.c:update_priority:
 7719|  5.81k|{
 7720|       |#if HAVE_WIN32_DESKTOP
 7721|       |    struct MPOpts *opts = mpctx->opts;
 7722|       |    if (opts->w32_priority > 0)
 7723|       |        SetPriorityClass(GetCurrentProcess(), opts->w32_priority);
 7724|       |#endif
 7725|  5.81k|}

mp_parse_cfgfiles:
   67|  5.81k|{
   68|  5.81k|    struct MPOpts *opts = mpctx->opts;
   69|       |
   70|  5.81k|    mp_mk_user_dir(mpctx->global, "home", "");
   71|       |
   72|  5.81k|    char *p1 = mp_get_user_path(NULL, mpctx->global, "~~home/");
   73|  5.81k|    char *p2 = mp_get_user_path(NULL, mpctx->global, "~~old_home/");
   74|  5.81k|    if (strcmp(p1, p2) != 0 && mp_path_exists(p2)) {
  ------------------
  |  Branch (74:9): [True: 0, False: 5.81k]
  |  Branch (74:32): [True: 0, False: 0]
  ------------------
   75|      0|        MP_WARN(mpctx, "Warning, two config dirs found:\n   %s (main)\n"
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   76|      0|                "   %s (bogus)\nYou should merge or delete the second one.\n",
   77|      0|                p1, p2);
   78|      0|    }
   79|  5.81k|    talloc_free(p1);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
   80|  5.81k|    talloc_free(p2);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
   81|       |
   82|  5.81k|    char *section = NULL;
   83|  5.81k|    bool encoding = opts->encode_opts->file && opts->encode_opts->file[0];
  ------------------
  |  Branch (83:21): [True: 0, False: 5.81k]
  |  Branch (83:48): [True: 0, False: 0]
  ------------------
   84|       |    // In encoding mode, we don't want to apply normal config options.
   85|       |    // So we "divert" normal options into a separate section, and the diverted
   86|       |    // section is never used - unless maybe it's explicitly referenced from an
   87|       |    // encoding profile.
   88|  5.81k|    if (encoding)
  ------------------
  |  Branch (88:9): [True: 0, False: 5.81k]
  ------------------
   89|      0|        section = "playback-default";
   90|       |
   91|  5.81k|    load_all_cfgfiles(mpctx, NULL, "encoding-profiles.conf");
   92|       |
   93|  5.81k|    load_all_cfgfiles(mpctx, section, "mpv.conf|config");
   94|       |
   95|  5.81k|    if (encoding) {
  ------------------
  |  Branch (95:9): [True: 0, False: 5.81k]
  ------------------
   96|      0|        m_config_set_profile(mpctx->mconfig, SECT_ENCODE, 0);
  ------------------
  |  |   64|      0|#define SECT_ENCODE "encoding"
  ------------------
   97|      0|        mp_input_enable_section(mpctx->input, "encode", MP_INPUT_EXCLUSIVE);
   98|      0|    }
   99|  5.81k|}
mp_load_auto_profiles:
  163|  7.46k|{
  164|  7.46k|    mp_auto_load_profile(mpctx, "protocol",
  165|  7.46k|                         mp_split_proto(bstr0(mpctx->filename), NULL));
  166|  7.46k|    mp_auto_load_profile(mpctx, "extension",
  167|  7.46k|                         bstr0(mp_splitext(mpctx->filename, NULL)));
  168|       |
  169|  7.46k|    mp_load_per_file_config(mpctx);
  170|  7.46k|}
mp_get_playback_resume_dir:
  201|   101k|{
  202|   101k|    char *wl_dir = mpctx->opts->watch_later_dir;
  203|   101k|    if (wl_dir && wl_dir[0]) {
  ------------------
  |  Branch (203:9): [True: 0, False: 101k]
  |  Branch (203:19): [True: 0, False: 0]
  ------------------
  204|      0|        wl_dir = mp_get_user_path(mpctx, mpctx->global, wl_dir);
  205|   101k|    } else {
  206|   101k|        wl_dir = mp_find_user_file(mpctx, mpctx->global, "state", MP_WATCH_LATER_CONF);
  ------------------
  |  |  172|   101k|#define MP_WATCH_LATER_CONF "watch_later"
  ------------------
  207|   101k|    }
  208|   101k|    return wl_dir;
  209|   101k|}
mp_load_playback_resume:
  433|  7.46k|{
  434|  7.46k|    bool resume = false;
  435|  7.46k|    if (!mpctx->opts->position_resume)
  ------------------
  |  Branch (435:9): [True: 0, False: 7.46k]
  ------------------
  436|      0|        return resume;
  437|  7.46k|    char *fname = mp_get_playback_resume_config_filename(mpctx, file);
  438|  7.46k|    if (fname && mp_path_exists(fname)) {
  ------------------
  |  Branch (438:9): [True: 0, False: 7.46k]
  |  Branch (438:18): [True: 0, False: 0]
  ------------------
  439|      0|        if (mpctx->opts->position_check_mtime &&
  ------------------
  |  Branch (439:13): [True: 0, False: 0]
  ------------------
  440|      0|            !mp_is_url(bstr0(file)) && !check_mtime(file, fname))
  ------------------
  |  Branch (440:13): [True: 0, False: 0]
  |  Branch (440:40): [True: 0, False: 0]
  ------------------
  441|      0|        {
  442|      0|            talloc_free(fname);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  443|      0|            return resume;
  444|      0|        }
  445|       |
  446|       |        // Never apply the saved start position to following files
  447|      0|        m_config_backup_opt(mpctx->mconfig, "start");
  448|      0|        MP_INFO(mpctx, "Resuming playback. This behavior can "
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  449|      0|               "be disabled with --no-resume-playback.\n");
  450|      0|        try_load_config(mpctx, fname, M_SETOPT_PRESERVE_CMDLINE, MSGL_V);
  451|      0|        resume = true;
  452|      0|    }
  453|  7.46k|    talloc_free(fname);
  ------------------
  |  |   47|  7.46k|#define talloc_free                     ta_free
  ------------------
  454|  7.46k|    return resume;
  455|  7.46k|}
mp_check_playlist_resume:
  464|  6.20k|{
  465|  6.20k|    if (!mpctx->opts->position_resume)
  ------------------
  |  Branch (465:9): [True: 0, False: 6.20k]
  ------------------
  466|      0|        return NULL;
  467|   100k|    for (int n = 0; n < playlist->num_entries; n++) {
  ------------------
  |  Branch (467:21): [True: 94.0k, False: 6.20k]
  ------------------
  468|  94.0k|        struct playlist_entry *e = playlist->entries[n];
  469|  94.0k|        char *conf = mp_get_playback_resume_config_filename(mpctx, e->filename);
  470|  94.0k|        bool exists = conf && mp_path_exists(conf);
  ------------------
  |  Branch (470:23): [True: 0, False: 94.0k]
  |  Branch (470:31): [True: 0, False: 0]
  ------------------
  471|  94.0k|        talloc_free(conf);
  ------------------
  |  |   47|  94.0k|#define talloc_free                     ta_free
  ------------------
  472|  94.0k|        if (exists)
  ------------------
  |  Branch (472:13): [True: 0, False: 94.0k]
  ------------------
  473|      0|            return e;
  474|  94.0k|    }
  475|  6.20k|    return NULL;
  476|  6.20k|}
configfiles.c:load_all_cfgfiles:
   56|  11.6k|{
   57|  11.6k|    char **cf = mp_find_all_config_files(NULL, mpctx->global, filename);
   58|  11.6k|    for (int i = 0; cf && cf[i]; i++)
  ------------------
  |  Branch (58:21): [True: 11.6k, False: 0]
  |  Branch (58:27): [True: 0, False: 11.6k]
  ------------------
   59|      0|        m_config_parse_config_file(mpctx->mconfig, mpctx->global, cf[i], section, 0);
   60|  11.6k|    talloc_free(cf);
  ------------------
  |  |   47|  11.6k|#define talloc_free                     ta_free
  ------------------
   61|  11.6k|}
configfiles.c:mp_auto_load_profile:
  149|  14.9k|{
  150|  14.9k|    if (!item.len)
  ------------------
  |  Branch (150:9): [True: 6.45k, False: 8.48k]
  ------------------
  151|  6.45k|        return;
  152|       |
  153|  8.48k|    char t[512];
  154|  8.48k|    snprintf(t, sizeof(t), "%s.%.*s", category, BSTR_P(item));
  ------------------
  |  |  283|  8.48k|#define BSTR_P(bstr) (int)((bstr).len), ((bstr).start ? (char*)(bstr).start : "")
  |  |  ------------------
  |  |  |  Branch (283:42): [True: 8.48k, False: 0]
  |  |  ------------------
  ------------------
  155|  8.48k|    m_profile_t *p = m_config_get_profile0(mpctx->mconfig, t);
  156|  8.48k|    if (p) {
  ------------------
  |  Branch (156:9): [True: 0, False: 8.48k]
  ------------------
  157|      0|        MP_INFO(mpctx, "Auto-loading profile '%s'\n", t);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  158|      0|        m_config_set_profile(mpctx->mconfig, t, FILE_LOCAL_FLAGS);
  ------------------
  |  |  113|      0|#define FILE_LOCAL_FLAGS (M_SETOPT_BACKUP | M_SETOPT_PRESERVE_CMDLINE)
  ------------------
  159|      0|    }
  160|  8.48k|}
configfiles.c:mp_load_per_file_config:
  116|  7.46k|{
  117|  7.46k|    struct MPOpts *opts = mpctx->opts;
  118|  7.46k|    char *confpath;
  119|  7.46k|    char cfg[512];
  120|  7.46k|    const char *file = mpctx->filename;
  121|       |
  122|  7.46k|    if (opts->use_filedir_conf) {
  ------------------
  |  Branch (122:9): [True: 0, False: 7.46k]
  ------------------
  123|      0|        if (snprintf(cfg, sizeof(cfg), "%s.conf", file) >= sizeof(cfg)) {
  ------------------
  |  Branch (123:13): [True: 0, False: 0]
  ------------------
  124|      0|            MP_VERBOSE(mpctx, "Filename is too long, can not load file or "
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  125|      0|                              "directory specific config files\n");
  126|      0|            return;
  127|      0|        }
  128|       |
  129|      0|        char *name = mp_basename(cfg);
  130|       |
  131|      0|        bstr dir = mp_dirname(cfg);
  132|      0|        char *dircfg = mp_path_join_bstr(NULL, dir, bstr0("mpv.conf"));
  133|      0|        try_load_config(mpctx, dircfg, FILE_LOCAL_FLAGS, MSGL_INFO);
  ------------------
  |  |  113|      0|#define FILE_LOCAL_FLAGS (M_SETOPT_BACKUP | M_SETOPT_PRESERVE_CMDLINE)
  ------------------
  134|      0|        talloc_free(dircfg);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  135|       |
  136|      0|        if (try_load_config(mpctx, cfg, FILE_LOCAL_FLAGS, MSGL_INFO))
  ------------------
  |  |  113|      0|#define FILE_LOCAL_FLAGS (M_SETOPT_BACKUP | M_SETOPT_PRESERVE_CMDLINE)
  ------------------
  |  Branch (136:13): [True: 0, False: 0]
  ------------------
  137|      0|            return;
  138|       |
  139|      0|        if ((confpath = mp_find_config_file(NULL, mpctx->global, name))) {
  ------------------
  |  Branch (139:13): [True: 0, False: 0]
  ------------------
  140|      0|            try_load_config(mpctx, confpath, FILE_LOCAL_FLAGS, MSGL_INFO);
  ------------------
  |  |  113|      0|#define FILE_LOCAL_FLAGS (M_SETOPT_BACKUP | M_SETOPT_PRESERVE_CMDLINE)
  ------------------
  141|       |
  142|      0|            talloc_free(confpath);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  143|      0|        }
  144|      0|    }
  145|  7.46k|}
configfiles.c:mp_get_playback_resume_config_filename:
  213|   101k|{
  214|   101k|    struct MPOpts *opts = mpctx->opts;
  215|   101k|    char *res = NULL;
  216|   101k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|   101k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|   101k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  217|   101k|    const char *path = NULL;
  218|   101k|    if (mp_is_url(bstr0(fname))) {
  ------------------
  |  Branch (218:9): [True: 21.3k, False: 80.1k]
  ------------------
  219|  21.3k|        path = fname;
  220|  80.1k|    } else if (opts->ignore_path_in_watch_later_config) {
  ------------------
  |  Branch (220:16): [True: 0, False: 80.1k]
  ------------------
  221|      0|        path = mp_basename(fname);
  222|  80.1k|    } else {
  223|  80.1k|        path = mp_normalize_path(tmp, fname);
  224|  80.1k|        if (!path)
  ------------------
  |  Branch (224:13): [True: 11, False: 80.1k]
  ------------------
  225|     11|            goto exit;
  226|  80.1k|    }
  227|   101k|    uint8_t md5[16];
  228|   101k|    av_md5_sum(md5, path, strlen(path));
  229|   101k|    char *conf = talloc_strdup(tmp, "");
  ------------------
  |  |   50|   101k|#define talloc_strdup                   ta_xstrdup
  ------------------
  230|  1.72M|    for (int i = 0; i < 16; i++)
  ------------------
  |  Branch (230:21): [True: 1.62M, False: 101k]
  ------------------
  231|  1.62M|        conf = talloc_asprintf_append(conf, "%02X", md5[i]);
  ------------------
  |  |   63|  1.62M|#define talloc_asprintf_append          ta_talloc_asprintf_append
  ------------------
  232|       |
  233|   101k|    char *wl_dir = mp_get_playback_resume_dir(mpctx);
  234|   101k|    if (wl_dir && wl_dir[0])
  ------------------
  |  Branch (234:9): [True: 0, False: 101k]
  |  Branch (234:19): [True: 0, False: 0]
  ------------------
  235|      0|        res = mp_path_join(NULL, wl_dir, conf);
  236|       |
  237|   101k|exit:
  238|   101k|    talloc_free(tmp);
  ------------------
  |  |   47|   101k|#define talloc_free                     ta_free
  ------------------
  239|   101k|    return res;
  240|   101k|}

mp_update_subtitle_exts:
   66|  5.81k|{
   67|  5.81k|    sub_exts = opts->sub_auto_exts;
   68|  5.81k|}
find_external_files:
  272|  4.53k|{
  273|  4.53k|    struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1);
  ------------------
  |  |   36|  4.53k|#define talloc_array_ptrtype            ta_xnew_array_ptrtype
  |  |  ------------------
  |  |  |  |  140|  4.53k|#define ta_xnew_array_ptrtype(...)      ta_oom_g(ta_new_array_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  4.53k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  274|  4.53k|    int n = 0;
  275|       |
  276|       |    // Load subtitles from current media directory
  277|  4.53k|    append_dir_subtitles(global, opts, &slist, &n, mp_dirname(fname), fname, 0, -1);
  278|       |
  279|       |    // Load subtitles in dirs specified by sub-paths option
  280|  4.53k|    if (opts->sub_auto >= 0) {
  ------------------
  |  Branch (280:9): [True: 4.53k, False: 0]
  ------------------
  281|  4.53k|        load_paths(global, opts, &slist, &n, fname, opts->sub_paths, "sub",
  282|  4.53k|                   STREAM_SUB);
  283|  4.53k|    }
  284|       |
  285|  4.53k|    if (opts->audiofile_auto >= 0) {
  ------------------
  |  Branch (285:9): [True: 0, False: 4.53k]
  ------------------
  286|      0|        load_paths(global, opts, &slist, &n, fname, opts->audiofile_paths,
  287|      0|                   "audio", STREAM_AUDIO);
  288|      0|    }
  289|       |
  290|       |    // Sort by name for filter_subidx()
  291|  4.53k|    qsort(slist, n, sizeof(*slist), compare_sub_filename);
  292|       |
  293|  4.53k|    filter_subidx(&slist, &n);
  294|       |
  295|       |    // Sort subs by priority and append them
  296|  4.53k|    qsort(slist, n, sizeof(*slist), compare_sub_priority);
  297|       |
  298|  4.53k|    struct subfn z = {0};
  299|  4.53k|    MP_TARRAY_APPEND(NULL, slist, n, z);
  ------------------
  |  |  105|  4.53k|    do {                                            \
  |  |  106|  4.53k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.53k|    do {                                            \
  |  |  |  |   97|  4.53k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.53k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.53k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.53k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 4.53k]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.53k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.53k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.53k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.53k|        (idxvar)++;                                 \
  |  |  109|  4.53k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  300|       |
  301|  4.53k|    return slist;
  302|  4.53k|}
external_files.c:append_dir_subtitles:
   92|  4.53k|{
   93|  4.53k|    void *tmpmem = talloc_new(NULL);
  ------------------
  |  |   40|  4.53k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  4.53k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
   94|  4.53k|    struct mp_log *log = mp_log_new(tmpmem, global->log, "find_files");
   95|       |
   96|  4.53k|    struct bstr f_fbname = bstr0(mp_basename(fname));
   97|  4.53k|    struct bstr f_fname = mp_iconv_to_utf8(log, f_fbname,
   98|  4.53k|                                           "UTF-8-MAC", MP_NO_LATIN1_FALLBACK);
   99|  4.53k|    struct bstr f_fname_noext = bstrdup(tmpmem, bstr_strip_ext(f_fname));
  100|  4.53k|    struct bstr f_fname_trim = bstr_strip(f_fname_noext);
  101|       |
  102|  4.53k|    if (f_fbname.start != f_fname.start)
  ------------------
  |  Branch (102:9): [True: 0, False: 4.53k]
  ------------------
  103|      0|        talloc_steal(tmpmem, f_fname.start);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  104|       |
  105|  4.53k|    char *path0 = bstrdup0(tmpmem, path);
  106|       |
  107|  4.53k|    if (mp_is_url(bstr0(path0)))
  ------------------
  |  Branch (107:9): [True: 4.53k, False: 0]
  ------------------
  108|  4.53k|        goto out;
  109|       |
  110|      0|    DIR *d = opendir(path0);
  111|      0|    if (!d)
  ------------------
  |  Branch (111:9): [True: 0, False: 0]
  ------------------
  112|      0|        goto out;
  113|      0|    mp_verbose(log, "Loading external files in %.*s\n", BSTR_P(path));
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (75:53): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  114|      0|    struct dirent *de;
  115|      0|    while ((de = readdir(d))) {
  ------------------
  |  Branch (115:12): [True: 0, False: 0]
  ------------------
  116|      0|        void *tmpmem2 = talloc_new(tmpmem);
  ------------------
  |  |   40|      0|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      0|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  117|      0|        struct bstr den = bstr0(de->d_name);
  118|      0|        struct bstr dename = mp_iconv_to_utf8(log, den,
  119|      0|                                              "UTF-8-MAC", MP_NO_LATIN1_FALLBACK);
  120|       |        // retrieve various parts of the filename
  121|      0|        struct bstr tmp_fname_noext = bstrdup(tmpmem2, bstr_strip_ext(dename));
  122|      0|        struct bstr tmp_fname_ext = bstr_get_ext(dename);
  123|      0|        struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext);
  124|       |
  125|      0|        if (den.start != dename.start)
  ------------------
  |  Branch (125:13): [True: 0, False: 0]
  ------------------
  126|      0|            talloc_steal(tmpmem2, dename.start);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  127|       |
  128|       |        // check what it is (most likely)
  129|      0|        int type = test_ext(opts, tmp_fname_ext);
  130|      0|        char **langs = NULL;
  131|      0|        int fuzz = -1;
  132|      0|        switch (type) {
  ------------------
  |  Branch (132:17): [True: 0, False: 0]
  ------------------
  133|      0|        case STREAM_SUB:
  ------------------
  |  Branch (133:9): [True: 0, False: 0]
  ------------------
  134|      0|            langs = opts->stream_lang[type];
  135|      0|            fuzz = opts->sub_auto;
  136|      0|            break;
  137|      0|        case STREAM_AUDIO:
  ------------------
  |  Branch (137:9): [True: 0, False: 0]
  ------------------
  138|      0|            langs = opts->stream_lang[type];
  139|      0|            fuzz = opts->audiofile_auto;
  140|      0|            break;
  141|      0|        case STREAM_VIDEO:
  ------------------
  |  Branch (141:9): [True: 0, False: 0]
  ------------------
  142|      0|            fuzz = opts->coverart_auto;
  143|      0|            break;
  144|      0|        }
  145|       |
  146|      0|        if (fuzz < 0 || (limit_type >= 0 && limit_type != type))
  ------------------
  |  Branch (146:13): [True: 0, False: 0]
  |  Branch (146:26): [True: 0, False: 0]
  |  Branch (146:45): [True: 0, False: 0]
  ------------------
  147|      0|            goto next_sub;
  148|       |
  149|       |        // we have a (likely) subtitle file
  150|       |        // higher prio -> auto-selection may prefer it (0 = not loaded)
  151|      0|        int prio = 0;
  152|       |
  153|      0|        if (bstrcasecmp(tmp_fname_trim, f_fname_trim) == 0)
  ------------------
  |  Branch (153:13): [True: 0, False: 0]
  ------------------
  154|      0|            prio |= 32; // exact movie name match
  155|       |
  156|      0|        bstr lang = {0};
  157|      0|        int start = 0;
  158|      0|        enum track_flags flags = 0;
  159|      0|        lang = mp_guess_lang_from_filename(dename, &start, &flags);
  160|      0|        if (bstr_case_startswith(tmp_fname_trim, f_fname_trim)) {
  ------------------
  |  Branch (160:13): [True: 0, False: 0]
  ------------------
  161|      0|            if (lang.len && start == f_fname_trim.len)
  ------------------
  |  Branch (161:17): [True: 0, False: 0]
  |  Branch (161:29): [True: 0, False: 0]
  ------------------
  162|      0|                prio |= 16; // exact movie name + followed by lang
  163|       |
  164|      0|            if (lang.len && fuzz >= 1)
  ------------------
  |  Branch (164:17): [True: 0, False: 0]
  |  Branch (164:29): [True: 0, False: 0]
  ------------------
  165|      0|                prio |= 4; // matches the movie name + a language was matched
  166|       |
  167|      0|            for (int n = 0; langs && langs[n]; n++) {
  ------------------
  |  Branch (167:29): [True: 0, False: 0]
  |  Branch (167:38): [True: 0, False: 0]
  ------------------
  168|      0|                if (lang.len && bstr_case_startswith(lang, bstr0(langs[n]))) {
  ------------------
  |  Branch (168:21): [True: 0, False: 0]
  |  Branch (168:33): [True: 0, False: 0]
  ------------------
  169|      0|                    if (fuzz >= 1)
  ------------------
  |  Branch (169:25): [True: 0, False: 0]
  ------------------
  170|      0|                        prio |= 8; // known language -> boost priority
  171|      0|                    break;
  172|      0|                }
  173|      0|            }
  174|      0|        }
  175|       |
  176|      0|        if (bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1)
  ------------------
  |  Branch (176:13): [True: 0, False: 0]
  |  Branch (176:61): [True: 0, False: 0]
  ------------------
  177|      0|            prio |= 2; // contains the movie name
  178|       |
  179|      0|        if (type == STREAM_VIDEO && prio == 0)
  ------------------
  |  Branch (179:13): [True: 0, False: 0]
  |  Branch (179:37): [True: 0, False: 0]
  ------------------
  180|      0|            prio = test_cover_filename(tmp_fname_trim, opts->coverart_whitelist);
  181|       |
  182|       |        // doesn't contain the movie name
  183|       |        // don't try in the mplayer subtitle directory
  184|      0|        if (!limit_fuzziness && fuzz >= 2)
  ------------------
  |  Branch (184:13): [True: 0, False: 0]
  |  Branch (184:33): [True: 0, False: 0]
  ------------------
  185|      0|            prio |= 1;
  186|       |
  187|      0|        mp_trace(log, "Potential external file: \"%s\"  Priority: %d\n",
  ------------------
  |  |   77|      0|#define mp_trace(log, ...)      mp_msg(log, MSGL_TRACE, __VA_ARGS__)
  ------------------
  188|      0|               de->d_name, prio);
  189|       |
  190|      0|        if (prio) {
  ------------------
  |  Branch (190:13): [True: 0, False: 0]
  ------------------
  191|      0|            char *subpath = mp_path_join_bstr(*slist, path, dename);
  192|      0|            if (mp_path_exists(subpath)) {
  ------------------
  |  Branch (192:17): [True: 0, False: 0]
  ------------------
  193|      0|                MP_TARRAY_GROW(NULL, *slist, *nsub);
  ------------------
  |  |   96|      0|    do {                                            \
  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  ------------------
  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  ------------------
  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  ------------------
  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  ------------------
  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  100|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  194|      0|                struct subfn *sub = *slist + (*nsub)++;
  195|       |
  196|       |                // annoying and redundant
  197|      0|                if (strncmp(subpath, "./", 2) == 0)
  ------------------
  |  Branch (197:21): [True: 0, False: 0]
  ------------------
  198|      0|                    subpath += 2;
  199|       |
  200|      0|                sub->type     = type;
  201|      0|                sub->priority = prio;
  202|      0|                sub->fname    = subpath;
  203|      0|                sub->lang     = lang.len ? bstrdup0(*slist, lang) : NULL;
  ------------------
  |  Branch (203:33): [True: 0, False: 0]
  ------------------
  204|      0|                sub->flags    = flags;
  205|      0|            } else
  206|      0|                talloc_free(subpath);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  207|      0|        }
  208|       |
  209|      0|    next_sub:
  210|      0|        talloc_free(tmpmem2);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  211|      0|    }
  212|      0|    closedir(d);
  213|       |
  214|  4.53k| out:
  215|  4.53k|    talloc_free(tmpmem);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  216|  4.53k|}
external_files.c:load_paths:
  248|  4.53k|{
  249|  4.53k|    for (int i = 0; paths && paths[i]; i++) {
  ------------------
  |  Branch (249:21): [True: 0, False: 4.53k]
  |  Branch (249:30): [True: 0, False: 0]
  ------------------
  250|      0|        char *expanded_path = mp_get_user_path(NULL, global, paths[i]);
  251|      0|        char *path = mp_path_join_bstr(
  252|      0|            *slist, mp_dirname(fname),
  253|      0|            bstr0(expanded_path ? expanded_path : paths[i]));
  ------------------
  |  Branch (253:19): [True: 0, False: 0]
  ------------------
  254|      0|        append_dir_subtitles(global, opts, slist, nsubs, bstr0(path),
  255|      0|                             fname, 0, type);
  256|      0|        talloc_free(expanded_path);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  257|      0|    }
  258|       |
  259|       |    // Load subtitles in ~/.mpv/sub (or similar) limiting sub fuzziness
  260|  4.53k|    char *mp_subdir = mp_find_config_file(NULL, global, cfg_path);
  261|  4.53k|    if (mp_subdir) {
  ------------------
  |  Branch (261:9): [True: 0, False: 4.53k]
  ------------------
  262|      0|        append_dir_subtitles(global, opts, slist, nsubs, bstr0(mp_subdir),
  263|      0|                             fname, 1, type);
  264|      0|    }
  265|  4.53k|    talloc_free(mp_subdir);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  266|  4.53k|}
external_files.c:filter_subidx:
  228|  4.53k|{
  229|  4.53k|    const char *prev = NULL;
  230|  4.53k|    for (int n = 0; n < *nsub; n++) {
  ------------------
  |  Branch (230:21): [True: 0, False: 4.53k]
  ------------------
  231|      0|        const char *fname = (*slist)[n].fname;
  232|      0|        if (case_endswith(fname, ".idx")) {
  ------------------
  |  Branch (232:13): [True: 0, False: 0]
  ------------------
  233|      0|            prev = fname;
  234|      0|        } else if (case_endswith(fname, ".sub")) {
  ------------------
  |  Branch (234:20): [True: 0, False: 0]
  ------------------
  235|      0|            if (prev && strncmp(prev, fname, strlen(fname) - 4) == 0)
  ------------------
  |  Branch (235:17): [True: 0, False: 0]
  |  Branch (235:25): [True: 0, False: 0]
  ------------------
  236|      0|                (*slist)[n].priority = -1;
  237|      0|        }
  238|      0|    }
  239|  4.53k|    for (int n = *nsub - 1; n >= 0; n--) {
  ------------------
  |  Branch (239:29): [True: 0, False: 4.53k]
  ------------------
  240|      0|        if ((*slist)[n].priority < 0)
  ------------------
  |  Branch (240:13): [True: 0, False: 0]
  ------------------
  241|      0|            MP_TARRAY_REMOVE_AT(*slist, *nsub, n);
  ------------------
  |  |  143|      0|    do {                                            \
  |  |  144|      0|        size_t at_ = (at);                          \
  |  |  145|      0|        assert(at_ <= (idxvar));                    \
  |  |  146|      0|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|      0|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|      0|        (idxvar)--;                                 \
  |  |  149|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  242|      0|    }
  243|  4.53k|}

mp_abort_playback_async:
   73|  94.7k|{
   74|  94.7k|    mp_cancel_trigger(mpctx->playback_abort);
   75|       |
   76|  94.7k|    mp_mutex_lock(&mpctx->abort_lock);
  ------------------
  |  |  131|  94.7k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
   77|       |
   78|  94.7k|    for (int n = 0; n < mpctx->num_abort_list; n++) {
  ------------------
  |  Branch (78:21): [True: 0, False: 94.7k]
  ------------------
   79|      0|        struct mp_abort_entry *abort = mpctx->abort_list[n];
   80|      0|        if (abort->coupled_to_playback)
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            mp_abort_trigger_locked(mpctx, abort);
   82|      0|    }
   83|       |
   84|  94.7k|    mp_mutex_unlock(&mpctx->abort_lock);
  ------------------
  |  |  133|  94.7k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
   85|  94.7k|}
print_track_list:
  283|  4.53k|{
  284|  4.53k|    if (msg)
  ------------------
  |  Branch (284:9): [True: 0, False: 4.53k]
  ------------------
  285|  4.53k|        MP_INFO(mpctx, "%s\n", msg);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  286|  18.1k|    for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
  ------------------
  |  Branch (286:21): [True: 13.6k, False: 4.53k]
  ------------------
  287|  29.2k|        for (int n = 0; n < mpctx->num_tracks; n++)
  ------------------
  |  Branch (287:25): [True: 15.6k, False: 13.6k]
  ------------------
  288|  15.6k|            if (mpctx->tracks[n]->type == t)
  ------------------
  |  Branch (288:17): [True: 5.22k, False: 10.4k]
  ------------------
  289|       |                // Indent tracks after messages like "Tracks switched" and
  290|       |                // "Playing:".
  291|  5.22k|                print_stream(mpctx, mpctx->tracks[n], msg ||
  ------------------
  |  Branch (291:55): [True: 0, False: 5.22k]
  ------------------
  292|  5.22k|                             mpctx->playlist->num_entries > 1 ||
  ------------------
  |  Branch (292:30): [True: 495, False: 4.72k]
  ------------------
  293|  5.22k|                             mpctx->playing->playlist_path);
  ------------------
  |  Branch (293:30): [True: 0, False: 4.72k]
  ------------------
  294|  13.6k|    }
  295|  4.53k|}
update_demuxer_properties:
  298|  97.8k|{
  299|  97.8k|    struct demuxer *demuxer = mpctx->demuxer;
  300|  97.8k|    if (!demuxer)
  ------------------
  |  Branch (300:9): [True: 0, False: 97.8k]
  ------------------
  301|      0|        return;
  302|  97.8k|    demux_update(demuxer, get_current_time(mpctx));
  303|  97.8k|    int events = demuxer->events;
  304|  97.8k|    if ((events & DEMUX_EVENT_INIT) && demuxer->num_editions > 1) {
  ------------------
  |  Branch (304:9): [True: 4.53k, False: 93.3k]
  |  Branch (304:40): [True: 0, False: 4.53k]
  ------------------
  305|      0|        for (int n = 0; n < demuxer->num_editions; n++) {
  ------------------
  |  Branch (305:25): [True: 0, False: 0]
  ------------------
  306|      0|            struct demux_edition *edition = &demuxer->editions[n];
  307|      0|            char b[128] = {0};
  308|      0|            if (mpctx->playlist->num_entries > 1 || mpctx->playing->playlist_path)
  ------------------
  |  Branch (308:17): [True: 0, False: 0]
  |  Branch (308:53): [True: 0, False: 0]
  ------------------
  309|      0|                APPEND(b, " ");
  ------------------
  |  |  238|      0|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  310|      0|            APPEND(b, "%s --edition=%d", n == demuxer->edition ?
  ------------------
  |  |  238|      0|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (238:54): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  311|      0|                   BLACK_CIRCLE : WHITE_CIRCLE, n);
  312|      0|            char *name = mp_tags_get_str(edition->metadata, "title");
  313|      0|            if (name)
  ------------------
  |  Branch (313:17): [True: 0, False: 0]
  ------------------
  314|      0|                APPEND(b, " '%s'", name);
  ------------------
  |  |  238|      0|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  315|      0|            if (edition->default_edition)
  ------------------
  |  Branch (315:17): [True: 0, False: 0]
  ------------------
  316|      0|                APPEND(b, " [default]");
  ------------------
  |  |  238|      0|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  317|      0|            MP_INFO(mpctx, "%s\n", b);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  318|      0|        }
  319|      0|    }
  320|  97.8k|    struct demuxer *tracks = mpctx->demuxer;
  321|  97.8k|    if (tracks->events & DEMUX_EVENT_STREAMS) {
  ------------------
  |  Branch (321:9): [True: 4.53k, False: 93.3k]
  ------------------
  322|  4.53k|        add_demuxer_tracks(mpctx, tracks);
  323|  4.53k|        print_track_list(mpctx, NULL);
  324|  4.53k|        tracks->events &= ~DEMUX_EVENT_STREAMS;
  325|  4.53k|    }
  326|  97.8k|    if (events & DEMUX_EVENT_METADATA) {
  ------------------
  |  Branch (326:9): [True: 4.53k, False: 93.3k]
  ------------------
  327|  4.53k|        struct mp_tags *info =
  328|  4.53k|            mp_tags_filtered(mpctx, demuxer->metadata, mpctx->opts->display_tags);
  329|       |        // prev is used to attempt to print changed tags only (to some degree)
  330|  4.53k|        struct mp_tags *prev = mpctx->filtered_tags;
  331|  4.53k|        int n_prev = 0;
  332|  4.53k|        bool had_output = false;
  333|  5.84k|        for (int n = 0; n < info->num_keys; n++) {
  ------------------
  |  Branch (333:25): [True: 1.30k, False: 4.53k]
  ------------------
  334|  1.30k|            if (prev && n_prev < prev->num_keys) {
  ------------------
  |  Branch (334:17): [True: 0, False: 1.30k]
  |  Branch (334:25): [True: 0, False: 0]
  ------------------
  335|      0|                if (strcmp(prev->keys[n_prev], info->keys[n]) == 0) {
  ------------------
  |  Branch (335:21): [True: 0, False: 0]
  ------------------
  336|      0|                    n_prev++;
  337|      0|                    if (strcmp(prev->values[n_prev - 1], info->values[n]) == 0)
  ------------------
  |  Branch (337:25): [True: 0, False: 0]
  ------------------
  338|      0|                        continue;
  339|      0|                }
  340|      0|            }
  341|  1.30k|            struct mp_log *log = mp_log_new(NULL, mpctx->log, "!display-tags");
  342|  1.30k|            if (!had_output)
  ------------------
  |  Branch (342:17): [True: 192, False: 1.11k]
  ------------------
  343|    192|                mp_info(log, "File tags:\n");
  ------------------
  |  |   74|    192|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  344|  1.30k|            mp_info(log, " %s: %s\n", info->keys[n], info->values[n]);
  ------------------
  |  |   74|  1.30k|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
  345|  1.30k|            had_output = true;
  346|  1.30k|            talloc_free(log);
  ------------------
  |  |   47|  1.30k|#define talloc_free                     ta_free
  ------------------
  347|  1.30k|        }
  348|  4.53k|        talloc_free(mpctx->filtered_tags);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  349|  4.53k|        mpctx->filtered_tags = info;
  350|  4.53k|        mp_notify(mpctx, MP_EVENT_METADATA_UPDATE, NULL);
  351|  4.53k|    }
  352|  97.8k|    if (events & DEMUX_EVENT_DURATION)
  ------------------
  |  Branch (352:9): [True: 17.2k, False: 80.6k]
  ------------------
  353|  17.2k|        mp_notify(mpctx, MP_EVENT_DURATION_UPDATE, NULL);
  354|  97.8k|    demuxer->events = 0;
  355|  97.8k|}
reselect_demux_stream:
  362|  6.26k|{
  363|  6.26k|    if (!track->stream)
  ------------------
  |  Branch (363:9): [True: 0, False: 6.26k]
  ------------------
  364|      0|        return;
  365|  6.26k|    double pts = get_current_time(mpctx);
  366|  6.26k|    if (pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  6.26k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (366:9): [True: 6.26k, False: 0]
  ------------------
  367|  6.26k|        pts += get_track_seek_offset(mpctx, track);
  368|  6.26k|        if (track->type == STREAM_SUB)
  ------------------
  |  Branch (368:13): [True: 341, False: 5.92k]
  ------------------
  369|    341|            pts -= 10.0;
  370|  6.26k|    }
  371|  6.26k|    if (refresh_only)
  ------------------
  |  Branch (371:9): [True: 0, False: 6.26k]
  ------------------
  372|      0|        demuxer_refresh_track(track->demuxer, track->stream, pts);
  373|  6.26k|    else
  374|  6.26k|        demuxer_select_track(track->demuxer, track->stream, pts, track->selected);
  375|  6.26k|}
add_demuxer_tracks:
  434|  9.07k|{
  435|  19.5k|    for (int n = 0; n < demux_get_num_stream(demuxer); n++)
  ------------------
  |  Branch (435:21): [True: 10.4k, False: 9.07k]
  ------------------
  436|  10.4k|        add_stream_track(mpctx, demuxer, demux_get_stream(demuxer, n));
  437|  9.07k|}
select_default_track:
  562|  18.1k|{
  563|  18.1k|    struct MPOpts *opts = mpctx->opts;
  564|  18.1k|    int tid = opts->stream_id[order][type];
  565|  18.1k|    int preferred_program = (type != STREAM_VIDEO && mpctx->current_track[0][STREAM_VIDEO]) ?
  ------------------
  |  Branch (565:30): [True: 13.6k, False: 4.53k]
  |  Branch (565:54): [True: 8.79k, False: 4.82k]
  ------------------
  566|  9.35k|                            mpctx->current_track[0][STREAM_VIDEO]->program_id : -1;
  567|  18.1k|    if (tid == -2)
  ------------------
  |  Branch (567:9): [True: 4.53k, False: 13.6k]
  ------------------
  568|  4.53k|        return NULL;
  569|  13.6k|    char **langs = process_langs(opts->stream_lang[type]);
  570|  13.6k|    bool os_langs = false;
  571|       |    // Try to add OS languages if enabled by the user and we don't already have a lang from slang.
  572|  13.6k|    if (type == STREAM_SUB && (!langs || !strcmp(langs[0], "")) && opts->subs_match_os_language) {
  ------------------
  |  Branch (572:9): [True: 4.53k, False: 9.07k]
  |  Branch (572:32): [True: 4.53k, False: 0]
  |  Branch (572:42): [True: 0, False: 0]
  |  Branch (572:68): [True: 4.53k, False: 0]
  ------------------
  573|  4.53k|        talloc_free(langs);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  574|  4.53k|        langs = add_os_langs();
  575|  4.53k|        os_langs = true;
  576|  4.53k|    }
  577|  13.6k|    const char *audio_lang = mpctx->current_track[0][STREAM_AUDIO] ?
  ------------------
  |  Branch (577:30): [True: 1.95k, False: 11.6k]
  ------------------
  578|  1.95k|                             mpctx->current_track[0][STREAM_AUDIO]->lang :
  579|  13.6k|                             NULL;
  580|  13.6k|    bool sub = type == STREAM_SUB;
  581|  13.6k|    struct track *pick = NULL;
  582|  29.2k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (582:21): [True: 15.6k, False: 13.6k]
  ------------------
  583|  15.6k|        struct track *track = mpctx->tracks[n];
  584|  15.6k|        if (track->type != type)
  ------------------
  |  Branch (584:13): [True: 10.4k, False: 5.22k]
  ------------------
  585|  10.4k|            continue;
  586|  5.22k|        if (track->user_tid == tid) {
  ------------------
  |  Branch (586:13): [True: 0, False: 5.22k]
  ------------------
  587|      0|            pick = track;
  588|      0|            goto cleanup;
  589|      0|        }
  590|  5.22k|        if (tid >= 0)
  ------------------
  |  Branch (590:13): [True: 0, False: 5.22k]
  ------------------
  591|      0|            continue;
  592|  5.22k|        if (track->no_auto_select)
  ------------------
  |  Branch (592:13): [True: 0, False: 5.22k]
  ------------------
  593|      0|            continue;
  594|  5.22k|        if (duplicate_track(mpctx, order, type, track))
  ------------------
  |  Branch (594:13): [True: 0, False: 5.22k]
  ------------------
  595|      0|            continue;
  596|  5.22k|        if (sub) {
  ------------------
  |  Branch (596:13): [True: 341, False: 4.88k]
  ------------------
  597|       |            // Subtitle specific auto-selecting crap.
  598|    341|            bool audio_matches = audio_lang && track->lang && !strcasecmp(audio_lang, track->lang);
  ------------------
  |  Branch (598:34): [True: 0, False: 341]
  |  Branch (598:48): [True: 0, False: 0]
  |  Branch (598:63): [True: 0, False: 0]
  ------------------
  599|    341|            bool forced = track->forced_track && (opts->subs_fallback_forced == 2 ||
  ------------------
  |  Branch (599:27): [True: 0, False: 341]
  |  Branch (599:51): [True: 0, False: 0]
  ------------------
  600|      0|                          (audio_matches && opts->subs_fallback_forced == 1));
  ------------------
  |  Branch (600:28): [True: 0, False: 0]
  |  Branch (600:45): [True: 0, False: 0]
  ------------------
  601|    341|            bool lang_match = !os_langs && mp_match_lang(langs, track->lang) > 0;
  ------------------
  |  Branch (601:31): [True: 0, False: 341]
  |  Branch (601:44): [True: 0, False: 0]
  ------------------
  602|    341|            bool subs_fallback = (track->is_external && !track->no_default) || opts->subs_fallback == 2 ||
  ------------------
  |  Branch (602:35): [True: 0, False: 341]
  |  Branch (602:57): [True: 0, False: 0]
  |  Branch (602:80): [True: 0, False: 341]
  ------------------
  603|    341|                                 (opts->subs_fallback == 1 && track->default_track);
  ------------------
  |  Branch (603:35): [True: 341, False: 0]
  |  Branch (603:63): [True: 0, False: 341]
  ------------------
  604|    341|            bool subs_matching_audio = (!mp_match_lang(langs, audio_lang) || opts->subs_with_matching_audio == 2 ||
  ------------------
  |  Branch (604:41): [True: 341, False: 0]
  |  Branch (604:78): [True: 0, False: 0]
  ------------------
  605|    341|                                        (opts->subs_with_matching_audio == 1 && track->forced_track));
  ------------------
  |  Branch (605:42): [True: 0, False: 0]
  |  Branch (605:81): [True: 0, False: 0]
  ------------------
  606|    341|            if (subs_matching_audio && ((!pick && (forced || lang_match || subs_fallback)) ||
  ------------------
  |  Branch (606:17): [True: 341, False: 0]
  |  Branch (606:42): [True: 341, False: 0]
  |  Branch (606:52): [True: 0, False: 341]
  |  Branch (606:62): [True: 0, False: 341]
  |  Branch (606:76): [True: 0, False: 341]
  ------------------
  607|    341|                (pick && compare_track(track, pick, langs, os_langs, forced, mpctx->opts, preferred_program))))
  ------------------
  |  Branch (607:18): [True: 0, False: 341]
  |  Branch (607:26): [True: 0, False: 0]
  ------------------
  608|      0|            {
  609|      0|                pick = track;
  610|      0|                pick->forced_select = forced;
  611|      0|            }
  612|  4.88k|        } else if (!pick || compare_track(track, pick, langs, os_langs, false, mpctx->opts, preferred_program)) {
  ------------------
  |  Branch (612:20): [True: 4.88k, False: 0]
  |  Branch (612:29): [True: 0, False: 0]
  ------------------
  613|  4.88k|            pick = track;
  614|  4.88k|        }
  615|  5.22k|    }
  616|       |
  617|  13.6k|    if (pick && pick->attached_picture && !mpctx->opts->audio_display)
  ------------------
  |  Branch (617:9): [True: 4.88k, False: 8.73k]
  |  Branch (617:17): [True: 0, False: 4.88k]
  |  Branch (617:43): [True: 0, False: 0]
  ------------------
  618|      0|        pick = NULL;
  619|  13.6k|    if (pick && !opts->autoload_files && pick->is_external)
  ------------------
  |  Branch (619:9): [True: 4.88k, False: 8.73k]
  |  Branch (619:17): [True: 0, False: 4.88k]
  |  Branch (619:42): [True: 0, False: 0]
  ------------------
  620|      0|        pick = NULL;
  621|  13.6k|cleanup:
  622|  13.6k|    talloc_free(langs);
  ------------------
  |  |   47|  13.6k|#define talloc_free                     ta_free
  ------------------
  623|  13.6k|    return pick;
  624|  13.6k|}
mark_track_selection:
  670|  1.04k|{
  671|  1.04k|    mp_assert(order >= 0 && order < num_ptracks[type]);
  ------------------
  |  |   41|  1.04k|#define mp_assert assert
  ------------------
  672|  1.04k|    mpctx->opts->stream_id[order][type] = value;
  673|  1.04k|    m_config_notify_change_opt_ptr(mpctx->mconfig,
  674|  1.04k|                                   &mpctx->opts->stream_id[order][type]);
  675|  1.04k|}
mp_switch_track_n:
  679|  1.04k|{
  680|  1.04k|    mp_assert(!track || track->type == type);
  ------------------
  |  |   41|  1.04k|#define mp_assert assert
  ------------------
  681|  1.04k|    mp_assert(type >= 0 && type < STREAM_TYPE_COUNT);
  ------------------
  |  |   41|  1.04k|#define mp_assert assert
  ------------------
  682|  1.04k|    mp_assert(order >= 0 && order < num_ptracks[type]);
  ------------------
  |  |   41|  1.04k|#define mp_assert assert
  ------------------
  683|       |
  684|       |    // Mark the current track selection as explicitly user-requested. (This is
  685|       |    // different from auto-selection or disabling a track due to errors.)
  686|  1.04k|    if (flags & FLAG_MARK_SELECTION)
  ------------------
  |  |  535|  1.04k|#define FLAG_MARK_SELECTION 1
  ------------------
  |  Branch (686:9): [True: 0, False: 1.04k]
  ------------------
  687|      0|        mark_track_selection(mpctx, order, type, track ? track->user_tid : -2);
  ------------------
  |  Branch (687:50): [True: 0, False: 0]
  ------------------
  688|       |
  689|       |    // No decoder should be initialized yet.
  690|  1.04k|    if (!mpctx->demuxer)
  ------------------
  |  Branch (690:9): [True: 0, False: 1.04k]
  ------------------
  691|      0|        return;
  692|       |
  693|  1.04k|    struct track *current = mpctx->current_track[order][type];
  694|  1.04k|    if (track == current)
  ------------------
  |  Branch (694:9): [True: 0, False: 1.04k]
  ------------------
  695|      0|        return;
  696|       |
  697|  1.04k|    if (current && current->sink) {
  ------------------
  |  Branch (697:9): [True: 1.04k, False: 0]
  |  Branch (697:20): [True: 0, False: 1.04k]
  ------------------
  698|      0|        MP_ERR(mpctx, "Can't disable input to complex filter.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  699|      0|        goto error;
  700|      0|    }
  701|  1.04k|    if ((type == STREAM_VIDEO && mpctx->vo_chain && !mpctx->vo_chain->track) ||
  ------------------
  |  Branch (701:10): [True: 903, False: 141]
  |  Branch (701:34): [True: 903, False: 0]
  |  Branch (701:53): [True: 0, False: 903]
  ------------------
  702|  1.04k|        (type == STREAM_AUDIO && mpctx->ao_chain && !mpctx->ao_chain->track))
  ------------------
  |  Branch (702:10): [True: 141, False: 903]
  |  Branch (702:34): [True: 138, False: 3]
  |  Branch (702:53): [True: 0, False: 138]
  ------------------
  703|      0|    {
  704|      0|        MP_ERR(mpctx, "Can't switch away from complex filter output.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  705|      0|        goto error;
  706|      0|    }
  707|       |
  708|  1.04k|    if (track && track->selected) {
  ------------------
  |  Branch (708:9): [True: 0, False: 1.04k]
  |  Branch (708:18): [True: 0, False: 0]
  ------------------
  709|       |        // Track has been selected in a different order parameter.
  710|      0|        MP_ERR(mpctx, "Track %d is already selected.\n", track->user_tid);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  711|      0|        goto error;
  712|      0|    }
  713|       |
  714|  1.04k|    if (order == 0) {
  ------------------
  |  Branch (714:9): [True: 1.04k, False: 0]
  ------------------
  715|  1.04k|        if (type == STREAM_VIDEO) {
  ------------------
  |  Branch (715:13): [True: 903, False: 141]
  ------------------
  716|    903|            uninit_video_chain(mpctx);
  717|    903|            if (!track)
  ------------------
  |  Branch (717:17): [True: 903, False: 0]
  ------------------
  718|    903|                handle_force_window(mpctx, true);
  719|    903|        } else if (type == STREAM_AUDIO) {
  ------------------
  |  Branch (719:20): [True: 141, False: 0]
  ------------------
  720|    141|            clear_audio_output_buffers(mpctx);
  721|    141|            uninit_audio_chain(mpctx);
  722|    141|            if (!track)
  ------------------
  |  Branch (722:17): [True: 141, False: 0]
  ------------------
  723|    141|                uninit_audio_out(mpctx);
  724|    141|        }
  725|  1.04k|    }
  726|  1.04k|    if (type == STREAM_SUB)
  ------------------
  |  Branch (726:9): [True: 0, False: 1.04k]
  ------------------
  727|      0|        uninit_sub(mpctx, current);
  728|       |
  729|  1.04k|    if (current) {
  ------------------
  |  Branch (729:9): [True: 1.04k, False: 0]
  ------------------
  730|  1.04k|        current->selected = false;
  731|  1.04k|        reselect_demux_stream(mpctx, current, false);
  732|  1.04k|    }
  733|       |
  734|  1.04k|    mpctx->current_track[order][type] = track;
  735|       |
  736|  1.04k|    if (track) {
  ------------------
  |  Branch (736:9): [True: 0, False: 1.04k]
  ------------------
  737|      0|        track->selected = true;
  738|      0|        reselect_demux_stream(mpctx, track, false);
  739|      0|    }
  740|       |
  741|  1.04k|    if (type == STREAM_VIDEO && order == 0) {
  ------------------
  |  Branch (741:9): [True: 903, False: 141]
  |  Branch (741:33): [True: 903, False: 0]
  ------------------
  742|    903|        reinit_video_chain(mpctx);
  743|    903|    } else if (type == STREAM_AUDIO && order == 0) {
  ------------------
  |  Branch (743:16): [True: 141, False: 0]
  |  Branch (743:40): [True: 141, False: 0]
  ------------------
  744|    141|        reinit_audio_chain(mpctx);
  745|    141|    } else if (type == STREAM_SUB && order >= 0 && order <= 2) {
  ------------------
  |  Branch (745:16): [True: 0, False: 0]
  |  Branch (745:38): [True: 0, False: 0]
  |  Branch (745:52): [True: 0, False: 0]
  ------------------
  746|      0|        reinit_sub(mpctx, track);
  747|      0|    }
  748|       |
  749|  1.04k|    mp_notify(mpctx, MP_EVENT_TRACK_SWITCHED, NULL);
  750|  1.04k|    mp_wakeup_core(mpctx);
  751|       |
  752|  1.04k|    talloc_free(mpctx->track_layout_hash);
  ------------------
  |  |   47|  1.04k|#define talloc_free                     ta_free
  ------------------
  753|  1.04k|    mpctx->track_layout_hash = talloc_steal(mpctx, track_layout_hash(mpctx));
  ------------------
  |  |   38|  1.04k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  1.04k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  754|       |
  755|  1.04k|    return;
  756|      0|error:
  757|      0|    mark_track_selection(mpctx, order, type, -1);
  758|      0|}
mp_deselect_track:
  767|  1.04k|{
  768|  1.04k|    if (track && track->selected) {
  ------------------
  |  Branch (768:9): [True: 1.04k, False: 0]
  |  Branch (768:18): [True: 1.04k, False: 0]
  ------------------
  769|  2.08k|        for (int t = 0; t < num_ptracks[track->type]; t++) {
  ------------------
  |  Branch (769:25): [True: 1.04k, False: 1.04k]
  ------------------
  770|  1.04k|            if (mpctx->current_track[t][track->type] != track)
  ------------------
  |  Branch (770:17): [True: 0, False: 1.04k]
  ------------------
  771|      0|                continue;
  772|  1.04k|            mp_switch_track_n(mpctx, t, track->type, NULL, 0);
  773|  1.04k|            mark_track_selection(mpctx, t, track->type, -1); // default
  774|  1.04k|        }
  775|  1.04k|    }
  776|  1.04k|}
autoload_external_files:
  958|  4.53k|{
  959|  4.53k|    struct MPOpts *opts = mpctx->opts;
  960|       |
  961|  4.53k|    if (opts->sub_auto < 0 && opts->audiofile_auto < 0 && opts->coverart_auto < 0)
  ------------------
  |  Branch (961:9): [True: 0, False: 4.53k]
  |  Branch (961:31): [True: 0, False: 0]
  |  Branch (961:59): [True: 0, False: 0]
  ------------------
  962|      0|        return;
  963|  4.53k|    if (!opts->autoload_files || strcmp(mpctx->filename, "-") == 0)
  ------------------
  |  Branch (963:9): [True: 0, False: 4.53k]
  |  Branch (963:34): [True: 0, False: 4.53k]
  ------------------
  964|      0|        return;
  965|       |
  966|  4.53k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  4.53k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  4.53k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  967|  4.53k|    struct subfn *list = find_external_files(mpctx->global, mpctx->filename, opts);
  968|  4.53k|    talloc_steal(tmp, list);
  ------------------
  |  |   38|  4.53k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  4.53k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  969|       |
  970|  4.53k|    int sc[STREAM_TYPE_COUNT] = {0};
  971|  9.76k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (971:21): [True: 5.22k, False: 4.53k]
  ------------------
  972|  5.22k|        if (!mpctx->tracks[n]->attached_picture)
  ------------------
  |  Branch (972:13): [True: 5.22k, False: 0]
  ------------------
  973|  5.22k|            sc[mpctx->tracks[n]->type]++;
  974|  5.22k|    }
  975|       |
  976|  4.53k|    for (int i = 0; list && list[i].fname; i++) {
  ------------------
  |  Branch (976:21): [True: 4.53k, False: 0]
  |  Branch (976:29): [True: 0, False: 4.53k]
  ------------------
  977|      0|        struct subfn *e = &list[i];
  978|       |
  979|      0|        for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (979:25): [True: 0, False: 0]
  ------------------
  980|      0|            struct track *t = mpctx->tracks[n];
  981|      0|            if (t->demuxer && strcmp(t->demuxer->filename, e->fname) == 0)
  ------------------
  |  Branch (981:17): [True: 0, False: 0]
  |  Branch (981:31): [True: 0, False: 0]
  ------------------
  982|      0|                goto skip;
  983|      0|        }
  984|      0|        if (e->type == STREAM_SUB && !sc[STREAM_VIDEO] && !sc[STREAM_AUDIO])
  ------------------
  |  Branch (984:13): [True: 0, False: 0]
  |  Branch (984:38): [True: 0, False: 0]
  |  Branch (984:59): [True: 0, False: 0]
  ------------------
  985|      0|            goto skip;
  986|      0|        if (e->type == STREAM_AUDIO && !sc[STREAM_VIDEO])
  ------------------
  |  Branch (986:13): [True: 0, False: 0]
  |  Branch (986:40): [True: 0, False: 0]
  ------------------
  987|      0|            goto skip;
  988|      0|        if (e->type == STREAM_VIDEO && (sc[STREAM_VIDEO] || !sc[STREAM_AUDIO]))
  ------------------
  |  Branch (988:13): [True: 0, False: 0]
  |  Branch (988:41): [True: 0, False: 0]
  |  Branch (988:61): [True: 0, False: 0]
  ------------------
  989|      0|            goto skip;
  990|       |
  991|      0|        enum track_flags flags = e->flags;
  992|       |        // when given filter is set to video, we are loading up cover art
  993|      0|        flags |= e->type == STREAM_VIDEO ? TRACK_ATTACHED_PICTURE : 0;
  ------------------
  |  Branch (993:18): [True: 0, False: 0]
  ------------------
  994|      0|        int first = mp_add_external_file(mpctx, e->fname, e->type, cancel, flags);
  995|      0|        if (first < 0)
  ------------------
  |  Branch (995:13): [True: 0, False: 0]
  ------------------
  996|      0|            goto skip;
  997|       |
  998|      0|        for (int n = first; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (998:29): [True: 0, False: 0]
  ------------------
  999|      0|            struct track *t = mpctx->tracks[n];
 1000|      0|            t->auto_loaded = true;
 1001|      0|            if (!t->lang)
  ------------------
  |  Branch (1001:17): [True: 0, False: 0]
  ------------------
 1002|      0|                t->lang = talloc_strdup(t, e->lang);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
 1003|      0|        }
 1004|      0|    skip:;
 1005|      0|    }
 1006|       |
 1007|  4.53k|    talloc_free(tmp);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
 1008|  4.53k|}
prepare_playlist:
 1013|  6.20k|{
 1014|  6.20k|    struct MPOpts *opts = mpctx->opts;
 1015|       |
 1016|  6.20k|    pl->current = NULL;
 1017|  6.20k|    pl->playlist_completed = false;
 1018|  6.20k|    pl->playlist_started = false;
 1019|       |
 1020|  6.20k|    if (opts->playlist_pos >= 0)
  ------------------
  |  Branch (1020:9): [True: 0, False: 6.20k]
  ------------------
 1021|      0|        pl->current = playlist_entry_from_index(pl, opts->playlist_pos);
 1022|       |
 1023|  6.20k|    if (pl->playlist_dir)
  ------------------
  |  Branch (1023:9): [True: 0, False: 6.20k]
  ------------------
 1024|      0|        playlist_set_current(pl);
 1025|       |
 1026|  6.20k|    if (opts->shuffle)
  ------------------
  |  Branch (1026:9): [True: 0, False: 6.20k]
  ------------------
 1027|      0|        playlist_shuffle(pl);
 1028|       |
 1029|  6.20k|    if (opts->merge_files)
  ------------------
  |  Branch (1029:9): [True: 0, False: 6.20k]
  ------------------
 1030|      0|        merge_playlist_files(pl);
 1031|       |
 1032|  6.20k|    if (!pl->current)
  ------------------
  |  Branch (1032:9): [True: 6.20k, False: 0]
  ------------------
 1033|  6.20k|        pl->current = mp_check_playlist_resume(mpctx, pl);
 1034|       |
 1035|  6.20k|    if (!pl->current)
  ------------------
  |  Branch (1035:9): [True: 6.20k, False: 0]
  ------------------
 1036|  6.20k|        pl->current = playlist_get_first(pl);
 1037|  6.20k|}
prefetch_next:
 1273|  10.3k|{
 1274|  10.3k|    if (!mpctx->opts->prefetch_open || mpctx->open_active)
  ------------------
  |  Branch (1274:9): [True: 0, False: 10.3k]
  |  Branch (1274:40): [True: 607, False: 9.78k]
  ------------------
 1275|    607|        return;
 1276|       |
 1277|  9.78k|    struct playlist_entry *new_entry = mp_next_file(mpctx, +1, false, false);
 1278|  9.78k|    if (new_entry && new_entry->filename) {
  ------------------
  |  Branch (1278:9): [True: 232, False: 9.55k]
  |  Branch (1278:22): [True: 232, False: 0]
  ------------------
 1279|    232|        MP_VERBOSE(mpctx, "Prefetching: %s\n", new_entry->filename);
  ------------------
  |  |   88|    232|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    232|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1280|    232|        start_open(mpctx, new_entry->filename, new_entry->stream_flags, true);
 1281|    232|    }
 1282|  9.78k|}
update_lavfi_complex:
 1491|  5.81k|{
 1492|  5.81k|    if (mpctx->playback_initialized) {
  ------------------
  |  Branch (1492:9): [True: 0, False: 5.81k]
  ------------------
 1493|      0|        if (reinit_complex_filters(mpctx, false) != 0)
  ------------------
  |  Branch (1493:13): [True: 0, False: 0]
  ------------------
 1494|      0|            issue_refresh_seek(mpctx, MPSEEK_EXACT);
 1495|      0|    }
 1496|  5.81k|}
mp_next_file:
 2038|   104k|{
 2039|   104k|    struct playlist_entry *next = playlist_get_next(mpctx->playlist, direction);
 2040|   104k|    if (next && direction < 0 && !force)
  ------------------
  |  Branch (2040:9): [True: 89.1k, False: 15.3k]
  |  Branch (2040:17): [True: 0, False: 89.1k]
  |  Branch (2040:34): [True: 0, False: 0]
  ------------------
 2041|      0|        next->playlist_prev_attempt = true;
 2042|   104k|    if (!next && mpctx->opts->loop_times != 1) {
  ------------------
  |  Branch (2042:9): [True: 15.3k, False: 89.1k]
  |  Branch (2042:18): [True: 0, False: 15.3k]
  ------------------
 2043|      0|        if (direction > 0) {
  ------------------
  |  Branch (2043:13): [True: 0, False: 0]
  ------------------
 2044|      0|            if (mpctx->opts->shuffle) {
  ------------------
  |  Branch (2044:17): [True: 0, False: 0]
  ------------------
 2045|      0|                if (!update_loop)
  ------------------
  |  Branch (2045:21): [True: 0, False: 0]
  ------------------
 2046|      0|                    return NULL;
 2047|      0|                playlist_shuffle(mpctx->playlist);
 2048|      0|            }
 2049|      0|            next = playlist_get_first(mpctx->playlist);
 2050|      0|            if (next && mpctx->opts->loop_times > 1 && update_loop) {
  ------------------
  |  Branch (2050:17): [True: 0, False: 0]
  |  Branch (2050:25): [True: 0, False: 0]
  |  Branch (2050:56): [True: 0, False: 0]
  ------------------
 2051|      0|                mpctx->opts->loop_times--;
 2052|      0|                m_config_notify_change_opt_ptr(mpctx->mconfig,
 2053|      0|                                               &mpctx->opts->loop_times);
 2054|      0|            }
 2055|      0|        } else {
 2056|      0|            next = playlist_get_last(mpctx->playlist);
 2057|      0|        }
 2058|      0|        bool ignore_failures = mpctx->opts->loop_times == -2;
 2059|      0|        if (!force && next && next->init_failed && !ignore_failures) {
  ------------------
  |  Branch (2059:13): [True: 0, False: 0]
  |  Branch (2059:23): [True: 0, False: 0]
  |  Branch (2059:31): [True: 0, False: 0]
  |  Branch (2059:52): [True: 0, False: 0]
  ------------------
 2060|       |            // Don't endless loop if no file in playlist is playable
 2061|      0|            bool all_failed = true;
 2062|      0|            for (int n = 0; n < mpctx->playlist->num_entries; n++) {
  ------------------
  |  Branch (2062:29): [True: 0, False: 0]
  ------------------
 2063|      0|                all_failed &= mpctx->playlist->entries[n]->init_failed;
 2064|      0|                if (!all_failed)
  ------------------
  |  Branch (2064:21): [True: 0, False: 0]
  ------------------
 2065|      0|                    break;
 2066|      0|            }
 2067|      0|            if (all_failed)
  ------------------
  |  Branch (2067:17): [True: 0, False: 0]
  ------------------
 2068|      0|                next = NULL;
 2069|      0|        }
 2070|      0|    }
 2071|   104k|    return next;
 2072|   104k|}
mp_play_files:
 2077|  5.81k|{
 2078|  5.81k|    stats_register_thread_cputime(mpctx->stats, "thread");
 2079|       |
 2080|       |    // Wait for all scripts to load before possibly starting playback.
 2081|  5.81k|    if (!mp_clients_all_initialized(mpctx)) {
  ------------------
  |  Branch (2081:9): [True: 0, False: 5.81k]
  ------------------
 2082|      0|        MP_VERBOSE(mpctx, "Waiting for scripts...\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2083|      0|        while (!mp_clients_all_initialized(mpctx))
  ------------------
  |  Branch (2083:16): [True: 0, False: 0]
  ------------------
 2084|      0|            mp_idle(mpctx);
 2085|      0|        mp_wakeup_core(mpctx); // avoid lost wakeups during waiting
 2086|      0|        MP_VERBOSE(mpctx, "Done loading scripts.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2087|      0|    }
 2088|       |    // After above is finished; but even if it's skipped.
 2089|  5.81k|    mp_msg_set_early_logging(mpctx->global, false);
 2090|       |
 2091|  5.81k|    prepare_playlist(mpctx, mpctx->playlist);
 2092|       |
 2093|   100k|    for (;;) {
 2094|   100k|        idle_loop(mpctx);
 2095|       |
 2096|   100k|        if (mpctx->stop_play == PT_QUIT)
  ------------------
  |  Branch (2096:13): [True: 5.81k, False: 94.7k]
  ------------------
 2097|  5.81k|            break;
 2098|       |
 2099|  94.7k|        if (mpctx->playlist->current)
  ------------------
  |  Branch (2099:13): [True: 94.7k, False: 0]
  ------------------
 2100|  94.7k|            play_current_file(mpctx);
 2101|       |
 2102|  94.7k|        if (mpctx->stop_play == PT_QUIT)
  ------------------
  |  Branch (2102:13): [True: 0, False: 94.7k]
  ------------------
 2103|      0|            break;
 2104|       |
 2105|  94.7k|        struct playlist_entry *new_entry = NULL;
 2106|  94.7k|        if (mpctx->stop_play == PT_NEXT_ENTRY || mpctx->stop_play == PT_ERROR ||
  ------------------
  |  Branch (2106:13): [True: 0, False: 94.7k]
  |  Branch (2106:50): [True: 91.7k, False: 2.95k]
  ------------------
 2107|  94.7k|            mpctx->stop_play == AT_END_OF_FILE)
  ------------------
  |  Branch (2107:13): [True: 2.95k, False: 0]
  ------------------
 2108|  94.7k|        {
 2109|  94.7k|            new_entry = mp_next_file(mpctx, +1, false, true);
 2110|  94.7k|        } else if (mpctx->stop_play == PT_CURRENT_ENTRY) {
  ------------------
  |  Branch (2110:20): [True: 0, False: 0]
  ------------------
 2111|      0|            new_entry = mpctx->playlist->current;
 2112|      0|        }
 2113|       |
 2114|  94.7k|        if (!new_entry)
  ------------------
  |  Branch (2114:13): [True: 5.81k, False: 88.9k]
  ------------------
 2115|  5.81k|            mpctx->playlist->playlist_completed = true;
 2116|       |
 2117|  94.7k|        mpctx->playlist->current = new_entry;
 2118|  94.7k|        mpctx->playlist->current_was_replaced = false;
 2119|  94.7k|        mpctx->stop_play = new_entry ? PT_NEXT_ENTRY : PT_STOP;
  ------------------
  |  Branch (2119:28): [True: 88.9k, False: 5.81k]
  ------------------
 2120|       |
 2121|  94.7k|        if (!mpctx->playlist->current && mpctx->opts->player_idle_mode < 2)
  ------------------
  |  Branch (2121:13): [True: 5.81k, False: 88.9k]
  |  Branch (2121:42): [True: 0, False: 5.81k]
  ------------------
 2122|      0|            break;
 2123|  94.7k|    }
 2124|       |
 2125|  5.81k|    cancel_open(mpctx);
 2126|       |
 2127|  5.81k|    if (mpctx->encode_lavc_ctx) {
  ------------------
  |  Branch (2127:9): [True: 0, False: 5.81k]
  ------------------
 2128|       |        // Make sure all streams get finished.
 2129|      0|        uninit_audio_out(mpctx);
 2130|      0|        uninit_video_out(mpctx);
 2131|       |
 2132|      0|        if (!encode_lavc_free(mpctx->encode_lavc_ctx))
  ------------------
  |  Branch (2132:13): [True: 0, False: 0]
  ------------------
 2133|      0|            mpctx->files_errored += 1;
 2134|       |
 2135|      0|        mpctx->encode_lavc_ctx = NULL;
 2136|      0|    }
 2137|  5.81k|}
mp_set_playlist_entry:
 2142|  5.81k|{
 2143|  5.81k|    mp_assert(!e || playlist_entry_to_index(mpctx->playlist, e) >= 0);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
 2144|  5.81k|    mpctx->playlist->current = e;
 2145|  5.81k|    mpctx->playlist->current_was_replaced = false;
 2146|  5.81k|    mp_notify(mpctx, MP_EVENT_CHANGE_PLAYLIST, NULL);
 2147|       |    // Make it pick up the new entry.
 2148|  5.81k|    if (mpctx->stop_play != PT_QUIT)
  ------------------
  |  Branch (2148:9): [True: 5.81k, False: 0]
  ------------------
 2149|  5.81k|        mpctx->stop_play = e ? PT_CURRENT_ENTRY : PT_STOP;
  ------------------
  |  Branch (2149:28): [True: 5.81k, False: 0]
  ------------------
 2150|  5.81k|    mp_wakeup_core(mpctx);
 2151|  5.81k|}
loadfile.c:print_stream:
  242|  5.22k|{
  243|  5.22k|    const char *tname = "?";
  244|  5.22k|    const char *selopt = "?";
  245|  5.22k|    const char *langopt = "?";
  246|  5.22k|    switch (t->type) {
  ------------------
  |  Branch (246:13): [True: 0, False: 5.22k]
  ------------------
  247|  2.93k|    case STREAM_VIDEO:
  ------------------
  |  Branch (247:5): [True: 2.93k, False: 2.29k]
  ------------------
  248|  2.93k|        tname = t->image ? "Image" : "Video"; selopt = "vid"; langopt = "vlang";
  ------------------
  |  Branch (248:17): [True: 1.67k, False: 1.25k]
  ------------------
  249|  2.93k|        break;
  250|  1.95k|    case STREAM_AUDIO:
  ------------------
  |  Branch (250:5): [True: 1.95k, False: 3.27k]
  ------------------
  251|  1.95k|        tname = "Audio"; selopt = "aid"; langopt = "alang";
  252|  1.95k|        break;
  253|    341|    case STREAM_SUB:
  ------------------
  |  Branch (253:5): [True: 341, False: 4.88k]
  ------------------
  254|    341|        tname = "Subs"; selopt = "sid"; langopt = "slang";
  255|    341|        break;
  256|  5.22k|    }
  257|  5.22k|    char b[2048] = {0};
  258|       |
  259|  5.22k|    int max_lang_length = 0;
  260|  12.2k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (260:21): [True: 7.01k, False: 5.22k]
  ------------------
  261|  7.01k|        if (mpctx->tracks[n]->lang)
  ------------------
  |  Branch (261:13): [True: 0, False: 7.01k]
  ------------------
  262|      0|            max_lang_length = MPMAX(strlen(mpctx->tracks[n]->lang), max_lang_length);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  263|  7.01k|    }
  264|       |
  265|  5.22k|    if (indent)
  ------------------
  |  Branch (265:9): [True: 495, False: 4.72k]
  ------------------
  266|    495|        APPEND(b, " ");
  ------------------
  |  |  238|    495|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  267|  5.22k|    APPEND(b, "%s %-5s  --%s=%-2d", t->selected ? BLACK_CIRCLE : WHITE_CIRCLE,
  ------------------
  |  |  238|  10.4k|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (238:54): [True: 4.88k, False: 341]
  |  |  ------------------
  ------------------
  268|  5.22k|           tname, selopt, t->user_tid);
  269|  5.22k|    if (t->lang) {
  ------------------
  |  Branch (269:9): [True: 0, False: 5.22k]
  ------------------
  270|      0|        APPEND(b, " --%s=%-*s ", langopt, max_lang_length, t->lang);
  ------------------
  |  |  238|      0|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  271|  5.22k|    } else if (max_lang_length) {
  ------------------
  |  Branch (271:16): [True: 0, False: 5.22k]
  ------------------
  272|      0|        FILL(b, (int) strlen(" --alang= ") + max_lang_length);
  ------------------
  |  |  239|      0|#define FILL(s, n) mp_snprintf_cat(s, sizeof(s), "%*s", n, "")
  ------------------
  273|      0|    }
  274|       |
  275|  5.22k|    void *ctx = talloc_new(NULL);
  ------------------
  |  |   40|  5.22k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  5.22k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  276|  5.22k|    APPEND(b, " %s", mp_format_track_metadata(ctx, t, false));
  ------------------
  |  |  238|  5.22k|#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
  ------------------
  277|  5.22k|    talloc_free(ctx);
  ------------------
  |  |   47|  5.22k|#define talloc_free                     ta_free
  ------------------
  278|       |
  279|  5.22k|    MP_INFO(mpctx, "%s\n", b);
  ------------------
  |  |   87|  5.22k|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.22k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  280|  5.22k|}
loadfile.c:add_stream_track:
  399|  10.4k|{
  400|  12.2k|    for (int i = 0; i < mpctx->num_tracks; i++) {
  ------------------
  |  Branch (400:21): [True: 7.01k, False: 5.22k]
  ------------------
  401|  7.01k|        struct track *track = mpctx->tracks[i];
  402|  7.01k|        if (track->stream == stream)
  ------------------
  |  Branch (402:13): [True: 5.22k, False: 1.78k]
  ------------------
  403|  5.22k|            return track;
  404|  7.01k|    }
  405|       |
  406|  5.22k|    struct track *track = talloc_ptrtype(NULL, track);
  ------------------
  |  |   34|  5.22k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  5.22k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.22k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  407|  5.22k|    *track = (struct track) {
  408|  5.22k|        .type = stream->type,
  409|  5.22k|        .user_tid = find_new_tid(mpctx, stream->type),
  410|  5.22k|        .demuxer_id = stream->demuxer_id,
  411|  5.22k|        .ff_index = stream->ff_index,
  412|  5.22k|        .hls_bitrate = stream->hls_bitrate,
  413|  5.22k|        .program_id = stream->program_id,
  414|  5.22k|        .title = stream->title,
  415|  5.22k|        .default_track = stream->default_track,
  416|  5.22k|        .forced_track = stream->forced_track,
  417|  5.22k|        .dependent_track = stream->dependent_track,
  418|  5.22k|        .visual_impaired_track = stream->visual_impaired_track,
  419|  5.22k|        .hearing_impaired_track = stream->hearing_impaired_track,
  420|  5.22k|        .image = stream->image,
  421|  5.22k|        .attached_picture = stream->attached_picture != NULL,
  422|  5.22k|        .lang = stream->lang,
  423|  5.22k|        .demuxer = demuxer,
  424|  5.22k|        .stream = stream,
  425|  5.22k|    };
  426|  5.22k|    MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
  ------------------
  |  |  105|  5.22k|    do {                                            \
  |  |  106|  5.22k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.22k|    do {                                            \
  |  |  |  |   97|  5.22k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.22k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.22k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.22k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.11k, False: 1.11k]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.22k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.11k|    do {                                                        \
  |  |  |  |  |  |   89|  4.11k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.11k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.11k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.11k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.11k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.11k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.11k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.22k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  5.22k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  5.22k|        (idxvar)++;                                 \
  |  |  109|  5.22k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  427|       |
  428|  5.22k|    mp_notify(mpctx, MP_EVENT_TRACKS_CHANGED, NULL);
  429|       |
  430|  5.22k|    return track;
  431|  10.4k|}
loadfile.c:find_new_tid:
  386|  5.22k|{
  387|  5.22k|    int new_id = 0;
  388|  6.11k|    for (int i = 0; i < mpctx->num_tracks; i++) {
  ------------------
  |  Branch (388:21): [True: 894, False: 5.22k]
  ------------------
  389|    894|        struct track *track = mpctx->tracks[i];
  390|    894|        if (track->type == t)
  ------------------
  |  Branch (390:13): [True: 0, False: 894]
  ------------------
  391|      0|            new_id = MPMAX(new_id, track->user_tid);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  392|    894|    }
  393|  5.22k|    return new_id + 1;
  394|  5.22k|}
loadfile.c:process_langs:
  550|  13.6k|{
  551|  13.6k|    size_t nb = 0;
  552|  13.6k|    char **out = NULL;
  553|  13.6k|    for (int i = 0; in && in[i]; i++) {
  ------------------
  |  Branch (553:21): [True: 0, False: 13.6k]
  |  Branch (553:27): [True: 0, False: 0]
  ------------------
  554|      0|        if (!append_lang(&nb, &out, talloc_strdup(NULL, in[i])))
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  |  Branch (554:13): [True: 0, False: 0]
  ------------------
  555|      0|            break;
  556|      0|    }
  557|  13.6k|    return out;
  558|  13.6k|}
loadfile.c:add_os_langs:
  535|  4.53k|{
  536|  4.53k|    size_t nb = 0;
  537|  4.53k|    char **out = NULL;
  538|  4.53k|    char **autos = mp_get_user_langs();
  539|  4.53k|    for (int i = 0; autos && autos[i]; i++) {
  ------------------
  |  Branch (539:21): [True: 4.53k, False: 0]
  |  Branch (539:30): [True: 0, False: 4.53k]
  ------------------
  540|      0|        if (!append_lang(&nb, &out, autos[i]))
  ------------------
  |  Branch (540:13): [True: 0, False: 0]
  ------------------
  541|      0|            goto cleanup;
  542|      0|    }
  543|       |
  544|  4.53k|cleanup:
  545|  4.53k|    talloc_free(autos);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
  546|  4.53k|    return out;
  547|  4.53k|}
loadfile.c:duplicate_track:
  515|  5.22k|{
  516|  5.22k|    for (int i = 0; i < order; i++) {
  ------------------
  |  Branch (516:21): [True: 0, False: 5.22k]
  ------------------
  517|      0|        if (mpctx->current_track[i][type] == track)
  ------------------
  |  Branch (517:13): [True: 0, False: 0]
  ------------------
  518|      0|            return true;
  519|      0|    }
  520|  5.22k|    return false;
  521|  5.22k|}
loadfile.c:track_layout_hash:
  627|  1.07k|{
  628|  1.07k|    char *h = talloc_strdup(NULL, "");
  ------------------
  |  |   50|  1.07k|#define talloc_strdup                   ta_xstrdup
  ------------------
  629|  4.29k|    for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
  ------------------
  |  Branch (629:24): [True: 3.21k, False: 1.07k]
  ------------------
  630|  6.52k|        for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (630:25): [True: 3.30k, False: 3.21k]
  ------------------
  631|  3.30k|            struct track *track = mpctx->tracks[n];
  632|  3.30k|            if (track->type != type)
  ------------------
  |  Branch (632:17): [True: 2.20k, False: 1.10k]
  ------------------
  633|  2.20k|                continue;
  634|  1.10k|            h = talloc_asprintf_append_buffer(h, "%d-%d-%d-%d-%s\n", type,
  ------------------
  |  |   64|  1.10k|#define talloc_asprintf_append_buffer   ta_talloc_asprintf_append_buffer
  ------------------
  635|  1.10k|                    track->user_tid, track->default_track, track->is_external,
  636|  1.10k|                    track->lang ? track->lang : "");
  ------------------
  |  Branch (636:21): [True: 0, False: 1.10k]
  ------------------
  637|  1.10k|        }
  638|  3.21k|    }
  639|  1.07k|    return h;
  640|  1.07k|}
loadfile.c:enable_demux_thread:
  378|  4.53k|{
  379|  4.53k|    if (mpctx->opts->demuxer_thread && !demux->fully_read) {
  ------------------
  |  Branch (379:9): [True: 4.53k, False: 0]
  |  Branch (379:40): [True: 4.11k, False: 420]
  ------------------
  380|  4.11k|        demux_set_wakeup_cb(demux, wakeup_demux, mpctx);
  381|  4.11k|        demux_start_thread(demux);
  382|  4.11k|    }
  383|  4.53k|}
loadfile.c:wakeup_demux:
   66|  12.7k|{
   67|  12.7k|    struct MPContext *mpctx = pctx;
   68|  12.7k|    mp_wakeup_core(mpctx);
   69|  12.7k|}
loadfile.c:start_open:
 1189|  7.51k|{
 1190|  7.51k|    cancel_open(mpctx);
 1191|       |
 1192|  7.51k|    mp_assert(!mpctx->open_active);
  ------------------
  |  |   41|  7.51k|#define mp_assert assert
  ------------------
 1193|  7.51k|    mp_assert(!mpctx->open_cancel);
  ------------------
  |  |   41|  7.51k|#define mp_assert assert
  ------------------
 1194|  7.51k|    mp_assert(!mpctx->open_res_demuxer);
  ------------------
  |  |   41|  7.51k|#define mp_assert assert
  ------------------
 1195|  7.51k|    mp_assert(!atomic_load(&mpctx->open_done));
  ------------------
  |  |   41|  7.51k|#define mp_assert assert
  ------------------
 1196|       |
 1197|  7.51k|    mpctx->open_cancel = mp_cancel_new(NULL);
 1198|  7.51k|    mpctx->open_url = talloc_strdup(NULL, url);
  ------------------
  |  |   50|  7.51k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1199|  7.51k|    mpctx->open_format = talloc_strdup(NULL, mpctx->opts->demuxer_name);
  ------------------
  |  |   50|  7.51k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1200|  7.51k|    mpctx->open_url_flags = url_flags;
 1201|  7.51k|    mpctx->open_for_prefetch = for_prefetch && mpctx->opts->demuxer_thread;
  ------------------
  |  Branch (1201:32): [True: 232, False: 7.28k]
  |  Branch (1201:48): [True: 232, False: 0]
  ------------------
 1202|  7.51k|    mpctx->demuxer_changed = false;
 1203|       |
 1204|  7.51k|    if (mp_thread_create(&mpctx->open_thread, open_demux_thread, mpctx)) {
  ------------------
  |  |  211|  7.51k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 7.51k]
  |  |  ------------------
  ------------------
 1205|      0|        cancel_open(mpctx);
 1206|      0|        return;
 1207|      0|    }
 1208|       |
 1209|  7.51k|    mpctx->open_active = true;
 1210|  7.51k|}
loadfile.c:open_demux_thread:
 1120|  7.51k|{
 1121|  7.51k|    struct MPContext *mpctx = ctx;
 1122|       |
 1123|  7.51k|    mp_thread_set_name("opener");
 1124|       |
 1125|  7.51k|    struct demuxer_params p = {
 1126|  7.51k|        .force_format = mpctx->open_format,
 1127|  7.51k|        .stream_flags = mpctx->open_url_flags,
 1128|  7.51k|        .stream_record = true,
 1129|  7.51k|        .is_top_level = true,
 1130|  7.51k|        .allow_playlist_create = mpctx->playlist->num_entries <= 1 &&
  ------------------
  |  Branch (1130:34): [True: 5.81k, False: 1.70k]
  ------------------
 1131|  7.51k|                                 !mpctx->playlist->playlist_dir,
  ------------------
  |  Branch (1131:34): [True: 5.81k, False: 0]
  ------------------
 1132|  7.51k|    };
 1133|  7.51k|    struct demuxer *demux =
 1134|  7.51k|        demux_open_url(mpctx->open_url, &p, mpctx->open_cancel, mpctx->global);
 1135|  7.51k|    mpctx->open_res_demuxer = demux;
 1136|       |
 1137|  7.51k|    if (demux) {
  ------------------
  |  Branch (1137:9): [True: 5.09k, False: 2.42k]
  ------------------
 1138|  5.09k|        MP_VERBOSE(mpctx, "Opening done: %s\n", mpctx->open_url);
  ------------------
  |  |   88|  5.09k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.09k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1139|       |
 1140|  5.09k|        if (mpctx->open_for_prefetch && !demux->fully_read) {
  ------------------
  |  Branch (1140:13): [True: 138, False: 4.95k]
  |  Branch (1140:41): [True: 138, False: 0]
  ------------------
 1141|    138|            int num_streams = demux_get_num_stream(demux);
 1142|    362|            for (int n = 0; n < num_streams; n++) {
  ------------------
  |  Branch (1142:29): [True: 224, False: 138]
  ------------------
 1143|    224|                struct sh_stream *sh = demux_get_stream(demux, n);
 1144|    224|                demuxer_select_track(demux, sh, MP_NOPTS_VALUE, true);
  ------------------
  |  |   38|    224|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 1145|    224|            }
 1146|       |
 1147|    138|            demux_set_wakeup_cb(demux, wakeup_demux, mpctx);
 1148|    138|            demux_start_thread(demux);
 1149|    138|            demux_start_prefetch(demux);
 1150|    138|        }
 1151|  5.09k|    } else {
 1152|  2.42k|        MP_VERBOSE(mpctx, "Opening failed or was aborted: %s\n", mpctx->open_url);
  ------------------
  |  |   88|  2.42k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.42k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1153|       |
 1154|  2.42k|        if (p.demuxer_failed) {
  ------------------
  |  Branch (1154:13): [True: 1.81k, False: 613]
  ------------------
 1155|  1.81k|            mpctx->open_res_error = MPV_ERROR_UNKNOWN_FORMAT;
 1156|  1.81k|        } else {
 1157|    613|            mpctx->open_res_error = MPV_ERROR_LOADING_FAILED;
 1158|    613|        }
 1159|  2.42k|    }
 1160|       |
 1161|  7.51k|    atomic_store(&mpctx->open_done, true);
 1162|  7.51k|    mp_wakeup_core(mpctx);
 1163|  7.51k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  7.51k|#define MP_THREAD_RETURN() return NULL
  ------------------
 1164|  7.51k|}
loadfile.c:reinit_complex_filters:
 1360|  99.2k|{
 1361|  99.2k|    char *graph = mpctx->opts->lavfi_complex;
 1362|  99.2k|    bool have_graph = graph && graph[0] && !force_uninit;
  ------------------
  |  Branch (1362:23): [True: 0, False: 99.2k]
  |  Branch (1362:32): [True: 0, False: 0]
  |  Branch (1362:44): [True: 0, False: 0]
  ------------------
 1363|  99.2k|    if (have_graph && mpctx->lavfi &&
  ------------------
  |  Branch (1363:9): [True: 0, False: 99.2k]
  |  Branch (1363:23): [True: 0, False: 0]
  ------------------
 1364|  99.2k|        strcmp(graph, mpctx->lavfi_graph) == 0 &&
  ------------------
  |  Branch (1364:9): [True: 0, False: 0]
  ------------------
 1365|  99.2k|        !mp_filter_has_failed(mpctx->lavfi))
  ------------------
  |  Branch (1365:9): [True: 0, False: 0]
  ------------------
 1366|      0|        return 0;
 1367|  99.2k|    if (!mpctx->lavfi && !have_graph)
  ------------------
  |  Branch (1367:9): [True: 99.2k, False: 0]
  |  Branch (1367:26): [True: 99.2k, False: 0]
  ------------------
 1368|  99.2k|        return 0;
 1369|       |
 1370|       |    // Deassociate the old filter pads. We leave both sources (tracks) and
 1371|       |    // sinks (AO/VO) "dangling", connected to neither track or filter pad.
 1372|       |    // Later, we either reassociate them with new pads, or uninit them if
 1373|       |    // they are still dangling. This avoids too interruptive actions like
 1374|       |    // recreating the VO.
 1375|      0|    deassociate_complex_filters(mpctx);
 1376|       |
 1377|      0|    bool success = false;
 1378|      0|    if (!have_graph) {
  ------------------
  |  Branch (1378:9): [True: 0, False: 0]
  ------------------
 1379|      0|        success = true; // normal full removal of graph
 1380|      0|        goto done;
 1381|      0|    }
 1382|       |
 1383|      0|    struct mp_lavfi *l =
 1384|      0|        mp_lavfi_create_graph(mpctx->filter_root, 0, false, NULL, NULL, graph);
 1385|      0|    if (!l)
  ------------------
  |  Branch (1385:9): [True: 0, False: 0]
  ------------------
 1386|      0|        goto done;
 1387|      0|    mpctx->lavfi = l->f;
 1388|      0|    mpctx->lavfi_graph = talloc_strdup(NULL, graph);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
 1389|       |
 1390|      0|    mp_filter_set_error_handler(mpctx->lavfi, mpctx->filter_root);
 1391|       |
 1392|      0|    for (int n = 0; n < mpctx->lavfi->num_pins; n++)
  ------------------
  |  Branch (1392:21): [True: 0, False: 0]
  ------------------
 1393|      0|        mp_pin_disconnect(mpctx->lavfi->pins[n]);
 1394|       |
 1395|      0|    struct mp_pin *pad = mp_filter_get_named_pin(mpctx->lavfi, "vo");
 1396|      0|    if (pad && mp_pin_get_dir(pad) == MP_PIN_OUT) {
  ------------------
  |  Branch (1396:9): [True: 0, False: 0]
  |  Branch (1396:16): [True: 0, False: 0]
  ------------------
 1397|      0|        if (mpctx->vo_chain && mpctx->vo_chain->track)
  ------------------
  |  Branch (1397:13): [True: 0, False: 0]
  |  Branch (1397:32): [True: 0, False: 0]
  ------------------
 1398|      0|            kill_outputs(mpctx, mpctx->vo_chain->track);
 1399|      0|        if (!mpctx->vo_chain) {
  ------------------
  |  Branch (1399:13): [True: 0, False: 0]
  ------------------
 1400|      0|            reinit_video_chain_src(mpctx, NULL);
 1401|      0|            if (!mpctx->vo_chain)
  ------------------
  |  Branch (1401:17): [True: 0, False: 0]
  ------------------
 1402|      0|                goto done;
 1403|      0|        }
 1404|      0|        struct vo_chain *vo_c = mpctx->vo_chain;
 1405|      0|        mp_assert(!vo_c->track);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1406|      0|        vo_c->filter_src = pad;
 1407|      0|        mp_pin_connect(vo_c->filter->f->pins[0], vo_c->filter_src);
 1408|      0|    }
 1409|       |
 1410|      0|    pad = mp_filter_get_named_pin(mpctx->lavfi, "ao");
 1411|      0|    if (pad && mp_pin_get_dir(pad) == MP_PIN_OUT) {
  ------------------
  |  Branch (1411:9): [True: 0, False: 0]
  |  Branch (1411:16): [True: 0, False: 0]
  ------------------
 1412|      0|        if (mpctx->ao_chain && mpctx->ao_chain->track)
  ------------------
  |  Branch (1412:13): [True: 0, False: 0]
  |  Branch (1412:32): [True: 0, False: 0]
  ------------------
 1413|      0|            kill_outputs(mpctx, mpctx->ao_chain->track);
 1414|      0|        if (!mpctx->ao_chain) {
  ------------------
  |  Branch (1414:13): [True: 0, False: 0]
  ------------------
 1415|      0|            reinit_audio_chain_src(mpctx, NULL);
 1416|      0|            if (!mpctx->ao_chain)
  ------------------
  |  Branch (1416:17): [True: 0, False: 0]
  ------------------
 1417|      0|                goto done;
 1418|      0|        }
 1419|      0|        struct ao_chain *ao_c = mpctx->ao_chain;
 1420|      0|        mp_assert(!ao_c->track);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1421|      0|        ao_c->filter_src = pad;
 1422|      0|        mp_pin_connect(ao_c->filter->f->pins[0], ao_c->filter_src);
 1423|      0|    }
 1424|       |
 1425|      0|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (1425:21): [True: 0, False: 0]
  ------------------
 1426|      0|        struct track *track = mpctx->tracks[n];
 1427|       |
 1428|      0|        char label[32];
 1429|      0|        char prefix;
 1430|      0|        switch (track->type) {
 1431|      0|        case STREAM_VIDEO: prefix = 'v'; break;
  ------------------
  |  Branch (1431:9): [True: 0, False: 0]
  ------------------
 1432|      0|        case STREAM_AUDIO: prefix = 'a'; break;
  ------------------
  |  Branch (1432:9): [True: 0, False: 0]
  ------------------
 1433|      0|        default: continue;
  ------------------
  |  Branch (1433:9): [True: 0, False: 0]
  ------------------
 1434|      0|        }
 1435|      0|        snprintf(label, sizeof(label), "%cid%d", prefix, track->user_tid);
 1436|       |
 1437|      0|        pad = mp_filter_get_named_pin(mpctx->lavfi, label);
 1438|      0|        if (!pad)
  ------------------
  |  Branch (1438:13): [True: 0, False: 0]
  ------------------
 1439|      0|            continue;
 1440|      0|        if (mp_pin_get_dir(pad) != MP_PIN_IN)
  ------------------
  |  Branch (1440:13): [True: 0, False: 0]
  ------------------
 1441|      0|            continue;
 1442|      0|        mp_assert(!mp_pin_is_connected(pad));
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1443|       |
 1444|      0|        mp_assert(!track->sink);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
 1445|       |
 1446|      0|        kill_outputs(mpctx, track);
 1447|       |
 1448|      0|        track->sink = pad;
 1449|      0|        track->selected = true;
 1450|       |
 1451|      0|        if (!track->dec) {
  ------------------
  |  Branch (1451:13): [True: 0, False: 0]
  ------------------
 1452|      0|            if (track->type == STREAM_VIDEO && !init_video_decoder(mpctx, track))
  ------------------
  |  Branch (1452:17): [True: 0, False: 0]
  |  Branch (1452:48): [True: 0, False: 0]
  ------------------
 1453|      0|                goto done;
 1454|      0|            if (track->type == STREAM_AUDIO && !init_audio_decoder(mpctx, track))
  ------------------
  |  Branch (1454:17): [True: 0, False: 0]
  |  Branch (1454:48): [True: 0, False: 0]
  ------------------
 1455|      0|                goto done;
 1456|      0|        }
 1457|       |
 1458|      0|        mp_pin_connect(track->sink, track->dec->f->pins[0]);
 1459|      0|    }
 1460|       |
 1461|       |    // Don't allow unconnected pins. Libavfilter would make the data flow a
 1462|       |    // real pain anyway.
 1463|      0|    for (int n = 0; n < mpctx->lavfi->num_pins; n++) {
  ------------------
  |  Branch (1463:21): [True: 0, False: 0]
  ------------------
 1464|      0|        struct mp_pin *pin = mpctx->lavfi->pins[n];
 1465|      0|        if (!mp_pin_is_connected(pin)) {
  ------------------
  |  Branch (1465:13): [True: 0, False: 0]
  ------------------
 1466|      0|            MP_ERR(mpctx, "Pad %s is not connected to anything.\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1467|      0|                   mp_pin_get_name(pin));
 1468|      0|            goto done;
 1469|      0|        }
 1470|      0|    }
 1471|       |
 1472|      0|    success = true;
 1473|      0|done:
 1474|       |
 1475|      0|    if (!success)
  ------------------
  |  Branch (1475:9): [True: 0, False: 0]
  ------------------
 1476|      0|        deassociate_complex_filters(mpctx);
 1477|       |
 1478|      0|    cleanup_deassociated_complex_filters(mpctx);
 1479|       |
 1480|      0|    if (mpctx->playback_initialized) {
  ------------------
  |  Branch (1480:9): [True: 0, False: 0]
  ------------------
 1481|      0|        for (int n = 0; n < mpctx->num_tracks; n++)
  ------------------
  |  Branch (1481:25): [True: 0, False: 0]
  ------------------
 1482|      0|            reselect_demux_stream(mpctx, mpctx->tracks[n], false);
 1483|      0|    }
 1484|       |
 1485|      0|    mp_notify(mpctx, MP_EVENT_TRACKS_CHANGED, NULL);
 1486|       |
 1487|      0|    return success ? 1 : -1;
  ------------------
  |  Branch (1487:12): [True: 0, False: 0]
  ------------------
 1488|      0|}
loadfile.c:play_current_file:
 1627|  94.7k|{
 1628|  94.7k|    struct MPOpts *opts = mpctx->opts;
 1629|       |
 1630|  94.7k|    mp_assert(mpctx->stop_play);
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
 1631|  94.7k|    mpctx->stop_play = 0;
 1632|       |
 1633|  94.7k|    process_hooks(mpctx, "on_before_start_file");
 1634|  94.7k|    if (mpctx->stop_play || !mpctx->playlist->current)
  ------------------
  |  Branch (1634:9): [True: 0, False: 94.7k]
  |  Branch (1634:29): [True: 0, False: 94.7k]
  ------------------
 1635|      0|        return;
 1636|       |
 1637|  94.7k|    mpv_event_start_file start_event = {
 1638|  94.7k|        .playlist_entry_id = mpctx->playlist->current->id,
 1639|  94.7k|    };
 1640|  94.7k|    mpv_event_end_file end_event = {
 1641|  94.7k|        .playlist_entry_id = start_event.playlist_entry_id,
 1642|  94.7k|    };
 1643|       |
 1644|  94.7k|    mp_notify(mpctx, MPV_EVENT_START_FILE, &start_event);
 1645|       |
 1646|  94.7k|    mp_cancel_reset(mpctx->playback_abort);
 1647|       |
 1648|  94.7k|    mpctx->error_playing = MPV_ERROR_LOADING_FAILED;
 1649|  94.7k|    mpctx->filename = NULL;
 1650|  94.7k|    mpctx->shown_aframes = 0;
 1651|  94.7k|    mpctx->shown_vframes = 0;
 1652|  94.7k|    mpctx->last_chapter_seek = -2;
 1653|  94.7k|    mpctx->last_chapter_flag = false;
 1654|  94.7k|    mpctx->last_chapter = -2;
 1655|  94.7k|    mpctx->paused = false;
 1656|  94.7k|    mpctx->playing_msg_shown = false;
 1657|  94.7k|    mpctx->max_frames = -1;
 1658|  94.7k|    mpctx->video_speed = mpctx->audio_speed = opts->playback_speed;
 1659|  94.7k|    mpctx->speed_factor_a = mpctx->speed_factor_v = 1.0;
 1660|  94.7k|    mpctx->display_sync_error = 0.0;
 1661|  94.7k|    mpctx->display_sync_active = false;
 1662|       |    // let get_current_time() show 0 as start time (before playback_pts is set)
 1663|  94.7k|    mpctx->last_seek_pts = 0.0;
 1664|  94.7k|    mpctx->seek = (struct seek_params){ 0 };
 1665|  94.7k|    mpctx->filter_root = mp_filter_create_root(mpctx->global);
 1666|  94.7k|    mp_filter_graph_set_wakeup_cb(mpctx->filter_root, mp_wakeup_core_cb, mpctx);
 1667|  94.7k|    mp_filter_graph_set_max_run_time(mpctx->filter_root, 0.1);
 1668|       |
 1669|  94.7k|    reset_playback_state(mpctx);
 1670|       |
 1671|  94.7k|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 1672|  94.7k|    if (mpctx->playlist->num_entries > 10)
  ------------------
  |  Branch (1672:9): [True: 87.2k, False: 7.46k]
  ------------------
 1673|  87.2k|        goto terminate_playback;
 1674|  7.46k|#endif
 1675|       |
 1676|  7.46k|    mpctx->playing = mpctx->playlist->current;
 1677|  7.46k|    mp_assert(mpctx->playing);
  ------------------
  |  |   41|  7.46k|#define mp_assert assert
  ------------------
 1678|  7.46k|    mp_assert(mpctx->playing->filename);
  ------------------
  |  |   41|  7.46k|#define mp_assert assert
  ------------------
 1679|  7.46k|    mpctx->playing->reserved += 1;
 1680|       |
 1681|  7.46k|    mpctx->filename = talloc_strdup(NULL, mpctx->playing->filename);
  ------------------
  |  |   50|  7.46k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1682|  7.46k|    mpctx->stream_open_filename = mpctx->filename;
 1683|       |
 1684|  7.46k|    mpctx->add_osd_seek_info &= OSD_SEEK_INFO_CURRENT_FILE;
 1685|       |
 1686|  7.46k|    if (opts->reset_options) {
  ------------------
  |  Branch (1686:9): [True: 0, False: 7.46k]
  ------------------
 1687|      0|        for (int n = 0; opts->reset_options[n]; n++) {
  ------------------
  |  Branch (1687:25): [True: 0, False: 0]
  ------------------
 1688|      0|            const char *opt = opts->reset_options[n];
 1689|      0|            if (opt[0]) {
  ------------------
  |  Branch (1689:17): [True: 0, False: 0]
  ------------------
 1690|      0|                if (strcmp(opt, "all") == 0) {
  ------------------
  |  Branch (1690:21): [True: 0, False: 0]
  ------------------
 1691|      0|                    m_config_backup_all_opts(mpctx->mconfig);
 1692|      0|                } else {
 1693|      0|                    m_config_backup_opt(mpctx->mconfig, opt);
 1694|      0|                }
 1695|      0|            }
 1696|      0|        }
 1697|      0|    }
 1698|       |
 1699|  7.46k|    mp_load_auto_profiles(mpctx);
 1700|       |
 1701|  7.46k|    bool watch_later = mp_load_playback_resume(mpctx, mpctx->filename);
 1702|       |
 1703|  7.46k|    load_per_file_options(mpctx->mconfig, mpctx->playing->params,
 1704|  7.46k|                          mpctx->playing->num_params);
 1705|       |
 1706|  7.46k|    mpctx->remaining_file_loops = mpctx->opts->loop_file;
 1707|  7.46k|    mp_notify_property(mpctx, "remaining-file-loops");
 1708|  7.46k|    mpctx->remaining_ab_loops = mpctx->opts->ab_loop_count;
 1709|  7.46k|    mp_notify_property(mpctx, "remaining-ab-loops");
 1710|       |
 1711|  7.46k|    mpctx->max_frames = opts->play_frames;
 1712|       |
 1713|  7.46k|    handle_force_window(mpctx, false);
 1714|       |
 1715|  7.46k|    if (mpctx->playlist->num_entries > 1 ||
  ------------------
  |  Branch (1715:9): [True: 1.65k, False: 5.81k]
  ------------------
 1716|  7.46k|        mpctx->playing->playlist_path)
  ------------------
  |  Branch (1716:9): [True: 0, False: 5.81k]
  ------------------
 1717|  7.46k|        MP_INFO(mpctx, "Playing: %s\n", mpctx->filename);
  ------------------
  |  |   87|  1.65k|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.65k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1718|       |
 1719|  7.46k|    mp_assert(mpctx->demuxer == NULL);
  ------------------
  |  |   41|  7.46k|#define mp_assert assert
  ------------------
 1720|       |
 1721|  7.46k|    process_hooks(mpctx, "on_load");
 1722|  7.46k|    if (mpctx->stop_play)
  ------------------
  |  Branch (1722:9): [True: 0, False: 7.46k]
  ------------------
 1723|      0|        goto terminate_playback;
 1724|       |
 1725|  7.46k|    if (opts->stream_dump && opts->stream_dump[0]) {
  ------------------
  |  Branch (1725:9): [True: 0, False: 7.46k]
  |  Branch (1725:30): [True: 0, False: 0]
  ------------------
 1726|      0|        if (stream_dump(mpctx, mpctx->stream_open_filename) >= 0)
  ------------------
  |  Branch (1726:13): [True: 0, False: 0]
  ------------------
 1727|      0|            mpctx->error_playing = 1;
 1728|      0|        goto terminate_playback;
 1729|      0|    }
 1730|       |
 1731|  7.46k|    open_demux_reentrant(mpctx);
 1732|  7.46k|    if (!mpctx->stop_play && !mpctx->demuxer) {
  ------------------
  |  Branch (1732:9): [True: 7.46k, False: 0]
  |  Branch (1732:30): [True: 2.37k, False: 5.09k]
  ------------------
 1733|  2.37k|        process_hooks(mpctx, "on_load_fail");
 1734|  2.37k|        if (strcmp(mpctx->stream_open_filename, mpctx->filename) != 0 &&
  ------------------
  |  Branch (1734:13): [True: 0, False: 2.37k]
  ------------------
 1735|  2.37k|            !mpctx->stop_play)
  ------------------
  |  Branch (1735:13): [True: 0, False: 0]
  ------------------
 1736|      0|        {
 1737|      0|            mpctx->error_playing = MPV_ERROR_LOADING_FAILED;
 1738|      0|            open_demux_reentrant(mpctx);
 1739|      0|        }
 1740|  2.37k|    }
 1741|  7.46k|    if (!mpctx->demuxer || mpctx->stop_play)
  ------------------
  |  Branch (1741:9): [True: 2.37k, False: 5.09k]
  |  Branch (1741:28): [True: 0, False: 5.09k]
  ------------------
 1742|  2.37k|        goto terminate_playback;
 1743|       |
 1744|  5.09k|    struct playlist *pl = mpctx->demuxer->playlist;
 1745|  5.09k|    if (pl) {
  ------------------
  |  Branch (1745:9): [True: 557, False: 4.53k]
  ------------------
 1746|       |        // pl->playlist_dir indicates that the playlist was auto-created from
 1747|       |        // the parent file. In this case, mpctx->filename points to real file.
 1748|    557|        if (watch_later && !pl->playlist_dir)
  ------------------
  |  Branch (1748:13): [True: 0, False: 557]
  |  Branch (1748:28): [True: 0, False: 0]
  ------------------
 1749|      0|            mp_delete_watch_later_conf(mpctx, mpctx->filename);
 1750|    557|        playlist_populate_playlist_path(pl, mpctx->filename);
 1751|    557|        if (infinite_playlist_loading_loop(mpctx, pl)) {
  ------------------
  |  Branch (1751:13): [True: 0, False: 557]
  ------------------
 1752|      0|            mpctx->stop_play = PT_STOP;
 1753|      0|            MP_ERR(mpctx, "Infinite playlist loading loop detected.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1754|      0|            goto terminate_playback;
 1755|      0|        }
 1756|    557|        transfer_playlist(mpctx, pl, &end_event.playlist_insert_id,
 1757|    557|                          &end_event.playlist_insert_num_entries);
 1758|    557|        mp_notify_property(mpctx, "playlist");
 1759|    557|        mpctx->error_playing = 2;
 1760|    557|        goto terminate_playback;
 1761|    557|    }
 1762|       |
 1763|  4.53k|    if (mpctx->opts->rebase_start_time)
  ------------------
  |  Branch (1763:9): [True: 4.53k, False: 0]
  ------------------
 1764|  4.53k|        demux_set_ts_offset(mpctx->demuxer, -mpctx->demuxer->start_time);
 1765|  4.53k|    enable_demux_thread(mpctx, mpctx->demuxer);
 1766|       |
 1767|  4.53k|    add_demuxer_tracks(mpctx, mpctx->demuxer);
 1768|       |
 1769|  4.53k|    load_external_opts(mpctx);
 1770|  4.53k|    if (mpctx->stop_play)
  ------------------
  |  Branch (1770:9): [True: 0, False: 4.53k]
  ------------------
 1771|      0|        goto terminate_playback;
 1772|       |
 1773|  4.53k|    check_previous_track_selection(mpctx);
 1774|       |
 1775|  4.53k|    process_hooks(mpctx, "on_preloaded");
 1776|  4.53k|    if (mpctx->stop_play)
  ------------------
  |  Branch (1776:9): [True: 0, False: 4.53k]
  ------------------
 1777|      0|        goto terminate_playback;
 1778|       |
 1779|  4.53k|    if (reinit_complex_filters(mpctx, false) < 0)
  ------------------
  |  Branch (1779:9): [True: 0, False: 4.53k]
  ------------------
 1780|      0|        goto terminate_playback;
 1781|       |
 1782|  18.1k|    for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
  ------------------
  |  Branch (1782:21): [True: 13.6k, False: 4.53k]
  ------------------
 1783|  31.7k|        for (int i = 0; i < num_ptracks[t]; i++) {
  ------------------
  |  Branch (1783:25): [True: 18.1k, False: 13.6k]
  ------------------
 1784|  18.1k|            struct track *sel = NULL;
 1785|  18.1k|            bool taken = (t == STREAM_VIDEO && mpctx->vo_chain) ||
  ------------------
  |  Branch (1785:27): [True: 4.53k, False: 13.6k]
  |  Branch (1785:48): [True: 0, False: 4.53k]
  ------------------
 1786|  18.1k|                         (t == STREAM_AUDIO && mpctx->ao_chain);
  ------------------
  |  Branch (1786:27): [True: 4.53k, False: 13.6k]
  |  Branch (1786:48): [True: 0, False: 4.53k]
  ------------------
 1787|  18.1k|            if (!taken && opts->stream_auto_sel)
  ------------------
  |  Branch (1787:17): [True: 18.1k, False: 0]
  |  Branch (1787:27): [True: 18.1k, False: 0]
  ------------------
 1788|  18.1k|                sel = select_default_track(mpctx, i, t);
 1789|  18.1k|            mpctx->current_track[i][t] = sel;
 1790|  18.1k|        }
 1791|  13.6k|    }
 1792|  18.1k|    for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
  ------------------
  |  Branch (1792:21): [True: 13.6k, False: 4.53k]
  ------------------
 1793|  31.7k|        for (int i = 0; i < num_ptracks[t]; i++) {
  ------------------
  |  Branch (1793:25): [True: 18.1k, False: 13.6k]
  ------------------
 1794|       |            // One track can strictly feed at most 1 decoder
 1795|  18.1k|            struct track *track = mpctx->current_track[i][t];
 1796|  18.1k|            if (track) {
  ------------------
  |  Branch (1796:17): [True: 4.88k, False: 13.2k]
  ------------------
 1797|  4.88k|                if (track->type != STREAM_SUB &&
  ------------------
  |  Branch (1797:21): [True: 4.88k, False: 0]
  ------------------
 1798|  4.88k|                    mpctx->encode_lavc_ctx &&
  ------------------
  |  Branch (1798:21): [True: 0, False: 4.88k]
  ------------------
 1799|  4.88k|                    !encode_lavc_stream_type_ok(mpctx->encode_lavc_ctx,
  ------------------
  |  Branch (1799:21): [True: 0, False: 0]
  ------------------
 1800|      0|                                                track->type))
 1801|      0|                {
 1802|      0|                    MP_WARN(mpctx, "Disabling %s (not supported by target "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1803|      0|                            "format).\n", stream_type_name(track->type));
 1804|      0|                    mpctx->current_track[i][t] = NULL;
 1805|      0|                    mark_track_selection(mpctx, i, t, -2); // disable
 1806|  4.88k|                } else if (track->selected) {
  ------------------
  |  Branch (1806:28): [True: 0, False: 4.88k]
  ------------------
 1807|      0|                    MP_ERR(mpctx, "Track %d can't be selected twice.\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1808|      0|                           track->user_tid);
 1809|      0|                    mpctx->current_track[i][t] = NULL;
 1810|      0|                    mark_track_selection(mpctx, i, t, -2); // disable
 1811|  4.88k|                } else {
 1812|  4.88k|                    track->selected = true;
 1813|  4.88k|                }
 1814|  4.88k|            }
 1815|       |
 1816|       |            // Revert selection of unselected tracks to default. This is needed
 1817|       |            // because track properties have inconsistent behavior.
 1818|  18.1k|            if (!track && opts->stream_id[i][t] >= 0)
  ------------------
  |  Branch (1818:17): [True: 13.2k, False: 4.88k]
  |  Branch (1818:27): [True: 0, False: 13.2k]
  ------------------
 1819|      0|                mark_track_selection(mpctx, i, t, -1); // default
 1820|  18.1k|        }
 1821|  13.6k|    }
 1822|       |
 1823|  18.1k|    for (int t = 0; t < STREAM_TYPE_COUNT; t++)
  ------------------
  |  Branch (1823:21): [True: 13.6k, False: 4.53k]
  ------------------
 1824|  29.2k|        for (int n = 0; n < mpctx->num_tracks; n++)
  ------------------
  |  Branch (1824:25): [True: 15.6k, False: 13.6k]
  ------------------
 1825|  15.6k|            if (mpctx->tracks[n]->type == t)
  ------------------
  |  Branch (1825:17): [True: 5.22k, False: 10.4k]
  ------------------
 1826|  5.22k|                reselect_demux_stream(mpctx, mpctx->tracks[n], false);
 1827|       |
 1828|  4.53k|    update_demuxer_properties(mpctx);
 1829|       |
 1830|  4.53k|    update_playback_speed(mpctx);
 1831|       |
 1832|  4.53k|    reinit_video_chain(mpctx);
 1833|  4.53k|    reinit_audio_chain(mpctx);
 1834|  4.53k|    reinit_sub_all(mpctx);
 1835|       |
 1836|  4.53k|    if (mpctx->encode_lavc_ctx) {
  ------------------
  |  Branch (1836:9): [True: 0, False: 4.53k]
  ------------------
 1837|      0|        if (mpctx->vo_chain)
  ------------------
  |  Branch (1837:13): [True: 0, False: 0]
  ------------------
 1838|      0|            encode_lavc_expect_stream(mpctx->encode_lavc_ctx, STREAM_VIDEO);
 1839|      0|        if (mpctx->ao_chain)
  ------------------
  |  Branch (1839:13): [True: 0, False: 0]
  ------------------
 1840|      0|            encode_lavc_expect_stream(mpctx->encode_lavc_ctx, STREAM_AUDIO);
 1841|      0|        encode_lavc_set_metadata(mpctx->encode_lavc_ctx,
 1842|      0|                                 mpctx->demuxer->metadata);
 1843|      0|    }
 1844|       |
 1845|  4.53k|    if (!mpctx->vo_chain && !mpctx->ao_chain && opts->stream_auto_sel) {
  ------------------
  |  Branch (1845:9): [True: 2.51k, False: 2.02k]
  |  Branch (1845:29): [True: 1.57k, False: 932]
  |  Branch (1845:49): [True: 1.57k, False: 0]
  ------------------
 1846|  1.57k|        MP_FATAL(mpctx, "No video or audio streams selected.\n");
  ------------------
  |  |   84|  1.57k|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.57k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1847|  1.57k|        mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
 1848|  1.57k|        goto terminate_playback;
 1849|  1.57k|    }
 1850|       |
 1851|  2.96k|    if (mpctx->vo_chain && mpctx->vo_chain->is_coverart) {
  ------------------
  |  Branch (1851:9): [True: 2.02k, False: 932]
  |  Branch (1851:28): [True: 0, False: 2.02k]
  ------------------
 1852|      0|        MP_INFO(mpctx,
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1853|      0|            "Displaying cover art. Use --no-audio-display to prevent this.\n");
 1854|      0|    }
 1855|       |
 1856|  2.96k|    if (!mpctx->vo_chain)
  ------------------
  |  Branch (1856:9): [True: 932, False: 2.02k]
  ------------------
 1857|    932|        handle_force_window(mpctx, true);
 1858|       |
 1859|  2.96k|    MP_VERBOSE(mpctx, "Starting playback...\n");
  ------------------
  |  |   88|  2.96k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.96k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1860|       |
 1861|  2.96k|    mpctx->playback_initialized = true;
 1862|  2.96k|    mpctx->playing->playlist_prev_attempt = false;
 1863|  2.96k|    mpctx->playlist->playlist_completed = false;
 1864|  2.96k|    mpctx->playlist->playlist_started = true;
 1865|  2.96k|    mp_notify(mpctx, MPV_EVENT_FILE_LOADED, NULL);
 1866|  2.96k|    update_screensaver_state(mpctx);
 1867|  2.96k|    clear_playlist_paths(mpctx);
 1868|       |
 1869|       |    // Clear out subs from the previous file if the video track is a still image.
 1870|  2.96k|    redraw_subs(mpctx);
 1871|       |
 1872|  2.96k|    if (watch_later)
  ------------------
  |  Branch (1872:9): [True: 0, False: 2.96k]
  ------------------
 1873|      0|        mp_delete_watch_later_conf(mpctx, mpctx->filename);
 1874|       |
 1875|  2.96k|    append_to_watch_history(mpctx);
 1876|       |
 1877|  2.96k|    if (mpctx->max_frames == 0) {
  ------------------
  |  Branch (1877:9): [True: 0, False: 2.96k]
  ------------------
 1878|      0|        if (!mpctx->stop_play)
  ------------------
  |  Branch (1878:13): [True: 0, False: 0]
  ------------------
 1879|      0|            mpctx->stop_play = PT_NEXT_ENTRY;
 1880|      0|        mpctx->error_playing = 0;
 1881|      0|        goto terminate_playback;
 1882|      0|    }
 1883|       |
 1884|  2.96k|    if (opts->demuxer_cache_wait) {
  ------------------
  |  Branch (1884:9): [True: 0, False: 2.96k]
  ------------------
 1885|      0|        demux_start_prefetch(mpctx->demuxer);
 1886|       |
 1887|      0|        while (!mpctx->stop_play) {
  ------------------
  |  Branch (1887:16): [True: 0, False: 0]
  ------------------
 1888|      0|            struct demux_reader_state s;
 1889|      0|            demux_get_reader_state(mpctx->demuxer, &s);
 1890|      0|            if (s.idle)
  ------------------
  |  Branch (1890:17): [True: 0, False: 0]
  ------------------
 1891|      0|                break;
 1892|       |
 1893|      0|            mp_idle(mpctx);
 1894|      0|        }
 1895|      0|    }
 1896|       |
 1897|       |    // (Not get_play_start_pts(), which would always trigger a seek.)
 1898|  2.96k|    double play_start_pts = rel_time_to_abs(mpctx, opts->play_start);
 1899|       |
 1900|       |    // Backward playback -> start from end by default.
 1901|  2.96k|    if (play_start_pts == MP_NOPTS_VALUE && opts->play_dir < 0)
  ------------------
  |  |   38|  5.92k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1901:9): [True: 2.96k, False: 0]
  |  Branch (1901:45): [True: 0, False: 2.96k]
  ------------------
 1902|      0|        play_start_pts = get_start_time(mpctx, -1);
 1903|       |
 1904|  2.96k|    if (play_start_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  2.96k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1904:9): [True: 0, False: 2.96k]
  ------------------
 1905|      0|        queue_seek(mpctx, MPSEEK_ABSOLUTE, play_start_pts, MPSEEK_DEFAULT, 0);
 1906|      0|        execute_queued_seek(mpctx);
 1907|      0|    }
 1908|       |
 1909|  2.96k|    update_internal_pause_state(mpctx);
 1910|       |
 1911|  2.96k|    mpctx->error_playing = 0;
 1912|  2.96k|    mpctx->in_playloop = true;
 1913|  96.2k|    while (!mpctx->stop_play)
  ------------------
  |  Branch (1913:12): [True: 93.3k, False: 2.96k]
  ------------------
 1914|  93.3k|        run_playloop(mpctx);
 1915|  2.96k|    mpctx->in_playloop = false;
 1916|       |
 1917|  2.96k|    MP_VERBOSE(mpctx, "EOF code: %d  \n", mpctx->stop_play);
  ------------------
  |  |   88|  2.96k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.96k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1918|       |
 1919|  94.7k|terminate_playback:
 1920|       |
 1921|  94.7k|    if (!mpctx->stop_play)
  ------------------
  |  Branch (1921:9): [True: 90.7k, False: 3.98k]
  ------------------
 1922|  90.7k|        mpctx->stop_play = PT_ERROR;
 1923|       |
 1924|  94.7k|    if (mpctx->stop_play != AT_END_OF_FILE)
  ------------------
  |  Branch (1924:9): [True: 91.7k, False: 2.95k]
  ------------------
 1925|  91.7k|        clear_audio_output_buffers(mpctx);
 1926|       |
 1927|  94.7k|    update_core_idle_state(mpctx);
 1928|       |
 1929|  94.7k|    if (mpctx->step_frames) {
  ------------------
  |  Branch (1929:9): [True: 0, False: 94.7k]
  ------------------
 1930|      0|        opts->pause = true;
 1931|      0|        m_config_notify_change_opt_ptr(mpctx->mconfig, &opts->pause);
 1932|      0|    }
 1933|       |
 1934|  94.7k|    process_hooks(mpctx, "on_unload");
 1935|       |
 1936|       |    // time to uninit all, except global stuff:
 1937|  94.7k|    reinit_complex_filters(mpctx, true);
 1938|  94.7k|    uninit_audio_chain(mpctx);
 1939|  94.7k|    uninit_video_chain(mpctx);
 1940|  94.7k|    uninit_sub_all(mpctx);
 1941|  94.7k|    if (!opts->gapless_audio && !mpctx->encode_lavc_ctx)
  ------------------
  |  Branch (1941:9): [True: 0, False: 94.7k]
  |  Branch (1941:33): [True: 0, False: 0]
  ------------------
 1942|      0|        uninit_audio_out(mpctx);
 1943|       |
 1944|  94.7k|    mpctx->playback_initialized = false;
 1945|       |
 1946|  94.7k|    uninit_demuxer(mpctx);
 1947|       |
 1948|       |    // Possibly stop ongoing async commands.
 1949|  94.7k|    mp_abort_playback_async(mpctx);
 1950|       |
 1951|  94.7k|    m_config_restore_backups(mpctx->mconfig);
 1952|       |
 1953|  94.7k|    TA_FREEP(&mpctx->filter_root);
  ------------------
  |  |   81|  94.7k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  94.7k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1954|  94.7k|    talloc_free(mpctx->filtered_tags);
  ------------------
  |  |   47|  94.7k|#define talloc_free                     ta_free
  ------------------
 1955|  94.7k|    mpctx->filtered_tags = NULL;
 1956|       |
 1957|  94.7k|    mp_notify(mpctx, MP_EVENT_TRACKS_CHANGED, NULL);
 1958|       |
 1959|  94.7k|    if (encode_lavc_didfail(mpctx->encode_lavc_ctx))
  ------------------
  |  Branch (1959:9): [True: 0, False: 94.7k]
  ------------------
 1960|      0|        mpctx->stop_play = PT_ERROR;
 1961|       |
 1962|  94.7k|    if (mpctx->stop_play == PT_ERROR && !mpctx->error_playing)
  ------------------
  |  Branch (1962:9): [True: 91.7k, False: 2.95k]
  |  Branch (1962:41): [True: 0, False: 91.7k]
  ------------------
 1963|      0|        mpctx->error_playing = MPV_ERROR_GENERIC;
 1964|       |
 1965|  94.7k|    bool nothing_played = !mpctx->shown_aframes && !mpctx->shown_vframes &&
  ------------------
  |  Branch (1965:27): [True: 94.0k, False: 732]
  |  Branch (1965:52): [True: 93.4k, False: 561]
  ------------------
 1966|  94.7k|                          mpctx->error_playing <= 0;
  ------------------
  |  Branch (1966:27): [True: 92.9k, False: 557]
  ------------------
 1967|  94.7k|    bool playlist_prev_continue = false;
 1968|  94.7k|    switch (mpctx->stop_play) {
  ------------------
  |  Branch (1968:13): [True: 0, False: 94.7k]
  ------------------
 1969|  91.7k|    case PT_ERROR:
  ------------------
  |  Branch (1969:5): [True: 91.7k, False: 2.95k]
  ------------------
 1970|  94.7k|    case AT_END_OF_FILE:
  ------------------
  |  Branch (1970:5): [True: 2.95k, False: 91.7k]
  ------------------
 1971|  94.7k|    {
 1972|  94.7k|        if (mpctx->error_playing == 0 && nothing_played)
  ------------------
  |  Branch (1972:13): [True: 2.95k, False: 91.7k]
  |  Branch (1972:42): [True: 1.66k, False: 1.29k]
  ------------------
 1973|  1.66k|            mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
 1974|  94.7k|        if (mpctx->error_playing < 0) {
  ------------------
  |  Branch (1974:13): [True: 92.9k, False: 1.85k]
  ------------------
 1975|  92.9k|            end_event.error = mpctx->error_playing;
 1976|  92.9k|            end_event.reason = MPV_END_FILE_REASON_ERROR;
 1977|  92.9k|        } else if (mpctx->error_playing == 2) {
  ------------------
  |  Branch (1977:20): [True: 557, False: 1.29k]
  ------------------
 1978|    557|            end_event.reason = MPV_END_FILE_REASON_REDIRECT;
 1979|  1.29k|        } else {
 1980|  1.29k|            end_event.reason = MPV_END_FILE_REASON_EOF;
 1981|  1.29k|        }
 1982|  94.7k|        if (mpctx->playing) {
  ------------------
  |  Branch (1982:13): [True: 7.46k, False: 87.2k]
  ------------------
 1983|  7.46k|            mpctx->playing->init_failed = nothing_played;
 1984|  7.46k|            playlist_prev_continue = mpctx->playing->playlist_prev_attempt &&
  ------------------
  |  Branch (1984:38): [True: 0, False: 7.46k]
  ------------------
 1985|  7.46k|                                     nothing_played;
  ------------------
  |  Branch (1985:38): [True: 0, False: 0]
  ------------------
 1986|  7.46k|            mpctx->playing->playlist_prev_attempt = false;
 1987|  7.46k|        }
 1988|  94.7k|        break;
 1989|  91.7k|    }
 1990|       |    // Note that error_playing is meaningless in these cases.
 1991|      0|    case PT_NEXT_ENTRY:
  ------------------
  |  Branch (1991:5): [True: 0, False: 94.7k]
  ------------------
 1992|      0|    case PT_CURRENT_ENTRY:
  ------------------
  |  Branch (1992:5): [True: 0, False: 94.7k]
  ------------------
 1993|      0|    case PT_STOP:           end_event.reason = MPV_END_FILE_REASON_STOP; break;
  ------------------
  |  Branch (1993:5): [True: 0, False: 94.7k]
  ------------------
 1994|      0|    case PT_QUIT:           end_event.reason = MPV_END_FILE_REASON_QUIT; break;
  ------------------
  |  Branch (1994:5): [True: 0, False: 94.7k]
  ------------------
 1995|  94.7k|    };
 1996|  94.7k|    mp_notify(mpctx, MPV_EVENT_END_FILE, &end_event);
 1997|       |
 1998|  94.7k|    MP_VERBOSE(mpctx, "finished playback, %s (reason %d)\n",
  ------------------
  |  |   88|  94.7k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  94.7k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1999|  94.7k|               mpv_error_string(end_event.error), end_event.reason);
 2000|  94.7k|    if (end_event.error == MPV_ERROR_UNKNOWN_FORMAT)
  ------------------
  |  Branch (2000:9): [True: 1.80k, False: 92.9k]
  ------------------
 2001|  94.7k|        MP_ERR(mpctx, "Failed to recognize file format.\n");
  ------------------
  |  |   85|  1.80k|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.80k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 2002|       |
 2003|  94.7k|    if (mpctx->playing)
  ------------------
  |  Branch (2003:9): [True: 7.46k, False: 87.2k]
  ------------------
 2004|  7.46k|        playlist_entry_unref(mpctx->playing);
 2005|  94.7k|    mpctx->playing = NULL;
 2006|  94.7k|    talloc_free(mpctx->filename);
  ------------------
  |  |   47|  94.7k|#define talloc_free                     ta_free
  ------------------
 2007|  94.7k|    mpctx->filename = NULL;
 2008|  94.7k|    mpctx->stream_open_filename = NULL;
 2009|       |
 2010|  94.7k|    if (end_event.error < 0 && nothing_played) {
  ------------------
  |  Branch (2010:9): [True: 92.9k, False: 1.85k]
  |  Branch (2010:32): [True: 92.9k, False: 0]
  ------------------
 2011|  92.9k|        mpctx->files_broken++;
 2012|  92.9k|    } else if (end_event.error < 0) {
  ------------------
  |  Branch (2012:16): [True: 0, False: 1.85k]
  ------------------
 2013|      0|        mpctx->files_errored++;
 2014|  1.85k|    } else {
 2015|  1.85k|        mpctx->files_played++;
 2016|  1.85k|    }
 2017|       |
 2018|  94.7k|    mp_assert(mpctx->stop_play);
  ------------------
  |  |   41|  94.7k|#define mp_assert assert
  ------------------
 2019|       |
 2020|  94.7k|    process_hooks(mpctx, "on_after_end_file");
 2021|       |
 2022|  94.7k|    if (playlist_prev_continue) {
  ------------------
  |  Branch (2022:9): [True: 0, False: 94.7k]
  ------------------
 2023|      0|        struct playlist_entry *e = mp_next_file(mpctx, -1, false, true);
 2024|      0|        if (e) {
  ------------------
  |  Branch (2024:13): [True: 0, False: 0]
  ------------------
 2025|      0|            mp_set_playlist_entry(mpctx, e);
 2026|      0|            play_current_file(mpctx);
 2027|      0|        }
 2028|      0|    }
 2029|  94.7k|}
loadfile.c:process_hooks:
 1061|   298k|{
 1062|   298k|    mp_hook_start(mpctx, name);
 1063|       |
 1064|   298k|    while (!mp_hook_test_completion(mpctx, name)) {
  ------------------
  |  Branch (1064:12): [True: 0, False: 298k]
  ------------------
 1065|      0|        mp_idle(mpctx);
 1066|       |
 1067|       |        // We have no idea what blocks a hook, so just do a full abort. This
 1068|       |        // does nothing for hooks that happen outside of playback.
 1069|      0|        if (mpctx->stop_play)
  ------------------
  |  Branch (1069:13): [True: 0, False: 0]
  ------------------
 1070|      0|            mp_abort_playback_async(mpctx);
 1071|      0|    }
 1072|   298k|}
loadfile.c:load_per_file_options:
 1112|  7.46k|{
 1113|  7.46k|    for (int n = 0; n < params_count; n++) {
  ------------------
  |  Branch (1113:21): [True: 0, False: 7.46k]
  ------------------
 1114|      0|        m_config_set_option_cli(conf, params[n].name, params[n].value,
 1115|      0|                                M_SETOPT_BACKUP);
 1116|      0|    }
 1117|  7.46k|}
loadfile.c:open_demux_reentrant:
 1213|  7.46k|{
 1214|  7.46k|    char *url = mpctx->stream_open_filename;
 1215|       |
 1216|  7.46k|    if (mpctx->open_active) {
  ------------------
  |  Branch (1216:9): [True: 232, False: 7.23k]
  ------------------
 1217|    232|        bool done = atomic_load(&mpctx->open_done);
 1218|    232|        bool failed = done && !mpctx->open_res_demuxer;
  ------------------
  |  Branch (1218:23): [True: 127, False: 105]
  |  Branch (1218:31): [True: 51, False: 76]
  ------------------
 1219|    232|        bool correct_url = strcmp(mpctx->open_url, url) == 0;
 1220|       |
 1221|    232|        if (correct_url && !mpctx->demuxer_changed && !failed) {
  ------------------
  |  Branch (1221:13): [True: 232, False: 0]
  |  Branch (1221:28): [True: 232, False: 0]
  |  Branch (1221:55): [True: 181, False: 51]
  ------------------
 1222|    181|            MP_VERBOSE(mpctx, "Using prefetched/prefetching URL.\n");
  ------------------
  |  |   88|    181|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    181|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1223|    181|        } else {
 1224|     51|            if (correct_url && failed) {
  ------------------
  |  Branch (1224:17): [True: 51, False: 0]
  |  Branch (1224:32): [True: 51, False: 0]
  ------------------
 1225|     51|                MP_VERBOSE(mpctx, "Prefetched URL failed, retrying.\n");
  ------------------
  |  |   88|     51|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     51|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1226|     51|            } else if (mpctx->demuxer_changed) {
  ------------------
  |  Branch (1226:24): [True: 0, False: 0]
  ------------------
 1227|      0|                if (done) {
  ------------------
  |  Branch (1227:21): [True: 0, False: 0]
  ------------------
 1228|      0|                    MP_VERBOSE(mpctx, "Dropping finished prefetch because demuxer options changed.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1229|      0|                } else {
 1230|      0|                    MP_VERBOSE(mpctx, "Aborting ongoing prefetch because demuxer options changed.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1231|      0|                }
 1232|      0|            } else {
 1233|      0|                if (done) {
  ------------------
  |  Branch (1233:21): [True: 0, False: 0]
  ------------------
 1234|      0|                    MP_VERBOSE(mpctx, "Dropping finished prefetch of wrong URL.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1235|      0|                } else {
 1236|      0|                    MP_VERBOSE(mpctx, "Aborting ongoing prefetch of wrong URL.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1237|      0|                }
 1238|      0|            }
 1239|     51|            cancel_open(mpctx);
 1240|     51|        }
 1241|    232|    }
 1242|       |
 1243|  7.46k|    if (!mpctx->open_active)
  ------------------
  |  Branch (1243:9): [True: 7.28k, False: 181]
  ------------------
 1244|  7.28k|        start_open(mpctx, url, mpctx->playing->stream_flags, false);
 1245|       |
 1246|       |    // If thread failed to start, cancel the playback
 1247|  7.46k|    if (!mpctx->open_active)
  ------------------
  |  Branch (1247:9): [True: 0, False: 7.46k]
  ------------------
 1248|      0|        goto cancel;
 1249|       |
 1250|       |    // User abort should cancel the opener now.
 1251|  7.46k|    mp_cancel_set_parent(mpctx->open_cancel, mpctx->playback_abort);
 1252|       |
 1253|  22.4k|    while (!atomic_load(&mpctx->open_done)) {
  ------------------
  |  Branch (1253:12): [True: 15.0k, False: 7.46k]
  ------------------
 1254|  15.0k|        mp_idle(mpctx);
 1255|       |
 1256|  15.0k|        if (mpctx->stop_play)
  ------------------
  |  Branch (1256:13): [True: 0, False: 15.0k]
  ------------------
 1257|      0|            mp_abort_playback_async(mpctx);
 1258|  15.0k|    }
 1259|       |
 1260|  7.46k|    if (mpctx->open_res_demuxer) {
  ------------------
  |  Branch (1260:9): [True: 5.09k, False: 2.37k]
  ------------------
 1261|  5.09k|        mpctx->demuxer = mpctx->open_res_demuxer;
 1262|  5.09k|        mpctx->open_res_demuxer = NULL;
 1263|  5.09k|        mp_cancel_set_parent(mpctx->demuxer->cancel, mpctx->playback_abort);
 1264|  5.09k|    } else {
 1265|  2.37k|        mpctx->error_playing = mpctx->open_res_error;
 1266|  2.37k|    }
 1267|       |
 1268|  7.46k|cancel:
 1269|  7.46k|    cancel_open(mpctx); // cleanup
 1270|  7.46k|}
loadfile.c:infinite_playlist_loading_loop:
 1291|    557|{
 1292|    557|    if (pl->num_entries) {
  ------------------
  |  Branch (1292:9): [True: 389, False: 168]
  ------------------
 1293|    389|        struct playlist_entry *e = pl->entries[0];
 1294|    389|        for (int n = 0; n < mpctx->playlist_paths_len; n++) {
  ------------------
  |  Branch (1294:25): [True: 0, False: 389]
  ------------------
 1295|      0|            if (strcmp(mpctx->playlist_paths[n], e->filename) == 0) {
  ------------------
  |  Branch (1295:17): [True: 0, False: 0]
  ------------------
 1296|      0|                clear_playlist_paths(mpctx);
 1297|      0|                return true;
 1298|      0|            }
 1299|      0|        }
 1300|    389|    }
 1301|    557|    MP_TARRAY_APPEND(mpctx, mpctx->playlist_paths, mpctx->playlist_paths_len,
  ------------------
  |  |  105|    557|    do {                                            \
  |  |  106|    557|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    557|    do {                                            \
  |  |  |  |   97|    557|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    557|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    557|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    557|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 551, False: 6]
  |  |  |  |  ------------------
  |  |  |  |   99|    557|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    551|    do {                                                        \
  |  |  |  |  |  |   89|    551|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    551|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    551|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    551|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    551|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    551|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    551|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    557|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    557|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    557|        (idxvar)++;                                 \
  |  |  109|    557|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1302|    557|                     talloc_strdup(mpctx->playlist_paths, mpctx->filename));
 1303|    557|    return false;
 1304|    557|}
loadfile.c:transfer_playlist:
 1043|    557|{
 1044|    557|    if (pl->num_entries) {
  ------------------
  |  Branch (1044:9): [True: 389, False: 168]
  ------------------
 1045|    389|        prepare_playlist(mpctx, pl);
 1046|    389|        struct playlist_entry *new = pl->current;
 1047|    389|        *num_new_entries = pl->num_entries;
 1048|    389|        *start_id = playlist_transfer_entries(mpctx->playlist, pl);
 1049|       |        // current entry is replaced
 1050|    389|        if (mpctx->playlist->current)
  ------------------
  |  Branch (1050:13): [True: 389, False: 0]
  ------------------
 1051|    389|            playlist_remove(mpctx->playlist, mpctx->playlist->current);
 1052|    389|        if (new)
  ------------------
  |  Branch (1052:13): [True: 389, False: 0]
  ------------------
 1053|    389|            mpctx->playlist->current = new;
 1054|    389|        mpctx->playlist->playlist_dir = talloc_steal(mpctx->playlist, pl->playlist_dir);
  ------------------
  |  |   38|    389|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|    389|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 1055|    389|    } else {
 1056|    168|        MP_WARN(mpctx, "Empty playlist!\n");
  ------------------
  |  |   86|    168|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    168|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1057|    168|    }
 1058|    557|}
loadfile.c:load_external_opts:
 1522|  4.53k|{
 1523|  4.53k|    struct mp_waiter wait = MP_WAITER_INITIALIZER;
  ------------------
  |  |   19|  4.53k|#define MP_WAITER_INITIALIZER { \
  |  |   20|  4.53k|    .lock = MP_STATIC_MUTEX_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  106|  4.53k|#define MP_STATIC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
  |  |  ------------------
  |  |   21|  4.53k|    .wakeup = MP_STATIC_COND_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  105|  4.53k|#define MP_STATIC_COND_INITIALIZER { .cond = PTHREAD_COND_INITIALIZER, .clk_id = CLOCK_REALTIME }
  |  |  ------------------
  |  |   22|  4.53k|    }
  ------------------
 1524|       |
 1525|  4.53k|    void *a[] = {mpctx, &wait};
 1526|  4.53k|    if (!mp_thread_pool_queue(mpctx->thread_pool, load_external_opts_thread, a)) {
  ------------------
  |  Branch (1526:9): [True: 0, False: 4.53k]
  ------------------
 1527|      0|        mpctx->stop_play = PT_ERROR;
 1528|      0|        return;
 1529|      0|    }
 1530|       |
 1531|  9.18k|    while (!mp_waiter_poll(&wait)) {
  ------------------
  |  Branch (1531:12): [True: 4.64k, False: 4.53k]
  ------------------
 1532|  4.64k|        mp_idle(mpctx);
 1533|       |
 1534|  4.64k|        if (mpctx->stop_play)
  ------------------
  |  Branch (1534:13): [True: 0, False: 4.64k]
  ------------------
 1535|      0|            mp_abort_playback_async(mpctx);
 1536|  4.64k|    }
 1537|       |
 1538|  4.53k|    mp_waiter_wait(&wait);
 1539|  4.53k|}
loadfile.c:load_external_opts_thread:
 1502|  4.53k|{
 1503|  4.53k|    void **a = p;
 1504|  4.53k|    struct MPContext *mpctx = a[0];
 1505|  4.53k|    struct mp_waiter *waiter = a[1];
 1506|       |
 1507|  4.53k|    mp_core_lock(mpctx);
 1508|       |
 1509|  4.53k|    load_chapters(mpctx);
 1510|  4.53k|    open_external_files(mpctx, mpctx->opts->audio_files, STREAM_AUDIO);
 1511|  4.53k|    open_external_files(mpctx, mpctx->opts->sub_name, STREAM_SUB);
 1512|  4.53k|    open_external_files(mpctx, mpctx->opts->coverart_files, STREAM_VIDEO);
 1513|  4.53k|    open_external_files(mpctx, mpctx->opts->external_files, STREAM_TYPE_COUNT);
 1514|  4.53k|    autoload_external_files(mpctx, mpctx->playback_abort);
 1515|       |
 1516|  4.53k|    mp_waiter_wakeup(waiter, 0);
 1517|  4.53k|    mp_wakeup_core(mpctx);
 1518|  4.53k|    mp_core_unlock(mpctx);
 1519|  4.53k|}
loadfile.c:load_chapters:
 1076|  4.53k|{
 1077|  4.53k|    struct demuxer *src = mpctx->demuxer;
 1078|  4.53k|    bool free_src = false;
 1079|  4.53k|    char *chapter_file = mpctx->opts->chapter_file;
 1080|  4.53k|    if (chapter_file && chapter_file[0]) {
  ------------------
  |  Branch (1080:9): [True: 0, False: 4.53k]
  |  Branch (1080:25): [True: 0, False: 0]
  ------------------
 1081|      0|        chapter_file = mp_get_user_path(NULL, mpctx->global, chapter_file);
 1082|      0|        mp_core_unlock(mpctx);
 1083|      0|        struct demuxer_params p = {.stream_flags = STREAM_ORIGIN_DIRECT};
  ------------------
  |  |   47|      0|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  ------------------
 1084|      0|        struct demuxer *demux = demux_open_url(chapter_file, &p,
 1085|      0|                                               mpctx->playback_abort,
 1086|      0|                                               mpctx->global);
 1087|      0|        mp_core_lock(mpctx);
 1088|      0|        if (demux) {
  ------------------
  |  Branch (1088:13): [True: 0, False: 0]
  ------------------
 1089|      0|            src = demux;
 1090|      0|            free_src = true;
 1091|      0|        }
 1092|      0|        talloc_free(mpctx->chapters);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1093|      0|        mpctx->chapters = NULL;
 1094|      0|        talloc_free(chapter_file);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1095|      0|    }
 1096|  4.53k|    if (src && !mpctx->chapters) {
  ------------------
  |  Branch (1096:9): [True: 4.53k, False: 0]
  |  Branch (1096:16): [True: 4.53k, False: 0]
  ------------------
 1097|  4.53k|        talloc_free(mpctx->chapters);
  ------------------
  |  |   47|  4.53k|#define talloc_free                     ta_free
  ------------------
 1098|  4.53k|        mpctx->num_chapters = src->num_chapters;
 1099|  4.53k|        mpctx->chapters = demux_copy_chapter_data(src->chapters, src->num_chapters);
 1100|  4.53k|        if (mpctx->opts->rebase_start_time) {
  ------------------
  |  Branch (1100:13): [True: 4.53k, False: 0]
  ------------------
 1101|  69.3k|            for (int n = 0; n < mpctx->num_chapters; n++)
  ------------------
  |  Branch (1101:29): [True: 64.7k, False: 4.53k]
  ------------------
 1102|  64.7k|                mpctx->chapters[n].pts -= src->start_time;
 1103|  4.53k|        }
 1104|  4.53k|    }
 1105|  4.53k|    if (free_src)
  ------------------
  |  Branch (1105:9): [True: 0, False: 4.53k]
  ------------------
 1106|      0|        demux_cancel_and_free(src);
 1107|  4.53k|}
loadfile.c:open_external_files:
  943|  18.1k|{
  944|       |    // Need a copy, because the option value could be mutated during iteration.
  945|  18.1k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  18.1k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  18.1k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  946|  18.1k|    files = mp_dup_str_array(tmp, files);
  947|       |
  948|  18.1k|    for (int n = 0; files && files[n]; n++)
  ------------------
  |  Branch (948:21): [True: 0, False: 18.1k]
  |  Branch (948:30): [True: 0, False: 0]
  ------------------
  949|       |        // when given filter is set to video, we are loading up cover art
  950|      0|        mp_add_external_file(mpctx, files[n], filter, mpctx->playback_abort,
  951|      0|                             filter == STREAM_VIDEO ? TRACK_ATTACHED_PICTURE : 0);
  ------------------
  |  Branch (951:30): [True: 0, False: 0]
  ------------------
  952|       |
  953|  18.1k|    talloc_free(tmp);
  ------------------
  |  |   47|  18.1k|#define talloc_free                     ta_free
  ------------------
  954|  18.1k|}
loadfile.c:check_previous_track_selection:
  645|  4.53k|{
  646|  4.53k|    struct MPOpts *opts = mpctx->opts;
  647|       |
  648|  4.53k|    if (!mpctx->track_layout_hash)
  ------------------
  |  Branch (648:9): [True: 4.50k, False: 29]
  ------------------
  649|  4.50k|        return;
  650|       |
  651|     29|    char *h = track_layout_hash(mpctx);
  652|     29|    if (strcmp(h, mpctx->track_layout_hash) != 0) {
  ------------------
  |  Branch (652:9): [True: 7, False: 22]
  ------------------
  653|       |        // Reset selection, but only if they're not "auto" or "off". The
  654|       |        // defaults are -1 (default selection), or -2 (off) for secondary tracks.
  655|     28|        for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
  ------------------
  |  Branch (655:25): [True: 21, False: 7]
  ------------------
  656|     49|            for (int i = 0; i < num_ptracks[t]; i++) {
  ------------------
  |  Branch (656:29): [True: 28, False: 21]
  ------------------
  657|     28|                if (opts->stream_id[i][t] >= 0)
  ------------------
  |  Branch (657:21): [True: 0, False: 28]
  ------------------
  658|      0|                    mark_track_selection(mpctx, i, t, i == 0 ? -1 : -2);
  ------------------
  |  Branch (658:55): [True: 0, False: 0]
  ------------------
  659|     28|            }
  660|     21|        }
  661|      7|        talloc_free(mpctx->track_layout_hash);
  ------------------
  |  |   47|      7|#define talloc_free                     ta_free
  ------------------
  662|      7|        mpctx->track_layout_hash = NULL;
  663|      7|    }
  664|     29|    talloc_free(h);
  ------------------
  |  |   47|     29|#define talloc_free                     ta_free
  ------------------
  665|     29|}
loadfile.c:clear_playlist_paths:
 1285|  2.96k|{
 1286|  2.96k|    TA_FREEP(&mpctx->playlist_paths);
  ------------------
  |  |   81|  2.96k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  2.96k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1287|  2.96k|    mpctx->playlist_paths_len = 0;
 1288|  2.96k|}
loadfile.c:append_to_watch_history:
 1542|  2.96k|{
 1543|  2.96k|    if (!mpctx->opts->save_watch_history)
  ------------------
  |  Branch (1543:9): [True: 2.96k, False: 0]
  ------------------
 1544|  2.96k|        return;
 1545|       |
 1546|      0|    void *ctx = talloc_new(NULL);
  ------------------
  |  |   40|      0|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      0|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
 1547|      0|    char *history_path = mp_get_user_path(ctx, mpctx->global,
 1548|      0|                                          mpctx->opts->watch_history_path);
 1549|      0|    char *history_path_dir = bstrto0(ctx, mp_dirname(history_path));
 1550|      0|    mp_mkdirp(history_path_dir);
 1551|       |
 1552|      0|    FILE *history_file = fopen(history_path, "ab");
 1553|      0|    if (!history_file) {
  ------------------
  |  Branch (1553:9): [True: 0, False: 0]
  ------------------
 1554|      0|        MP_ERR(mpctx, "Failed to open history file: %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1555|      0|               mp_strerror(errno));
 1556|      0|        goto done;
 1557|      0|    }
 1558|       |
 1559|      0|    char *title = (char *)mp_find_non_filename_media_title(mpctx);
 1560|       |
 1561|      0|    mpv_node_list *list = talloc_zero(ctx, mpv_node_list);
  ------------------
  |  |   27|      0|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|      0|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1562|      0|    mpv_node node = {
 1563|      0|        .format = MPV_FORMAT_NODE_MAP,
 1564|      0|        .u.list = list,
 1565|      0|    };
 1566|      0|    list->num = title ? 3 : 2;
  ------------------
  |  Branch (1566:17): [True: 0, False: 0]
  ------------------
 1567|      0|    list->keys = talloc_array(ctx, char*, list->num);
  ------------------
  |  |   29|      0|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|      0|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1568|      0|    list->values = talloc_array(ctx, mpv_node, list->num);
  ------------------
  |  |   29|      0|#define talloc_array                    ta_xnew_array
  |  |  ------------------
  |  |  |  |  135|      0|#define ta_xnew_array(...)              ta_oom_g(ta_new_array(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1569|      0|    list->keys[0] = "time";
 1570|      0|    list->values[0] = (struct mpv_node) {
 1571|      0|        .format = MPV_FORMAT_INT64,
 1572|      0|        .u.int64 = time(NULL),
 1573|      0|    };
 1574|      0|    list->keys[1] = "path";
 1575|      0|    list->values[1] = (struct mpv_node) {
 1576|      0|        .format = MPV_FORMAT_STRING,
 1577|      0|        .u.string = mp_normalize_path(ctx, mpctx->filename),
 1578|      0|    };
 1579|      0|    if (title) {
  ------------------
  |  Branch (1579:9): [True: 0, False: 0]
  ------------------
 1580|      0|        list->keys[2] = "title";
 1581|      0|        list->values[2] = (struct mpv_node) {
 1582|      0|            .format = MPV_FORMAT_STRING,
 1583|      0|            .u.string = title,
 1584|      0|        };
 1585|      0|    }
 1586|       |
 1587|      0|    bstr dst = {0};
 1588|      0|    json_append(&dst, &node, -1);
 1589|      0|    talloc_steal(ctx, dst.start);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
 1590|      0|    if (!dst.len) {
  ------------------
  |  Branch (1590:9): [True: 0, False: 0]
  ------------------
 1591|      0|        MP_ERR(mpctx, "Failed to serialize history entry\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1592|      0|        goto done;
 1593|      0|    }
 1594|      0|    bstr_xappend0(ctx, &dst, "\n");
 1595|       |
 1596|      0|    int seek = fseek(history_file, 0, SEEK_END);
 1597|      0|    off_t history_size = ftell(history_file);
 1598|      0|    if (seek != 0 || history_size == -1) {
  ------------------
  |  Branch (1598:9): [True: 0, False: 0]
  |  Branch (1598:22): [True: 0, False: 0]
  ------------------
 1599|      0|        MP_ERR(mpctx, "Failed to get history file size: %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1600|      0|               mp_strerror(errno));
 1601|      0|        goto done;
 1602|      0|    }
 1603|       |
 1604|      0|    bool failed = fwrite(dst.start, dst.len, 1, history_file) != 1 ||
  ------------------
  |  Branch (1604:19): [True: 0, False: 0]
  ------------------
 1605|      0|                  fflush(history_file) != 0;
  ------------------
  |  Branch (1605:19): [True: 0, False: 0]
  ------------------
 1606|       |
 1607|      0|    if (failed) {
  ------------------
  |  Branch (1607:9): [True: 0, False: 0]
  ------------------
 1608|      0|        MP_ERR(mpctx, "Failed to write to history file: %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1609|      0|               mp_strerror(errno));
 1610|       |
 1611|      0|        int fd = fileno(history_file);
 1612|      0|        if (fd == -1 || ftruncate(fd, history_size) == -1)
  ------------------
  |  Branch (1612:13): [True: 0, False: 0]
  |  Branch (1612:25): [True: 0, False: 0]
  ------------------
 1613|      0|            MP_ERR(mpctx, "Failed to roll-back history file: %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1614|      0|                   mp_strerror(errno));
 1615|      0|    }
 1616|       |
 1617|      0|done:
 1618|      0|    if (history_file != NULL && fclose(history_file) != 0)
  ------------------
  |  Branch (1618:9): [True: 0, False: 0]
  |  Branch (1618:33): [True: 0, False: 0]
  ------------------
 1619|      0|        MP_ERR(mpctx, "Failed to close history file: %s\n", mp_strerror(errno));
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1620|       |
 1621|      0|    talloc_free(ctx);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1622|      0|}
loadfile.c:uninit_demuxer:
  193|  94.7k|{
  194|   379k|    for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
  ------------------
  |  Branch (194:21): [True: 284k, False: 94.7k]
  ------------------
  195|   663k|        for (int r = 0; r < num_ptracks[t]; r++)
  ------------------
  |  Branch (195:25): [True: 379k, False: 284k]
  ------------------
  196|   379k|            mpctx->current_track[r][t] = NULL;
  197|   284k|    }
  198|       |
  199|  94.7k|    talloc_free(mpctx->chapters);
  ------------------
  |  |   47|  94.7k|#define talloc_free                     ta_free
  ------------------
  200|  94.7k|    mpctx->chapters = NULL;
  201|  94.7k|    mpctx->num_chapters = 0;
  202|       |
  203|  94.7k|    mp_abort_cache_dumping(mpctx);
  204|       |
  205|  94.7k|    struct demuxer **demuxers = NULL;
  206|  94.7k|    int num_demuxers = 0;
  207|       |
  208|  94.7k|    if (mpctx->demuxer)
  ------------------
  |  Branch (208:9): [True: 5.09k, False: 89.6k]
  ------------------
  209|  5.09k|        MP_TARRAY_APPEND(NULL, demuxers, num_demuxers, mpctx->demuxer);
  ------------------
  |  |  105|  5.09k|    do {                                            \
  |  |  106|  5.09k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  5.09k|    do {                                            \
  |  |  |  |   97|  5.09k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  5.09k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  5.09k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  5.09k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 5.09k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  5.09k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  5.09k|    do {                                                        \
  |  |  |  |  |  |   89|  5.09k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  5.09k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  5.09k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  5.09k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  5.09k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  5.09k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  5.09k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  5.09k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  5.09k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  5.09k|        (idxvar)++;                                 \
  |  |  109|  5.09k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  210|  94.7k|    mpctx->demuxer = NULL;
  211|       |
  212|  99.9k|    for (int i = 0; i < mpctx->num_tracks; i++) {
  ------------------
  |  Branch (212:21): [True: 5.22k, False: 94.7k]
  ------------------
  213|  5.22k|        struct track *track = mpctx->tracks[i];
  214|       |
  215|  5.22k|        mp_assert(!track->dec && !track->d_sub);
  ------------------
  |  |   41|  5.22k|#define mp_assert assert
  ------------------
  216|  5.22k|        mp_assert(!track->vo_c && !track->ao_c);
  ------------------
  |  |   41|  5.22k|#define mp_assert assert
  ------------------
  217|  5.22k|        mp_assert(!track->sink);
  ------------------
  |  |   41|  5.22k|#define mp_assert assert
  ------------------
  218|       |
  219|       |        // Demuxers can be added in any order (if they appear mid-stream), and
  220|       |        // we can't know which tracks uses which, so here's some O(n^2) trash.
  221|  5.22k|        for (int n = 0; n < num_demuxers; n++) {
  ------------------
  |  Branch (221:25): [True: 5.22k, False: 0]
  ------------------
  222|  5.22k|            if (demuxers[n] == track->demuxer) {
  ------------------
  |  Branch (222:17): [True: 5.22k, False: 0]
  ------------------
  223|  5.22k|                track->demuxer = NULL;
  224|  5.22k|                break;
  225|  5.22k|            }
  226|  5.22k|        }
  227|  5.22k|        if (track->demuxer)
  ------------------
  |  Branch (227:13): [True: 0, False: 5.22k]
  ------------------
  228|      0|            MP_TARRAY_APPEND(NULL, demuxers, num_demuxers, track->demuxer);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  229|       |
  230|  5.22k|        talloc_free(track);
  ------------------
  |  |   47|  5.22k|#define talloc_free                     ta_free
  ------------------
  231|  5.22k|    }
  232|  94.7k|    mpctx->num_tracks = 0;
  233|       |
  234|  94.7k|    kill_demuxers_reentrant(mpctx, demuxers, num_demuxers);
  235|  94.7k|    talloc_free(demuxers);
  ------------------
  |  |   47|  94.7k|#define talloc_free                     ta_free
  ------------------
  236|  94.7k|}
loadfile.c:kill_demuxers_reentrant:
  135|  94.7k|{
  136|  94.7k|    struct demux_free_async_state **items = NULL;
  137|  94.7k|    int num_items = 0;
  138|       |
  139|  99.8k|    for (int n = 0; n < num_demuxers; n++) {
  ------------------
  |  Branch (139:21): [True: 5.09k, False: 94.7k]
  ------------------
  140|  5.09k|        struct demuxer *d = demuxers[n];
  141|       |
  142|  5.09k|        if (!demux_cancel_test(d)) {
  ------------------
  |  Branch (142:13): [True: 5.09k, False: 0]
  ------------------
  143|       |            // Make sure it is set if it wasn't yet.
  144|  5.09k|            demux_set_wakeup_cb(d, wakeup_demux, mpctx);
  145|       |
  146|  5.09k|            struct demux_free_async_state *item = demux_free_async(d);
  147|  5.09k|            if (item) {
  ------------------
  |  Branch (147:17): [True: 4.11k, False: 977]
  ------------------
  148|  4.11k|                MP_TARRAY_APPEND(NULL, items, num_items, item);
  ------------------
  |  |  105|  4.11k|    do {                                            \
  |  |  106|  4.11k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  4.11k|    do {                                            \
  |  |  |  |   97|  4.11k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  4.11k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  4.11k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  4.11k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 4.11k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|  4.11k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  4.11k|    do {                                                        \
  |  |  |  |  |  |   89|  4.11k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  4.11k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  4.11k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  4.11k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  4.11k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  4.11k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  4.11k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  4.11k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  4.11k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  4.11k|        (idxvar)++;                                 \
  |  |  109|  4.11k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  149|  4.11k|                d = NULL;
  150|  4.11k|            }
  151|  5.09k|        }
  152|       |
  153|  5.09k|        demux_cancel_and_free(d);
  154|  5.09k|    }
  155|       |
  156|  94.7k|    if (!num_items)
  ------------------
  |  Branch (156:9): [True: 90.6k, False: 4.11k]
  ------------------
  157|  90.6k|        return;
  158|       |
  159|  4.11k|    MP_DBG(mpctx, "Terminating demuxers...\n");
  ------------------
  |  |   89|  4.11k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  4.11k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  160|       |
  161|  4.11k|    double end = mp_time_sec() + mpctx->opts->demux_termination_timeout;
  162|  4.11k|    bool force = false;
  163|  16.4k|    while (num_items) {
  ------------------
  |  Branch (163:12): [True: 12.3k, False: 4.11k]
  ------------------
  164|  12.3k|        double wait = end - mp_time_sec();
  165|       |
  166|  20.5k|        for (int n = 0; n < num_items; n++) {
  ------------------
  |  Branch (166:25): [True: 12.3k, False: 8.23k]
  ------------------
  167|  12.3k|            struct demux_free_async_state *item = items[n];
  168|  12.3k|            if (demux_free_async_finish(item)) {
  ------------------
  |  Branch (168:17): [True: 4.11k, False: 8.23k]
  ------------------
  169|  4.11k|                items[n] = items[num_items - 1];
  170|  4.11k|                num_items -= 1;
  171|  4.11k|                n--;
  172|  4.11k|                goto repeat;
  173|  8.23k|            } else if (wait < 0) {
  ------------------
  |  Branch (173:24): [True: 0, False: 8.23k]
  ------------------
  174|      0|                demux_free_async_force(item);
  175|      0|                if (!force)
  ------------------
  |  Branch (175:21): [True: 0, False: 0]
  ------------------
  176|      0|                    MP_VERBOSE(mpctx, "Forcefully terminating demuxers...\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  177|      0|                force = true;
  178|      0|            }
  179|  12.3k|        }
  180|       |
  181|  8.23k|        if (wait >= 0)
  ------------------
  |  Branch (181:13): [True: 8.23k, False: 0]
  ------------------
  182|  8.23k|            mp_set_timeout(mpctx, wait);
  183|  8.23k|        mp_idle(mpctx);
  184|  12.3k|    repeat:;
  185|  12.3k|    }
  186|       |
  187|  4.11k|    talloc_free(items);
  ------------------
  |  |   47|  4.11k|#define talloc_free                     ta_free
  ------------------
  188|       |
  189|  4.11k|    MP_DBG(mpctx, "Done terminating demuxers.\n");
  ------------------
  |  |   89|  4.11k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  4.11k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  190|  4.11k|}
loadfile.c:cancel_open:
 1167|  20.8k|{
 1168|  20.8k|    if (mpctx->open_cancel)
  ------------------
  |  Branch (1168:9): [True: 7.51k, False: 13.3k]
  ------------------
 1169|  7.51k|        mp_cancel_trigger(mpctx->open_cancel);
 1170|       |
 1171|  20.8k|    if (mpctx->open_active)
  ------------------
  |  Branch (1171:9): [True: 7.51k, False: 13.3k]
  ------------------
 1172|  7.51k|        mp_thread_join(mpctx->open_thread);
  ------------------
  |  |  212|  7.51k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
 1173|  20.8k|    mpctx->open_active = false;
 1174|       |
 1175|  20.8k|    if (mpctx->open_res_demuxer)
  ------------------
  |  Branch (1175:9): [True: 0, False: 20.8k]
  ------------------
 1176|      0|        demux_cancel_and_free(mpctx->open_res_demuxer);
 1177|  20.8k|    mpctx->open_res_demuxer = NULL;
 1178|       |
 1179|  20.8k|    TA_FREEP(&mpctx->open_cancel);
  ------------------
  |  |   81|  20.8k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  20.8k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1180|  20.8k|    TA_FREEP(&mpctx->open_url);
  ------------------
  |  |   81|  20.8k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  20.8k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1181|  20.8k|    TA_FREEP(&mpctx->open_format);
  ------------------
  |  |   81|  20.8k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  20.8k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1182|       |
 1183|  20.8k|    atomic_store(&mpctx->open_done, false);
 1184|  20.8k|}

mp_update_logging:
  122|  11.6k|{
  123|  11.6k|    bool had_log_file = mp_msg_has_log_file(mpctx->global);
  124|       |
  125|  11.6k|    mp_msg_update_msglevels(mpctx->global, mpctx->opts);
  126|       |
  127|  11.6k|    bool enable = mpctx->opts->use_terminal;
  128|  11.6k|    bool enabled = cas_terminal_owner(mpctx, mpctx);
  129|  11.6k|    if (enable != enabled) {
  ------------------
  |  Branch (129:9): [True: 0, False: 11.6k]
  ------------------
  130|      0|        if (enable && cas_terminal_owner(NULL, mpctx)) {
  ------------------
  |  Branch (130:13): [True: 0, False: 0]
  |  Branch (130:23): [True: 0, False: 0]
  ------------------
  131|      0|            terminal_init();
  132|      0|            enabled = true;
  133|      0|        } else if (!enable) {
  ------------------
  |  Branch (133:20): [True: 0, False: 0]
  ------------------
  134|      0|            terminal_uninit();
  135|      0|            cas_terminal_owner(mpctx, NULL);
  136|      0|        }
  137|      0|    }
  138|       |
  139|  11.6k|    if (mp_msg_has_log_file(mpctx->global) && !had_log_file) {
  ------------------
  |  Branch (139:9): [True: 0, False: 11.6k]
  |  Branch (139:47): [True: 0, False: 0]
  ------------------
  140|       |        // for log-file=... in config files.
  141|       |        // we did flush earlier messages, but they were in a cyclic buffer, so
  142|       |        // the version might have been overwritten. ensure we have it.
  143|      0|        mp_print_version(mpctx->log, false);
  144|      0|    }
  145|       |
  146|  11.6k|    if (enabled && !preinit && mpctx->opts->consolecontrols)
  ------------------
  |  Branch (146:9): [True: 0, False: 11.6k]
  |  Branch (146:20): [True: 0, False: 0]
  |  Branch (146:32): [True: 0, False: 0]
  ------------------
  147|      0|        terminal_setup_getch(mpctx->input);
  148|       |
  149|  11.6k|    if (enabled)
  ------------------
  |  Branch (149:9): [True: 0, False: 11.6k]
  ------------------
  150|      0|        encoder_update_log(mpctx->global);
  151|  11.6k|}
mp_print_version:
  154|  5.81k|{
  155|  5.81k|    int v = always ? MSGL_INFO : MSGL_V;
  ------------------
  |  Branch (155:13): [True: 0, False: 5.81k]
  ------------------
  156|  5.81k|    mp_msg(log, v, "%s %s\n", mpv_version, mpv_copyright);
  157|  5.81k|    if (strcmp(mpv_builddate, "UNKNOWN"))
  ------------------
  |  Branch (157:9): [True: 5.81k, False: 0]
  ------------------
  158|  5.81k|        mp_msg(log, v, " built on %s\n", mpv_builddate);
  159|  5.81k|    mp_msg(log, v, "libplacebo version: %s\n", PL_VERSION);
  ------------------
  |  |   32|  5.81k|#define PL_VERSION (pl_version())
  ------------------
  160|  5.81k|    check_library_versions(log, v);
  161|       |    // Only in verbose mode.
  162|  5.81k|    if (!always) {
  ------------------
  |  Branch (162:9): [True: 5.81k, False: 0]
  ------------------
  163|  5.81k|        mp_msg(log, MSGL_V, "Configuration: " CONFIGURATION "\n");
  164|  5.81k|        mp_msg(log, MSGL_V, "List of enabled features: " FULLCONFIG "\n");
  165|       |        #ifdef NDEBUG
  166|       |            mp_msg(log, MSGL_V, "Built with NDEBUG.\n");
  167|       |        #endif
  168|  5.81k|    }
  169|  5.81k|}
mp_destroy:
  172|  5.81k|{
  173|  5.81k|    mp_shutdown_clients(mpctx);
  174|       |
  175|  5.81k|    mp_uninit_ipc(mpctx->ipc_ctx);
  176|  5.81k|    mpctx->ipc_ctx = NULL;
  177|       |
  178|  5.81k|    uninit_audio_out(mpctx);
  179|  5.81k|    uninit_video_out(mpctx);
  180|       |
  181|       |    // If it's still set here, it's an error.
  182|  5.81k|    encode_lavc_free(mpctx->encode_lavc_ctx);
  183|  5.81k|    mpctx->encode_lavc_ctx = NULL;
  184|       |
  185|  5.81k|    command_uninit(mpctx);
  186|       |
  187|  5.81k|    mp_clients_destroy(mpctx);
  188|       |
  189|  5.81k|    osd_free(mpctx->osd);
  190|       |
  191|       |#if HAVE_COCOA
  192|       |    cocoa_set_input_context(NULL);
  193|       |#endif
  194|       |
  195|  5.81k|    if (cas_terminal_owner(mpctx, mpctx)) {
  ------------------
  |  Branch (195:9): [True: 0, False: 5.81k]
  ------------------
  196|      0|        terminal_uninit();
  197|      0|        cas_terminal_owner(mpctx, NULL);
  198|      0|    }
  199|       |
  200|  5.81k|    mp_input_uninit(mpctx->input);
  201|  5.81k|    mp_clipboard_destroy(mpctx->clipboard);
  202|       |
  203|  5.81k|    uninit_libav(mpctx->global);
  204|       |
  205|  5.81k|    mp_msg_uninit(mpctx->global);
  206|  5.81k|    mp_assert(!mpctx->num_abort_list);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  207|  5.81k|    talloc_free(mpctx->abort_list);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  208|  5.81k|    mp_mutex_destroy(&mpctx->abort_lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  209|  5.81k|    talloc_free(mpctx->mconfig); // destroy before dispatch
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  210|  5.81k|    talloc_free(mpctx);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  211|  5.81k|}
mp_create:
  253|  5.81k|{
  254|  5.81k|    if (!check_locale()) {
  ------------------
  |  Branch (254:9): [True: 0, False: 5.81k]
  ------------------
  255|       |        // Normally, we never print anything (except if the "terminal" option
  256|       |        // is enabled), so this is an exception.
  257|      0|        fprintf(stderr, "Non-C locale detected. This is not supported.\n"
  258|      0|                        "Call 'setlocale(LC_NUMERIC, \"C\");' in your code.\n");
  259|      0|        return NULL;
  260|      0|    }
  261|       |
  262|  5.81k|    char *enable_talloc = getenv("MPV_LEAK_REPORT");
  263|  5.81k|    if (enable_talloc && strcmp(enable_talloc, "1") == 0)
  ------------------
  |  Branch (263:9): [True: 0, False: 5.81k]
  |  Branch (263:26): [True: 0, False: 0]
  ------------------
  264|      0|        talloc_enable_leak_report();
  ------------------
  |  |   42|      0|#define talloc_enable_leak_report       ta_enable_leak_report
  ------------------
  265|       |
  266|  5.81k|    mp_time_init();
  267|       |
  268|  5.81k|    struct MPContext *mpctx = talloc(NULL, MPContext);
  ------------------
  |  |   26|  5.81k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  269|  5.81k|    *mpctx = (struct MPContext){
  270|  5.81k|        .last_chapter = -2,
  271|  5.81k|        .term_osd_contents = talloc_strdup(mpctx, ""),
  ------------------
  |  |   50|  5.81k|#define talloc_strdup                   ta_xstrdup
  ------------------
  272|  5.81k|        .osd_progbar = { .type = -1 },
  273|  5.81k|        .playlist = talloc_zero(mpctx, struct playlist),
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  274|  5.81k|        .dispatch = mp_dispatch_create(mpctx),
  275|  5.81k|        .playback_abort = mp_cancel_new(mpctx),
  276|  5.81k|        .thread_pool = mp_thread_pool_create(mpctx, 0, 1, 30),
  277|  5.81k|        .stop_play = PT_NEXT_ENTRY,
  278|  5.81k|        .play_dir = 1,
  279|  5.81k|    };
  280|       |
  281|  5.81k|    mp_mutex_init(&mpctx->abort_lock);
  282|       |
  283|  5.81k|    mpctx->global = talloc_zero(mpctx, struct mpv_global);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  284|       |
  285|  5.81k|    demux_packet_pool_init(mpctx->global);
  286|  5.81k|    stats_global_init(mpctx->global);
  287|       |
  288|       |    // Nothing must call mp_msg*() and related before this
  289|  5.81k|    mp_msg_init(mpctx->global);
  290|  5.81k|    mpctx->log = mp_log_new(mpctx, mpctx->global->log, "!cplayer");
  291|  5.81k|    mpctx->statusline = mp_log_new(mpctx, mpctx->log, "!statusline");
  292|       |
  293|  5.81k|    mpctx->stats = stats_ctx_create(mpctx, mpctx->global, "main");
  294|       |
  295|       |    // Create the config context and register the options
  296|  5.81k|    mpctx->mconfig = m_config_new(mpctx, mpctx->log, &mp_opt_root);
  297|  5.81k|    mpctx->opts = mpctx->mconfig->optstruct;
  298|  5.81k|    mpctx->global->config = mpctx->mconfig->shadow;
  299|  5.81k|    mpctx->mconfig->includefunc = cfg_include;
  300|  5.81k|    mpctx->mconfig->includefunc_ctx = mpctx;
  301|  5.81k|    mpctx->mconfig->use_profiles = true;
  302|  5.81k|    mpctx->mconfig->is_toplevel = true;
  303|  5.81k|    mpctx->mconfig->global = mpctx->global;
  304|  5.81k|    m_config_parse(mpctx->mconfig, "", bstr0(def_config), NULL, 0);
  305|       |
  306|  5.81k|    mpctx->input = mp_input_init(mpctx->global, mp_wakeup_core_cb, mpctx);
  307|  5.81k|    screenshot_init(mpctx);
  308|  5.81k|    command_init(mpctx);
  309|  5.81k|    init_libav(mpctx->global);
  310|  5.81k|    mp_clients_init(mpctx);
  311|  5.81k|    mpctx->osd = osd_create(mpctx->global);
  312|       |
  313|       |#if HAVE_COCOA
  314|       |    cocoa_set_input_context(mpctx->input);
  315|       |#endif
  316|       |
  317|  5.81k|    char *verbose_env = getenv("MPV_VERBOSE");
  318|  5.81k|    if (verbose_env)
  ------------------
  |  Branch (318:9): [True: 0, False: 5.81k]
  ------------------
  319|      0|        mpctx->opts->verbose = atoi(verbose_env);
  320|       |
  321|  5.81k|    mp_cancel_trigger(mpctx->playback_abort);
  322|       |
  323|  5.81k|    return mpctx;
  324|  5.81k|}
mp_initialize:
  332|  5.81k|{
  333|  5.81k|    struct MPOpts *opts = mpctx->opts;
  334|       |
  335|  5.81k|    mp_assert(!mpctx->initialized);
  ------------------
  |  |   41|  5.81k|#define mp_assert assert
  ------------------
  336|       |
  337|       |    // Preparse the command line, so we can init the terminal early.
  338|  5.81k|    if (options) {
  ------------------
  |  Branch (338:9): [True: 0, False: 5.81k]
  ------------------
  339|      0|        m_config_preparse_command_line(mpctx->mconfig, mpctx->global,
  340|      0|                                       &opts->verbose, options);
  341|      0|    }
  342|       |
  343|  5.81k|    mp_init_paths(mpctx->global, opts);
  344|  5.81k|    mp_msg_set_early_logging(mpctx->global, true);
  345|  5.81k|    mp_update_logging(mpctx, true);
  346|       |
  347|  5.81k|    if (options) {
  ------------------
  |  Branch (347:9): [True: 0, False: 5.81k]
  ------------------
  348|      0|        MP_VERBOSE(mpctx, "Command line options:");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  349|      0|        for (int i = 0; options[i]; i++)
  ------------------
  |  Branch (349:25): [True: 0, False: 0]
  ------------------
  350|      0|            MP_VERBOSE(mpctx, " '%s'", options[i]);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  351|      0|        MP_VERBOSE(mpctx, "\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  352|      0|    }
  353|       |
  354|  5.81k|    mp_print_version(mpctx->log, false);
  355|       |
  356|  5.81k|    mp_parse_cfgfiles(mpctx);
  357|       |
  358|  5.81k|    if (options) {
  ------------------
  |  Branch (358:9): [True: 0, False: 5.81k]
  ------------------
  359|      0|        int r = m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist,
  360|      0|                                               mpctx->global, options);
  361|      0|        if (r < 0)
  ------------------
  |  Branch (361:13): [True: 0, False: 0]
  ------------------
  362|      0|            return r == M_OPT_EXIT ? 1 : -1;
  ------------------
  |  |  533|      0|#define M_OPT_EXIT              -6
  ------------------
  |  Branch (362:20): [True: 0, False: 0]
  ------------------
  363|      0|    }
  364|       |
  365|  5.81k|    if (opts->operation_mode == 1) {
  ------------------
  |  Branch (365:9): [True: 0, False: 5.81k]
  ------------------
  366|      0|        m_config_set_profile(mpctx->mconfig, "builtin-pseudo-gui",
  367|      0|                             M_SETOPT_NO_OVERWRITE);
  368|      0|        m_config_set_profile(mpctx->mconfig, "pseudo-gui", 0);
  369|      0|    }
  370|       |
  371|       |    // Backup the default settings, which should not be stored in the resume
  372|       |    // config files. This explicitly includes values set by config files and
  373|       |    // the command line.
  374|  5.81k|    m_config_backup_watch_later_opts(mpctx->mconfig);
  375|       |
  376|  5.81k|    mp_input_load_config(mpctx->input);
  377|       |
  378|       |    // From this point on, all mpctx members are initialized.
  379|  5.81k|    mpctx->initialized = true;
  380|  5.81k|    mpctx->mconfig->option_change_callback = mp_option_change_callback;
  381|  5.81k|    mpctx->mconfig->option_change_callback_ctx = mpctx;
  382|  5.81k|    m_config_set_update_dispatch_queue(mpctx->mconfig, mpctx->dispatch);
  383|       |    // Run all update handlers.
  384|  5.81k|    mp_option_change_callback(mpctx, NULL, UPDATE_OPTS_MASK, false);
  ------------------
  |  |  453|  5.81k|#define UPDATE_OPTS_MASK        ((UPDATE_OPT_LAST << 1) - 1)
  |  |  ------------------
  |  |  |  |  450|  5.81k|#define UPDATE_OPT_LAST         (UINT64_C(1) << 20)
  |  |  ------------------
  ------------------
  385|  5.81k|    handle_option_callbacks(mpctx);
  386|       |
  387|  5.81k|    if (handle_help_options(mpctx))
  ------------------
  |  Branch (387:9): [True: 0, False: 5.81k]
  ------------------
  388|      0|        return 1; // help
  389|       |
  390|  5.81k|    check_library_versions(mp_null_log, 0);
  391|       |
  392|  5.81k|    if (!mpctx->playlist->num_entries && !opts->player_idle_mode &&
  ------------------
  |  Branch (392:9): [True: 5.81k, False: 0]
  |  Branch (392:42): [True: 0, False: 5.81k]
  ------------------
  393|  5.81k|        options)
  ------------------
  |  Branch (393:9): [True: 0, False: 0]
  ------------------
  394|      0|    {
  395|       |        // nothing to play
  396|      0|        mp_print_version(mpctx->log, true);
  397|      0|        MP_INFO(mpctx, "%s", mp_help_text);
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  398|      0|        return 1;
  399|      0|    }
  400|       |
  401|  5.81k|    MP_STATS(mpctx, "start init");
  ------------------
  |  |   95|  5.81k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.81k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  402|       |
  403|       |#if HAVE_COCOA
  404|       |    mpv_handle *ctx = mp_new_client(mpctx->clients, "mac");
  405|       |    cocoa_set_mpv_handle(ctx);
  406|       |#endif
  407|       |
  408|       |#if HAVE_WIN32_SMTC
  409|       |    if (opts->media_controls)
  410|       |        mp_smtc_init(mp_new_client(mpctx->clients, "SystemMediaTransportControls"));
  411|       |#endif
  412|       |
  413|  5.81k|    mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global);
  414|       |
  415|  5.81k|    if (opts->encode_opts->file && opts->encode_opts->file[0]) {
  ------------------
  |  Branch (415:9): [True: 0, False: 5.81k]
  |  Branch (415:36): [True: 0, False: 0]
  ------------------
  416|      0|        mpctx->encode_lavc_ctx = encode_lavc_init(mpctx->global);
  417|      0|        if(!mpctx->encode_lavc_ctx) {
  ------------------
  |  Branch (417:12): [True: 0, False: 0]
  ------------------
  418|      0|            MP_INFO(mpctx, "Encoding initialization failed.\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  419|      0|            return -1;
  420|      0|        }
  421|      0|    }
  422|       |
  423|  5.81k|    mp_load_scripts(mpctx);
  424|       |
  425|  5.81k|    if (opts->force_vo == 2 && handle_force_window(mpctx, false) < 0)
  ------------------
  |  Branch (425:9): [True: 0, False: 5.81k]
  |  Branch (425:32): [True: 0, False: 0]
  ------------------
  426|      0|        return -1;
  427|       |
  428|       |    // Needed to properly enter _initial_ idle mode if playlist empty.
  429|  5.81k|    if (mpctx->opts->player_idle_mode && !mpctx->playlist->num_entries)
  ------------------
  |  Branch (429:9): [True: 5.81k, False: 0]
  |  Branch (429:42): [True: 5.81k, False: 0]
  ------------------
  430|  5.81k|        mpctx->stop_play = PT_STOP;
  431|       |
  432|  5.81k|    MP_STATS(mpctx, "end init");
  ------------------
  |  |   95|  5.81k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.81k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  433|       |
  434|  5.81k|    return 0;
  435|  5.81k|}
main.c:cas_terminal_owner:
  112|  17.4k|{
  113|  17.4k|    mp_mutex_lock(&terminal_owner_lock);
  ------------------
  |  |  131|  17.4k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  114|  17.4k|    bool r = terminal_owner == old;
  115|  17.4k|    if (r)
  ------------------
  |  Branch (115:9): [True: 0, False: 17.4k]
  ------------------
  116|      0|        terminal_owner = new;
  117|  17.4k|    mp_mutex_unlock(&terminal_owner_lock);
  ------------------
  |  |  133|  17.4k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  118|  17.4k|    return r;
  119|  17.4k|}
main.c:check_locale:
  247|  5.81k|{
  248|  5.81k|    char *name = setlocale(LC_NUMERIC, NULL);
  249|  5.81k|    return !name || strcmp(name, "C") == 0 || strcmp(name, "C.UTF-8") == 0;
  ------------------
  |  Branch (249:12): [True: 0, False: 5.81k]
  |  Branch (249:21): [True: 5.81k, False: 0]
  |  Branch (249:47): [True: 0, False: 0]
  ------------------
  250|  5.81k|}
main.c:handle_help_options:
  214|  5.81k|{
  215|  5.81k|    struct MPOpts *opts = mpctx->opts;
  216|  5.81k|    struct mp_log *log = mpctx->log;
  217|  5.81k|    if (opts->ao_opts->audio_device &&
  ------------------
  |  Branch (217:9): [True: 5.81k, False: 0]
  ------------------
  218|  5.81k|        strcmp(opts->ao_opts->audio_device, "help") == 0)
  ------------------
  |  Branch (218:9): [True: 0, False: 5.81k]
  ------------------
  219|      0|    {
  220|      0|        ao_print_devices(mpctx->global, log, mpctx->ao);
  221|      0|        return true;
  222|      0|    }
  223|  5.81k|    if (opts->property_print_help) {
  ------------------
  |  Branch (223:9): [True: 0, False: 5.81k]
  ------------------
  224|      0|        property_print_help(mpctx);
  225|      0|        return true;
  226|      0|    }
  227|  5.81k|    if (encode_lavc_showhelp(log, opts->encode_opts))
  ------------------
  |  Branch (227:9): [True: 0, False: 5.81k]
  ------------------
  228|      0|        return true;
  229|  5.81k|    return false;
  230|  5.81k|}

rel_time_to_abs:
   55|   894k|{
   56|   894k|    double length = get_time_length(mpctx);
   57|       |    // Relative times are an offset to the start of the file.
   58|   894k|    double start = 0;
   59|   894k|    if (mpctx->demuxer && !mpctx->opts->rebase_start_time)
  ------------------
  |  Branch (59:9): [True: 894k, False: 0]
  |  Branch (59:27): [True: 0, False: 894k]
  ------------------
   60|      0|        start = mpctx->demuxer->start_time;
   61|       |
   62|   894k|    switch (t.type) {
  ------------------
  |  Branch (62:13): [True: 894k, False: 0]
  ------------------
   63|      0|    case REL_TIME_ABSOLUTE:
  ------------------
  |  Branch (63:5): [True: 0, False: 894k]
  ------------------
   64|      0|        return t.pos;
   65|      0|    case REL_TIME_RELATIVE:
  ------------------
  |  Branch (65:5): [True: 0, False: 894k]
  ------------------
   66|      0|        if (t.pos >= 0) {
  ------------------
  |  Branch (66:13): [True: 0, False: 0]
  ------------------
   67|      0|            return start + t.pos;
   68|      0|        } else {
   69|      0|            if (length >= 0)
  ------------------
  |  Branch (69:17): [True: 0, False: 0]
  ------------------
   70|      0|                return start + MPMAX(length + t.pos, 0.0);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   71|      0|        }
   72|      0|        break;
   73|      0|    case REL_TIME_PERCENT:
  ------------------
  |  Branch (73:5): [True: 0, False: 894k]
  ------------------
   74|      0|        if (length >= 0)
  ------------------
  |  Branch (74:13): [True: 0, False: 0]
  ------------------
   75|      0|            return start + length * (t.pos / 100.0);
   76|      0|        break;
   77|      0|    case REL_TIME_CHAPTER:
  ------------------
  |  Branch (77:5): [True: 0, False: 894k]
  ------------------
   78|      0|        return chapter_start_time(mpctx, t.pos); // already absolute time
   79|   894k|    }
   80|       |
   81|   894k|    return MP_NOPTS_VALUE;
  ------------------
  |  |   38|   894k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
   82|   894k|}
get_play_end_pts:
  100|   445k|{
  101|   445k|    double end = get_play_end_pts_setting(mpctx);
  102|   445k|    double ab[2];
  103|   445k|    if (mpctx->ab_loop_clip && get_ab_loop_times(mpctx, ab)) {
  ------------------
  |  Branch (103:9): [True: 11.1k, False: 434k]
  |  Branch (103:32): [True: 0, False: 11.1k]
  ------------------
  104|      0|        if (end == MP_NOPTS_VALUE || end > ab[1])
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (104:13): [True: 0, False: 0]
  |  Branch (104:38): [True: 0, False: 0]
  ------------------
  105|      0|            end = ab[1];
  106|      0|    }
  107|   445k|    return end;
  108|   445k|}
get_ab_loop_times:
  125|  17.0k|{
  126|  17.0k|    struct MPOpts *opts = mpctx->opts;
  127|  17.0k|    int dir = mpctx->play_dir;
  128|       |
  129|  17.0k|    t[0] = opts->ab_loop[0];
  130|  17.0k|    t[1] = opts->ab_loop[1];
  131|       |
  132|  17.0k|    if (!mpctx->remaining_ab_loops)
  ------------------
  |  Branch (132:9): [True: 0, False: 17.0k]
  ------------------
  133|      0|        return false;
  134|       |
  135|  17.0k|    if (t[0] == MP_NOPTS_VALUE || t[1] == MP_NOPTS_VALUE || t[0] == t[1])
  ------------------
  |  |   38|  34.0k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                  if (t[0] == MP_NOPTS_VALUE || t[1] == MP_NOPTS_VALUE || t[0] == t[1])
  ------------------
  |  |   38|  17.0k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (135:9): [True: 17.0k, False: 0]
  |  Branch (135:35): [True: 0, False: 0]
  |  Branch (135:61): [True: 0, False: 0]
  ------------------
  136|  17.0k|        return false;
  137|       |
  138|      0|    if (t[0] * dir > t[1] * dir)
  ------------------
  |  Branch (138:9): [True: 0, False: 0]
  ------------------
  139|      0|        MPSWAP(double, t[0], t[1]);
  ------------------
  |  |   47|      0|    do { type SWAP_tmp = b; b = a; a = SWAP_tmp; } while (0)
  |  |  ------------------
  |  |  |  Branch (47:59): [Folded - Ignored]
  |  |  ------------------
  ------------------
  140|       |
  141|      0|    return true;
  142|  17.0k|}
get_track_seek_offset:
  145|  6.26k|{
  146|  6.26k|    struct MPOpts *opts = mpctx->opts;
  147|  6.26k|    if (track->selected) {
  ------------------
  |  Branch (147:9): [True: 4.88k, False: 1.38k]
  ------------------
  148|  4.88k|        if (track->type == STREAM_AUDIO)
  ------------------
  |  Branch (148:13): [True: 1.95k, False: 2.93k]
  ------------------
  149|  1.95k|            return -opts->audio_delay;
  150|  2.93k|        if (track->type == STREAM_SUB)
  ------------------
  |  Branch (150:13): [True: 0, False: 2.93k]
  ------------------
  151|      0|        {
  152|      0|            for (int n = 0; n < num_ptracks[STREAM_SUB]; n++) {
  ------------------
  |  Branch (152:29): [True: 0, False: 0]
  ------------------
  153|      0|                if (mpctx->current_track[n][STREAM_SUB] == track)
  ------------------
  |  Branch (153:21): [True: 0, False: 0]
  ------------------
  154|      0|                    return -opts->subs_shared->sub_delay[n];
  155|      0|            }
  156|      0|        }
  157|  2.93k|    }
  158|  4.31k|    return 0;
  159|  6.26k|}
update_content_type:
  178|  2.02k|{
  179|  2.02k|    enum mp_content_type content_type;
  180|  2.02k|    if (!track || !track->vo_c) {
  ------------------
  |  Branch (180:9): [True: 0, False: 2.02k]
  |  Branch (180:19): [True: 0, False: 2.02k]
  ------------------
  181|      0|        content_type = MP_CONTENT_NONE;
  182|  2.02k|    } else if (track->image) {
  ------------------
  |  Branch (182:16): [True: 887, False: 1.14k]
  ------------------
  183|    887|        content_type = MP_CONTENT_IMAGE;
  184|  1.14k|    } else {
  185|  1.14k|        content_type = MP_CONTENT_VIDEO;
  186|  1.14k|    }
  187|  2.02k|    if (mpctx->video_out)
  ------------------
  |  Branch (187:9): [True: 2.02k, False: 0]
  ------------------
  188|  2.02k|        vo_control(mpctx->video_out, VOCTRL_CONTENT_TYPE, &content_type);
  189|  2.02k|}
update_vo_playback_state:
  192|  79.3k|{
  193|  79.3k|    if (mpctx->video_out && mpctx->video_out->config_ok) {
  ------------------
  |  Branch (193:9): [True: 72.2k, False: 7.13k]
  |  Branch (193:29): [True: 72.0k, False: 204]
  ------------------
  194|  72.0k|        struct voctrl_playback_state oldstate = mpctx->vo_playback_state;
  195|  72.0k|        double pos = get_current_pos_ratio(mpctx, false);
  196|  72.0k|        struct voctrl_playback_state newstate = {
  197|  72.0k|            .taskbar_progress = mpctx->opts->vo->taskbar_progress && pos >= 0,
  ------------------
  |  Branch (197:33): [True: 72.0k, False: 0]
  |  Branch (197:70): [True: 72.0k, False: 0]
  ------------------
  198|  72.0k|            .playing = mpctx->playing,
  199|  72.0k|            .paused = mpctx->paused,
  200|  72.0k|            .position = pos > 0 ? lrint(pos * UINT8_MAX) : 0,
  ------------------
  |  Branch (200:25): [True: 71.1k, False: 846]
  ------------------
  201|  72.0k|        };
  202|       |
  203|  72.0k|        if (oldstate.taskbar_progress != newstate.taskbar_progress ||
  ------------------
  |  Branch (203:13): [True: 558, False: 71.4k]
  ------------------
  204|  72.0k|            oldstate.playing != newstate.playing ||
  ------------------
  |  Branch (204:13): [True: 0, False: 71.4k]
  ------------------
  205|  72.0k|            oldstate.paused != newstate.paused ||
  ------------------
  |  Branch (205:13): [True: 42, False: 71.4k]
  ------------------
  206|  72.0k|            oldstate.position != newstate.position)
  ------------------
  |  Branch (206:13): [True: 43.5k, False: 27.8k]
  ------------------
  207|  44.1k|        {
  208|       |            // Don't update progress bar if it was and still is hidden
  209|  44.1k|            if ((oldstate.playing && oldstate.taskbar_progress) ||
  ------------------
  |  Branch (209:18): [True: 43.5k, False: 558]
  |  Branch (209:38): [True: 43.5k, False: 0]
  ------------------
  210|  44.1k|                (newstate.playing && newstate.taskbar_progress))
  ------------------
  |  Branch (210:18): [True: 558, False: 0]
  |  Branch (210:38): [True: 558, False: 0]
  ------------------
  211|  44.1k|            {
  212|  44.1k|                vo_control_async(mpctx->video_out,
  213|  44.1k|                                 VOCTRL_UPDATE_PLAYBACK_STATE, &newstate);
  214|  44.1k|            }
  215|  44.1k|            mpctx->vo_playback_state = newstate;
  216|  44.1k|        }
  217|  72.0k|    } else {
  218|  7.33k|        mpctx->vo_playback_state = (struct voctrl_playback_state){ 0 };
  219|  7.33k|    }
  220|  79.3k|}
update_window_title:
  223|  83.6k|{
  224|  83.6k|    if (!mpctx->video_out && !mpctx->ao) {
  ------------------
  |  Branch (224:9): [True: 8.47k, False: 75.1k]
  |  Branch (224:30): [True: 6.29k, False: 2.17k]
  ------------------
  225|  6.29k|        talloc_free(mpctx->last_window_title);
  ------------------
  |  |   47|  6.29k|#define talloc_free                     ta_free
  ------------------
  226|  6.29k|        mpctx->last_window_title = NULL;
  227|  6.29k|        return;
  228|  6.29k|    }
  229|  77.3k|    char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle);
  230|  77.3k|    if (!mpctx->last_window_title || force ||
  ------------------
  |  Branch (230:9): [True: 3.48k, False: 73.8k]
  |  Branch (230:38): [True: 794, False: 73.0k]
  ------------------
  231|  77.3k|        strcmp(title, mpctx->last_window_title) != 0)
  ------------------
  |  Branch (231:9): [True: 2, False: 73.0k]
  ------------------
  232|  4.28k|    {
  233|  4.28k|        talloc_free(mpctx->last_window_title);
  ------------------
  |  |   47|  4.28k|#define talloc_free                     ta_free
  ------------------
  234|  4.28k|        mpctx->last_window_title = talloc_steal(mpctx, title);
  ------------------
  |  |   38|  4.28k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  4.28k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  235|       |
  236|  4.28k|        if (mpctx->video_out)
  ------------------
  |  Branch (236:13): [True: 2.93k, False: 1.34k]
  ------------------
  237|  2.93k|            vo_control(mpctx->video_out, VOCTRL_UPDATE_WINDOW_TITLE, title);
  238|       |
  239|  4.28k|        if (mpctx->ao) {
  ------------------
  |  Branch (239:13): [True: 1.35k, False: 2.93k]
  ------------------
  240|  1.35k|            ao_control(mpctx->ao, AOCONTROL_UPDATE_STREAM_TITLE, title);
  241|  1.35k|        }
  242|  73.0k|    } else {
  243|  73.0k|        talloc_free(title);
  ------------------
  |  |   47|  73.0k|#define talloc_free                     ta_free
  ------------------
  244|  73.0k|    }
  245|  77.3k|}
error_on_track:
  248|  7.32k|{
  249|  7.32k|    if (!track || !track->selected)
  ------------------
  |  Branch (249:9): [True: 5.23k, False: 2.08k]
  |  Branch (249:19): [True: 1.04k, False: 1.04k]
  ------------------
  250|  6.27k|        return;
  251|  1.04k|    mp_deselect_track(mpctx, track);
  252|  1.04k|    if (track->type == STREAM_AUDIO)
  ------------------
  |  Branch (252:9): [True: 141, False: 903]
  ------------------
  253|  1.04k|        MP_INFO(mpctx, "Audio: no audio\n");
  ------------------
  |  |   87|    141|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    141|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  254|  1.04k|    if (track->type == STREAM_VIDEO)
  ------------------
  |  Branch (254:9): [True: 903, False: 141]
  ------------------
  255|  1.04k|        MP_INFO(mpctx, "Video: no video\n");
  ------------------
  |  |   87|    903|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    903|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  256|  1.04k|    if (mpctx->opts->stop_playback_on_init_failure ||
  ------------------
  |  Branch (256:9): [True: 0, False: 1.04k]
  ------------------
  257|  1.04k|        (!mpctx->current_track[0][STREAM_AUDIO] &&
  ------------------
  |  Branch (257:10): [True: 1.03k, False: 12]
  ------------------
  258|  1.04k|         !mpctx->current_track[0][STREAM_VIDEO]))
  ------------------
  |  Branch (258:10): [True: 1.03k, False: 0]
  ------------------
  259|  1.03k|    {
  260|  1.03k|        if (!mpctx->stop_play)
  ------------------
  |  Branch (260:13): [True: 1.03k, False: 0]
  ------------------
  261|  1.03k|            mpctx->stop_play = PT_ERROR;
  262|  1.03k|        if (mpctx->error_playing >= 0)
  ------------------
  |  Branch (262:13): [True: 0, False: 1.03k]
  ------------------
  263|      0|            mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
  264|  1.03k|    }
  265|  1.04k|    mp_wakeup_core(mpctx);
  266|  1.04k|}
mp_status_str:
  338|  86.9k|{
  339|  86.9k|    switch (st) {
  340|  6.07k|    case STATUS_SYNCING:    return "syncing";
  ------------------
  |  Branch (340:5): [True: 6.07k, False: 80.8k]
  ------------------
  341|      0|    case STATUS_READY:      return "ready";
  ------------------
  |  Branch (341:5): [True: 0, False: 86.9k]
  ------------------
  342|  74.4k|    case STATUS_PLAYING:    return "playing";
  ------------------
  |  Branch (342:5): [True: 74.4k, False: 12.4k]
  ------------------
  343|  1.77k|    case STATUS_DRAINING:   return "draining";
  ------------------
  |  Branch (343:5): [True: 1.77k, False: 85.1k]
  ------------------
  344|  4.62k|    case STATUS_EOF:        return "eof";
  ------------------
  |  Branch (344:5): [True: 4.62k, False: 82.3k]
  ------------------
  345|      0|    default:                return "bug";
  ------------------
  |  Branch (345:5): [True: 0, False: 86.9k]
  ------------------
  346|  86.9k|    }
  347|  86.9k|}
str_in_list:
  350|   125k|{
  351|   125k|    if (!list)
  ------------------
  |  Branch (351:9): [True: 0, False: 125k]
  ------------------
  352|      0|        return false;
  353|   375k|    while (*list) {
  ------------------
  |  Branch (353:12): [True: 375k, False: 0]
  ------------------
  354|   375k|        if (!bstrcasecmp0(str, *list++))
  ------------------
  |  Branch (354:13): [True: 125k, False: 250k]
  ------------------
  355|   125k|            return true;
  356|   375k|    }
  357|      0|    return false;
  358|   125k|}
mp_format_track_metadata:
  366|  5.22k|{
  367|  5.22k|    struct sh_stream *s = t->stream;
  368|  5.22k|    bstr dst = {0};
  369|       |
  370|  5.22k|    if (t->title)
  ------------------
  |  Branch (370:9): [True: 0, False: 5.22k]
  ------------------
  371|      0|        bstr_xappend_asprintf(ctx, &dst, "'%s' ", t->title);
  372|       |
  373|  5.22k|    const char *codec = s ? s->codec->codec : NULL;
  ------------------
  |  Branch (373:25): [True: 5.22k, False: 0]
  ------------------
  374|       |
  375|  5.22k|    bstr_xappend0(ctx, &dst, "(");
  376|       |
  377|  5.22k|    if (add_lang && t->lang)
  ------------------
  |  Branch (377:9): [True: 0, False: 5.22k]
  |  Branch (377:21): [True: 0, False: 0]
  ------------------
  378|      0|        bstr_xappend_asprintf(ctx, &dst, "%s ", t->lang);
  379|       |
  380|  5.22k|    bstr_xappend0(ctx, &dst, codec ? codec : "<unknown>");
  ------------------
  |  Branch (380:30): [True: 5.22k, False: 0]
  ------------------
  381|       |
  382|  5.22k|    if (s && s->codec->codec_profile)
  ------------------
  |  Branch (382:9): [True: 5.22k, False: 0]
  |  Branch (382:14): [True: 0, False: 5.22k]
  ------------------
  383|      0|        bstr_xappend_asprintf(ctx, &dst, " [%s]", s->codec->codec_profile);
  384|  5.22k|    if (s && s->codec->disp_w)
  ------------------
  |  Branch (384:9): [True: 5.22k, False: 0]
  |  Branch (384:14): [True: 1.67k, False: 3.54k]
  ------------------
  385|  1.67k|        bstr_xappend_asprintf(ctx, &dst, " %dx%d", s->codec->disp_w, s->codec->disp_h);
  386|  5.22k|    if (s && s->codec->fps && !t->image) {
  ------------------
  |  Branch (386:9): [True: 5.22k, False: 0]
  |  Branch (386:14): [True: 1.93k, False: 3.29k]
  |  Branch (386:31): [True: 255, False: 1.67k]
  ------------------
  387|    255|        char *fps = mp_format_double(ctx, s->codec->fps, 4, false, false, true);
  388|    255|        bstr_xappend_asprintf(ctx, &dst, " %s fps", fps);
  389|    255|    }
  390|  5.22k|    if (s && s->codec->channels.num)
  ------------------
  |  Branch (390:9): [True: 5.22k, False: 0]
  |  Branch (390:14): [True: 1.79k, False: 3.43k]
  ------------------
  391|  1.79k|        bstr_xappend_asprintf(ctx, &dst, " %dch", s->codec->channels.num);
  392|  5.22k|    if (s && s->codec->samplerate)
  ------------------
  |  Branch (392:9): [True: 5.22k, False: 0]
  |  Branch (392:14): [True: 1.70k, False: 3.51k]
  ------------------
  393|  1.70k|        bstr_xappend_asprintf(ctx, &dst, " %d Hz", s->codec->samplerate);
  394|  5.22k|    if (s && s->codec->bitrate > 0 && s->codec->bitrate < INT_MAX - 500) {
  ------------------
  |  Branch (394:9): [True: 5.22k, False: 0]
  |  Branch (394:14): [True: 1.64k, False: 3.57k]
  |  Branch (394:39): [True: 1.64k, False: 1]
  ------------------
  395|  1.64k|        bstr_xappend_asprintf(ctx, &dst, " %d kbps", (s->codec->bitrate + 500) / 1000);
  396|  3.58k|    } else if (s && s->hls_bitrate > 0 && s->hls_bitrate < INT_MAX - 500) {
  ------------------
  |  Branch (396:16): [True: 3.58k, False: 0]
  |  Branch (396:21): [True: 0, False: 3.58k]
  |  Branch (396:43): [True: 0, False: 0]
  ------------------
  397|      0|        bstr_xappend_asprintf(ctx, &dst, " %d kbps", (s->hls_bitrate + 500) / 1000);
  398|      0|    }
  399|  5.22k|    bstr_xappend0(ctx, &dst, ")");
  400|       |
  401|  5.22k|    bool first = true;
  402|  5.22k|    if (t->default_track)
  ------------------
  |  Branch (402:9): [True: 0, False: 5.22k]
  ------------------
  403|      0|        ADD_FLAG(ctx, dst, "default", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  404|  5.22k|    if (t->forced_track)
  ------------------
  |  Branch (404:9): [True: 0, False: 5.22k]
  ------------------
  405|      0|        ADD_FLAG(ctx, dst, "forced", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  406|  5.22k|    if (t->dependent_track)
  ------------------
  |  Branch (406:9): [True: 0, False: 5.22k]
  ------------------
  407|      0|        ADD_FLAG(ctx, dst, "dependent", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  408|  5.22k|    if (t->visual_impaired_track)
  ------------------
  |  Branch (408:9): [True: 0, False: 5.22k]
  ------------------
  409|      0|        ADD_FLAG(ctx, dst, "visual-impaired", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  410|  5.22k|    if (t->hearing_impaired_track)
  ------------------
  |  Branch (410:9): [True: 0, False: 5.22k]
  ------------------
  411|      0|        ADD_FLAG(ctx, dst, "hearing-impaired", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  412|  5.22k|    if (t->is_external)
  ------------------
  |  Branch (412:9): [True: 0, False: 5.22k]
  ------------------
  413|      0|        ADD_FLAG(ctx, dst, "external", first);
  ------------------
  |  |  360|      0|#define ADD_FLAG(ctx, dst, flag, first) do {                           \
  |  |  361|      0|    bstr_xappend_asprintf(ctx, &dst, " %s%s", first ? "[" : "", flag); \
  |  |  ------------------
  |  |  |  Branch (361:47): [True: 0, False: 0]
  |  |  ------------------
  |  |  362|      0|    first = false;                                                     \
  |  |  363|      0|} while(0)
  |  |  ------------------
  |  |  |  Branch (363:9): [Folded - Ignored]
  |  |  ------------------
  ------------------
  414|  5.22k|    if (!first)
  ------------------
  |  Branch (414:9): [True: 0, False: 5.22k]
  ------------------
  415|      0|        bstr_xappend0(ctx, &dst, "]");
  416|       |
  417|  5.22k|    return bstrto0(ctx, dst);
  418|  5.22k|}
mp_find_non_filename_media_title:
  421|   545k|{
  422|   545k|    const char *name = mpctx->opts->media_title;
  423|   545k|    if (name && name[0])
  ------------------
  |  Branch (423:9): [True: 0, False: 545k]
  |  Branch (423:17): [True: 0, False: 0]
  ------------------
  424|      0|        return name;
  425|   545k|    if (mpctx->demuxer) {
  ------------------
  |  Branch (425:9): [True: 545k, False: 98]
  ------------------
  426|   545k|        name = mp_tags_get_str(mpctx->demuxer->metadata, "service_name");
  427|   545k|        if (name && name[0])
  ------------------
  |  Branch (427:13): [True: 0, False: 545k]
  |  Branch (427:21): [True: 0, False: 0]
  ------------------
  428|      0|            return name;
  429|   545k|        name = mp_tags_get_str(mpctx->demuxer->metadata, "title");
  430|   545k|        if (name && name[0])
  ------------------
  |  Branch (430:13): [True: 1.13k, False: 544k]
  |  Branch (430:21): [True: 1.13k, False: 0]
  ------------------
  431|  1.13k|            return name;
  432|   544k|        name = mp_tags_get_str(mpctx->demuxer->metadata, "icy-title");
  433|   544k|        if (name && name[0])
  ------------------
  |  Branch (433:13): [True: 0, False: 544k]
  |  Branch (433:21): [True: 0, False: 0]
  ------------------
  434|      0|            return name;
  435|   544k|    }
  436|   544k|    if (mpctx->playing && mpctx->playing->title)
  ------------------
  |  Branch (436:9): [True: 544k, False: 0]
  |  Branch (436:27): [True: 0, False: 544k]
  ------------------
  437|      0|        return mpctx->playing->title;
  438|   544k|    return NULL;
  439|   544k|}
misc.c:get_play_end_pts_setting:
   85|   445k|{
   86|   445k|    struct MPOpts *opts = mpctx->opts;
   87|   445k|    double end = rel_time_to_abs(mpctx, opts->play_end);
   88|   445k|    double length = rel_time_to_abs(mpctx, opts->play_length);
   89|   445k|    if (length != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|   445k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (89:9): [True: 0, False: 445k]
  ------------------
   90|      0|        double start = get_play_start_pts(mpctx);
   91|      0|        if (end == MP_NOPTS_VALUE || start + length < end)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (91:13): [True: 0, False: 0]
  |  Branch (91:38): [True: 0, False: 0]
  ------------------
   92|      0|            end = start + length;
   93|      0|    }
   94|   445k|    return end;
   95|   445k|}

term_osd_clear_subs:
  121|  96.7k|{
  122|  96.7k|    term_osd_set_subs(mpctx, NULL, 0);
  123|  96.7k|    term_osd_set_subs(mpctx, NULL, 1);
  124|  96.7k|}
term_osd_set_subs:
  127|   193k|{
  128|   193k|    if (mpctx->video_out || !text || !mpctx->opts->subs_shared->sub_visibility[order])
  ------------------
  |  Branch (128:9): [True: 4.59k, False: 188k]
  |  Branch (128:29): [True: 188k, False: 0]
  |  Branch (128:38): [True: 0, False: 0]
  ------------------
  129|   193k|        text = ""; // disable
  130|   193k|    if (strcmp(mpctx->term_osd_subs[order] ? mpctx->term_osd_subs[order] : "", text) == 0)
  ------------------
  |  Branch (130:9): [True: 193k, False: 0]
  |  Branch (130:16): [True: 0, False: 193k]
  ------------------
  131|   193k|        return;
  132|      0|    talloc_replace(mpctx, mpctx->term_osd_subs[order], text);
  ------------------
  |  |   54|      0|#define talloc_replace                  ta_replace
  |  |  ------------------
  |  |  |  |  106|      0|    do {                                                \
  |  |  |  |  107|      0|        if (!(str)) {                                   \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (107:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  108|      0|            (str) = ta_xstrdup((ta_parent), (replace)); \
  |  |  |  |  109|      0|        } else {                                        \
  |  |  |  |  110|      0|            *(str) = '\0';                              \
  |  |  |  |  111|      0|            ta_xstrdup_append(&(str), (replace));       \
  |  |  |  |  ------------------
  |  |  |  |  |  |  123|      0|#define ta_xstrdup_append(...)          ta_oom_b(ta_strdup_append(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  112|      0|        }                                               \
  |  |  |  |  113|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  133|      0|    term_osd_update(mpctx);
  134|      0|}
set_osd_bar_chapters:
  375|  97.7k|{
  376|  97.7k|    if (mpctx->osd_progbar.type != type)
  ------------------
  |  Branch (376:9): [True: 97.7k, False: 0]
  ------------------
  377|  97.7k|        return;
  378|       |
  379|      0|    mpctx->osd_progbar.num_stops = 0;
  380|      0|    double len = get_time_length(mpctx);
  381|      0|    if (len > 0) {
  ------------------
  |  Branch (381:9): [True: 0, False: 0]
  ------------------
  382|       |        // Always render the loop points, even if they're incomplete.
  383|      0|        double ab[2];
  384|      0|        bool valid = get_ab_loop_times(mpctx, ab);
  385|      0|        for (int n = 0; n < 2; n++) {
  ------------------
  |  Branch (385:25): [True: 0, False: 0]
  ------------------
  386|      0|            if (ab[n] != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (386:17): [True: 0, False: 0]
  ------------------
  387|      0|                MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  388|      0|                                 mpctx->osd_progbar.num_stops, ab[n] / len);
  389|      0|            }
  390|      0|        }
  391|      0|        if (!valid) {
  ------------------
  |  Branch (391:13): [True: 0, False: 0]
  ------------------
  392|      0|            int num = get_chapter_count(mpctx);
  393|      0|            for (int n = 0; n < num; n++) {
  ------------------
  |  Branch (393:29): [True: 0, False: 0]
  ------------------
  394|      0|                double time = chapter_start_time(mpctx, n);
  395|      0|                if (time >= 0) {
  ------------------
  |  Branch (395:21): [True: 0, False: 0]
  ------------------
  396|      0|                    float pos = time / len;
  397|      0|                    MP_TARRAY_APPEND(mpctx, mpctx->osd_progbar.stops,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  398|      0|                                     mpctx->osd_progbar.num_stops, pos);
  399|      0|                }
  400|      0|            }
  401|      0|        }
  402|      0|    }
  403|      0|    osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
  404|      0|    mp_wakeup_core(mpctx);
  405|      0|}
update_osd_msg:
  501|   212k|{
  502|   212k|    struct MPOpts *opts = mpctx->opts;
  503|   212k|    struct osd_state *osd = mpctx->osd;
  504|       |
  505|   212k|    double now = mp_time_sec();
  506|       |
  507|   212k|    if (!mpctx->osd_force_update) {
  ------------------
  |  Branch (507:9): [True: 140k, False: 71.9k]
  ------------------
  508|       |        // Assume nothing is going on at all.
  509|   140k|        if (!mpctx->osd_idle_update)
  ------------------
  |  Branch (509:13): [True: 1.25k, False: 138k]
  ------------------
  510|  1.25k|            return;
  511|       |
  512|   138k|        double delay = 0.050; // update the OSD at most this often
  513|   138k|        double diff = now - mpctx->osd_last_update;
  514|   138k|        if (diff < delay) {
  ------------------
  |  Branch (514:13): [True: 131k, False: 7.33k]
  ------------------
  515|   131k|            mp_set_timeout(mpctx, delay - diff);
  516|   131k|            return;
  517|   131k|        }
  518|   138k|    }
  519|  79.3k|    mpctx->osd_force_update = false;
  520|  79.3k|    mpctx->osd_idle_update = false;
  521|  79.3k|    mpctx->osd_last_update = now;
  522|       |
  523|  79.3k|    if (mpctx->osd_visible) {
  ------------------
  |  Branch (523:9): [True: 0, False: 79.3k]
  ------------------
  524|      0|        double sleep = mpctx->osd_visible - now;
  525|      0|        if (sleep > 0) {
  ------------------
  |  Branch (525:13): [True: 0, False: 0]
  ------------------
  526|      0|            mp_set_timeout(mpctx, sleep);
  527|      0|            mpctx->osd_idle_update = true;
  528|      0|        } else {
  529|      0|            mpctx->osd_visible = 0;
  530|      0|            mpctx->osd_progbar.type = -1; // disable
  531|      0|            osd_set_progbar(mpctx->osd, &mpctx->osd_progbar);
  532|      0|        }
  533|      0|    }
  534|       |
  535|  79.3k|    if (mpctx->osd_function_visible) {
  ------------------
  |  Branch (535:9): [True: 0, False: 79.3k]
  ------------------
  536|      0|        double sleep = mpctx->osd_function_visible - now;
  537|      0|        if (sleep > 0) {
  ------------------
  |  Branch (537:13): [True: 0, False: 0]
  ------------------
  538|      0|            mp_set_timeout(mpctx, sleep);
  539|      0|            mpctx->osd_idle_update = true;
  540|      0|        } else {
  541|      0|            mpctx->osd_function_visible = 0;
  542|      0|            mpctx->osd_function = 0;
  543|      0|        }
  544|      0|    }
  545|       |
  546|  79.3k|    if (mpctx->osd_msg_next_duration > 0) {
  ------------------
  |  Branch (546:9): [True: 0, False: 79.3k]
  ------------------
  547|       |        // This is done to avoid cutting the OSD message short if slow commands
  548|       |        // are executed between setting the OSD message and showing it.
  549|      0|        mpctx->osd_msg_visible = now + mpctx->osd_msg_next_duration;
  550|      0|        mpctx->osd_msg_next_duration = 0;
  551|      0|    }
  552|       |
  553|  79.3k|    if (mpctx->osd_msg_visible) {
  ------------------
  |  Branch (553:9): [True: 0, False: 79.3k]
  ------------------
  554|      0|        double sleep = mpctx->osd_msg_visible - now;
  555|      0|        if (sleep > 0) {
  ------------------
  |  Branch (555:13): [True: 0, False: 0]
  ------------------
  556|      0|            mp_set_timeout(mpctx, sleep);
  557|      0|            mpctx->osd_idle_update = true;
  558|      0|        } else {
  559|      0|            talloc_free(mpctx->osd_msg_text);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  560|      0|            mpctx->osd_msg_text = NULL;
  561|      0|            mpctx->osd_msg_visible = 0;
  562|      0|            mpctx->osd_show_pos = false;
  563|      0|        }
  564|      0|    }
  565|       |
  566|  79.3k|    add_seek_osd_messages(mpctx);
  567|       |
  568|  79.3k|    if (mpctx->osd_progbar.type == OSD_BAR_SEEK) {
  ------------------
  |  Branch (568:9): [True: 0, False: 79.3k]
  ------------------
  569|      0|        double pos = get_current_pos_ratio(mpctx, false);
  570|      0|        update_osd_bar(mpctx, OSD_BAR_SEEK, 0, 1, MPCLAMP(pos, 0, 1));
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  571|      0|    }
  572|       |
  573|  79.3k|    term_osd_set_text_lazy(mpctx, mpctx->osd_msg_text);
  574|  79.3k|    term_osd_print_status_lazy(mpctx);
  575|  79.3k|    term_osd_update(mpctx);
  576|       |
  577|  79.3k|    if (!opts->video_osd)
  ------------------
  |  Branch (577:9): [True: 78.9k, False: 398]
  ------------------
  578|  78.9k|        return;
  579|       |
  580|    398|    int osd_level = opts->osd_level;
  581|    398|    if (mpctx->osd_show_pos)
  ------------------
  |  Branch (581:9): [True: 0, False: 398]
  ------------------
  582|      0|        osd_level = 3;
  583|       |
  584|    398|    char *text = NULL;
  585|    398|    sadd_osd_status(&text, mpctx, osd_level);
  586|    398|    if (mpctx->osd_msg_text && mpctx->osd_msg_text[0]) {
  ------------------
  |  Branch (586:9): [True: 0, False: 398]
  |  Branch (586:32): [True: 0, False: 0]
  ------------------
  587|      0|        text = talloc_asprintf_append(text, "%s%s", text ? "\n" : "",
  ------------------
  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  ------------------
  |  Branch (587:53): [True: 0, False: 0]
  ------------------
  588|      0|                                      mpctx->osd_msg_text);
  589|      0|    }
  590|    398|    osd_set_text(osd, text);
  591|    398|    talloc_free(text);
  ------------------
  |  |   47|    398|#define talloc_free                     ta_free
  ------------------
  592|    398|}
osd.c:term_osd_update:
   76|  79.3k|{
   77|  79.3k|    int num_parts = 0;
   78|  79.3k|    char *parts[4] = {0};
   79|       |
   80|  79.3k|    if (!mpctx->opts->use_terminal)
  ------------------
  |  Branch (80:9): [True: 79.3k, False: 0]
  ------------------
   81|  79.3k|        return;
   82|       |
   83|      0|    if (!term_osd_empty(mpctx->term_osd_subs[0]))
  ------------------
  |  Branch (83:9): [True: 0, False: 0]
  ------------------
   84|      0|        parts[num_parts++] = mpctx->term_osd_subs[0];
   85|      0|    if (!term_osd_empty(mpctx->term_osd_subs[1]))
  ------------------
  |  Branch (85:9): [True: 0, False: 0]
  ------------------
   86|      0|        parts[num_parts++] = mpctx->term_osd_subs[1];
   87|      0|    if (!term_osd_empty(mpctx->term_osd_text))
  ------------------
  |  Branch (87:9): [True: 0, False: 0]
  ------------------
   88|      0|        parts[num_parts++] = mpctx->term_osd_text;
   89|      0|    if (!term_osd_empty(mpctx->term_osd_status))
  ------------------
  |  Branch (89:9): [True: 0, False: 0]
  ------------------
   90|      0|        parts[num_parts++] = mpctx->term_osd_status;
   91|       |
   92|      0|    char *s = join_lines(mpctx, parts, num_parts);
   93|       |
   94|      0|    if (strcmp(mpctx->term_osd_contents, s) == 0 &&
  ------------------
  |  Branch (94:9): [True: 0, False: 0]
  ------------------
   95|      0|        mp_msg_has_status_line(mpctx->global))
  ------------------
  |  Branch (95:9): [True: 0, False: 0]
  ------------------
   96|      0|    {
   97|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
   98|      0|    } else {
   99|      0|        talloc_free(mpctx->term_osd_contents);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  100|      0|        mpctx->term_osd_contents = s;
  101|      0|        mp_msg(mpctx->statusline, MSGL_STATUS, "%s", s);
  102|      0|    }
  103|      0|}
osd.c:add_seek_osd_messages:
  470|  79.3k|{
  471|  79.3k|    if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_BAR) {
  ------------------
  |  Branch (471:9): [True: 0, False: 79.3k]
  ------------------
  472|      0|        double pos = get_current_pos_ratio(mpctx, false);
  473|      0|        set_osd_bar(mpctx, OSD_BAR_SEEK, 0, 1, 0, MPCLAMP(pos, 0, 1));
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  474|      0|        set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
  475|      0|    }
  476|  79.3k|    if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) {
  ------------------
  |  Branch (476:9): [True: 0, False: 79.3k]
  ------------------
  477|       |        // Never in term-osd mode
  478|      0|        bool video_osd = mpctx->video_out && mpctx->opts->video_osd;
  ------------------
  |  Branch (478:26): [True: 0, False: 0]
  |  Branch (478:46): [True: 0, False: 0]
  ------------------
  479|      0|        if (video_osd && mpctx->opts->term_osd != 1) {
  ------------------
  |  Branch (479:13): [True: 0, False: 0]
  |  Branch (479:26): [True: 0, False: 0]
  ------------------
  480|      0|            if (set_osd_msg(mpctx, 1, mpctx->opts->osd_duration, ""))
  ------------------
  |  Branch (480:17): [True: 0, False: 0]
  ------------------
  481|      0|                mpctx->osd_show_pos = true;
  482|      0|        }
  483|      0|    }
  484|  79.3k|    if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_CHAPTER_TEXT) {
  ------------------
  |  Branch (484:9): [True: 0, False: 79.3k]
  ------------------
  485|      0|        char *chapter = chapter_display_name(mpctx, get_current_chapter(mpctx));
  486|      0|        set_osd_msg(mpctx, 1, mpctx->opts->osd_duration,
  487|      0|                     "Chapter: %s", chapter);
  488|      0|        talloc_free(chapter);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  489|      0|    }
  490|  79.3k|    if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_CURRENT_FILE) {
  ------------------
  |  Branch (490:9): [True: 0, False: 79.3k]
  ------------------
  491|      0|        if (mpctx->filename) {
  ------------------
  |  Branch (491:13): [True: 0, False: 0]
  ------------------
  492|      0|            set_osd_msg(mpctx, 1, mpctx->opts->osd_duration, "%s",
  493|      0|                        mpctx->filename);
  494|      0|        }
  495|      0|    }
  496|  79.3k|    mpctx->add_osd_seek_info = 0;
  497|  79.3k|}
osd.c:term_osd_set_text_lazy:
  137|  79.3k|{
  138|  79.3k|    bool video_osd = mpctx->video_out && mpctx->opts->video_osd;
  ------------------
  |  Branch (138:22): [True: 72.2k, False: 7.13k]
  |  Branch (138:42): [True: 0, False: 72.2k]
  ------------------
  139|  79.3k|    if ((video_osd && mpctx->opts->term_osd != 1) || !text)
  ------------------
  |  Branch (139:10): [True: 0, False: 79.3k]
  |  Branch (139:23): [True: 0, False: 0]
  |  Branch (139:54): [True: 79.3k, False: 0]
  ------------------
  140|  79.3k|        text = ""; // disable
  141|  79.3k|    talloc_replace(mpctx, mpctx->term_osd_text, text);
  ------------------
  |  |   54|  79.3k|#define talloc_replace                  ta_replace
  |  |  ------------------
  |  |  |  |  106|  79.3k|    do {                                                \
  |  |  |  |  107|  79.3k|        if (!(str)) {                                   \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (107:13): [True: 5.81k, False: 73.5k]
  |  |  |  |  ------------------
  |  |  |  |  108|  5.81k|            (str) = ta_xstrdup((ta_parent), (replace)); \
  |  |  |  |  109|  73.5k|        } else {                                        \
  |  |  |  |  110|  73.5k|            *(str) = '\0';                              \
  |  |  |  |  111|  73.5k|            ta_xstrdup_append(&(str), (replace));       \
  |  |  |  |  ------------------
  |  |  |  |  |  |  123|  73.5k|#define ta_xstrdup_append(...)          ta_oom_b(ta_strdup_append(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  112|  73.5k|        }                                               \
  |  |  |  |  113|  79.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (113:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  142|  79.3k|}
osd.c:term_osd_print_status_lazy:
  279|  79.3k|{
  280|  79.3k|    struct MPOpts *opts = mpctx->opts;
  281|       |
  282|  79.3k|    term_osd_update_title(mpctx);
  283|  79.3k|    update_window_title(mpctx, false);
  284|  79.3k|    update_vo_playback_state(mpctx);
  285|       |
  286|  79.3k|    if (!opts->use_terminal)
  ------------------
  |  Branch (286:9): [True: 79.3k, False: 0]
  ------------------
  287|  79.3k|        return;
  288|       |
  289|      0|    if (opts->quiet || !mpctx->playback_initialized || !mpctx->playing_msg_shown)
  ------------------
  |  Branch (289:9): [True: 0, False: 0]
  |  Branch (289:24): [True: 0, False: 0]
  |  Branch (289:56): [True: 0, False: 0]
  ------------------
  290|      0|    {
  291|      0|        if (!mpctx->playing)
  ------------------
  |  Branch (291:13): [True: 0, False: 0]
  ------------------
  292|      0|            term_osd_set_status_lazy(mpctx, "");
  293|      0|        return;
  294|      0|    }
  295|       |
  296|      0|    char *line = get_term_status_msg(mpctx);
  297|       |
  298|      0|    if (opts->term_osd_bar) {
  ------------------
  |  Branch (298:9): [True: 0, False: 0]
  ------------------
  299|      0|        saddf(&line, "\n");
  ------------------
  |  |   47|      0|#define saddf(var, ...) (*(var) = talloc_asprintf_append((*var), __VA_ARGS__))
  |  |  ------------------
  |  |  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  |  |  ------------------
  ------------------
  300|      0|        int w = 80, h = 24;
  301|      0|        terminal_get_size(&w, &h);
  302|      0|        add_term_osd_bar(mpctx, &line, w);
  303|      0|    }
  304|       |
  305|      0|    term_osd_set_status_lazy(mpctx, line);
  306|      0|    talloc_free(line);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  307|      0|}
osd.c:term_osd_update_title:
  106|  79.3k|{
  107|  79.3k|    if (!mpctx->opts->use_terminal)
  ------------------
  |  Branch (107:9): [True: 79.3k, False: 0]
  ------------------
  108|  79.3k|        return;
  109|       |
  110|      0|    char *s = mp_property_expand_escaped_string(mpctx, mpctx->opts->term_title);
  111|      0|    if (bstr_equals(bstr0(s), bstr0(mpctx->term_osd_title))) {
  ------------------
  |  Branch (111:9): [True: 0, False: 0]
  ------------------
  112|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  113|      0|        return;
  114|      0|    }
  115|       |
  116|      0|    mp_msg_set_term_title(mpctx->statusline, s);
  117|      0|    mpctx->term_osd_title = talloc_steal(mpctx, s);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  118|      0|}
osd.c:sadd_osd_status:
  436|    398|{
  437|    398|    mp_assert(level >= 0 && level <= 3);
  ------------------
  |  |   41|    398|#define mp_assert assert
  ------------------
  438|    398|    if (level == 0)
  ------------------
  |  Branch (438:9): [True: 0, False: 398]
  ------------------
  439|      0|        return;
  440|    398|    char *msg = mpctx->opts->osd_msg[level - 1];
  441|       |
  442|    398|    if (msg && msg[0]) {
  ------------------
  |  Branch (442:9): [True: 0, False: 398]
  |  Branch (442:16): [True: 0, False: 0]
  ------------------
  443|      0|        char *text = mp_property_expand_escaped_string(mpctx, msg);
  444|      0|        *buffer = talloc_strdup_append(*buffer, text);
  ------------------
  |  |   57|      0|#define talloc_strdup_append            ta_talloc_strdup_append
  ------------------
  445|      0|        talloc_free(text);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  446|    398|    } else if (level >= 2) {
  ------------------
  |  Branch (446:16): [True: 0, False: 398]
  ------------------
  447|      0|        bool fractions = mpctx->opts->osd_fractions;
  448|      0|        char sym[10];
  449|      0|        get_current_osd_sym(mpctx, sym, sizeof(sym));
  450|      0|        saddf(buffer, "%s ", sym);
  ------------------
  |  |   47|      0|#define saddf(var, ...) (*(var) = talloc_asprintf_append((*var), __VA_ARGS__))
  |  |  ------------------
  |  |  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  |  |  ------------------
  ------------------
  451|      0|        char *custom_msg = mpctx->opts->osd_status_msg;
  452|      0|        if (custom_msg && level == 3) {
  ------------------
  |  Branch (452:13): [True: 0, False: 0]
  |  Branch (452:27): [True: 0, False: 0]
  ------------------
  453|      0|            char *text = mp_property_expand_escaped_string(mpctx, custom_msg);
  454|      0|            *buffer = talloc_strdup_append(*buffer, text);
  ------------------
  |  |   57|      0|#define talloc_strdup_append            ta_talloc_strdup_append
  ------------------
  455|      0|            talloc_free(text);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  456|      0|        } else {
  457|      0|            sadd_hhmmssff(buffer, get_playback_time(mpctx), fractions);
  458|      0|            if (level == 3) {
  ------------------
  |  Branch (458:17): [True: 0, False: 0]
  ------------------
  459|      0|                saddf(buffer, " / ");
  ------------------
  |  |   47|      0|#define saddf(var, ...) (*(var) = talloc_asprintf_append((*var), __VA_ARGS__))
  |  |  ------------------
  |  |  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  |  |  ------------------
  ------------------
  460|      0|                sadd_hhmmssff(buffer, get_time_length(mpctx), fractions);
  461|      0|                sadd_percentage(buffer, get_current_pos_ratio(mpctx, false));
  462|      0|            }
  463|      0|        }
  464|      0|    }
  465|    398|}

mp_wait_events:
   54|   138k|{
   55|   138k|    mp_client_send_property_changes(mpctx);
   56|       |
   57|   138k|    stats_event(mpctx->stats, "iterations");
   58|       |
   59|   138k|    bool sleeping = mpctx->sleeptime > 0;
   60|   138k|    if (sleeping)
  ------------------
  |  Branch (60:9): [True: 130k, False: 7.83k]
  ------------------
   61|   138k|        MP_STATS(mpctx, "start sleep");
  ------------------
  |  |   95|   130k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   130k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   62|       |
   63|   138k|    mp_dispatch_queue_process(mpctx->dispatch, mpctx->sleeptime);
   64|       |
   65|   138k|    mpctx->sleeptime = INFINITY;
   66|       |
   67|   138k|    if (sleeping)
  ------------------
  |  Branch (67:9): [True: 130k, False: 7.83k]
  ------------------
   68|   138k|        MP_STATS(mpctx, "end sleep");
  ------------------
  |  |   95|   130k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   130k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   69|   138k|}
mp_set_timeout:
   75|   451k|{
   76|   451k|    if (mpctx->sleeptime > sleeptime) {
  ------------------
  |  Branch (76:9): [True: 295k, False: 155k]
  ------------------
   77|   295k|        mpctx->sleeptime = sleeptime;
   78|   295k|        int64_t abstime = mp_time_ns_add(mp_time_ns(), sleeptime);
   79|   295k|        mp_dispatch_adjust_timeout(mpctx->dispatch, abstime);
   80|   295k|    }
   81|   451k|}
mp_wakeup_core:
   87|   546k|{
   88|   546k|    mp_dispatch_interrupt(mpctx->dispatch);
   89|   546k|}
mp_wakeup_core_cb:
   93|   166k|{
   94|   166k|    struct MPContext *mpctx = ctx;
   95|   166k|    mp_wakeup_core(mpctx);
   96|   166k|}
mp_core_lock:
   99|  4.53k|{
  100|  4.53k|    mp_dispatch_lock(mpctx->dispatch);
  101|  4.53k|}
mp_core_unlock:
  104|  4.53k|{
  105|  4.53k|    mp_dispatch_unlock(mpctx->dispatch);
  106|  4.53k|}
handle_option_callbacks:
  127|   143k|{
  128|   148k|    for (int i = 0; i < mpctx->num_option_callbacks; i++)
  ------------------
  |  Branch (128:21): [True: 5.81k, False: 143k]
  ------------------
  129|  5.81k|        mp_option_run_callback(mpctx, &mpctx->option_callbacks[i]);
  130|   143k|    mpctx->num_option_callbacks = 0;
  131|   143k|}
get_relative_time:
  134|  77.6k|{
  135|  77.6k|    int64_t new_time = mp_time_ns();
  136|  77.6k|    int64_t delta = new_time - mpctx->last_time;
  137|  77.6k|    mpctx->last_time = new_time;
  138|  77.6k|    return delta * 1e-9;
  139|  77.6k|}
update_core_idle_state:
  142|   383k|{
  143|   383k|    bool eof = mpctx->video_status == STATUS_EOF &&
  ------------------
  |  Branch (143:16): [True: 302k, False: 80.5k]
  ------------------
  144|   383k|               mpctx->audio_status == STATUS_EOF;
  ------------------
  |  Branch (144:16): [True: 288k, False: 14.9k]
  ------------------
  145|   383k|    bool active = !mpctx->paused && mpctx->restart_complete &&
  ------------------
  |  Branch (145:19): [True: 383k, False: 116]
  |  Branch (145:37): [True: 86.7k, False: 296k]
  ------------------
  146|   383k|                  !mpctx->stop_play && mpctx->in_playloop && !eof;
  ------------------
  |  Branch (146:19): [True: 80.8k, False: 5.92k]
  |  Branch (146:40): [True: 80.8k, False: 0]
  |  Branch (146:62): [True: 80.0k, False: 835]
  ------------------
  147|       |
  148|   383k|    if (mpctx->playback_active != active) {
  ------------------
  |  Branch (148:9): [True: 4.28k, False: 379k]
  ------------------
  149|  4.28k|        mpctx->playback_active = active;
  150|       |
  151|  4.28k|        update_screensaver_state(mpctx);
  152|       |
  153|  4.28k|        mp_notify(mpctx, MP_EVENT_CORE_IDLE, NULL);
  154|  4.28k|    }
  155|   383k|}
get_internal_paused:
  158|   104k|{
  159|   104k|    return mpctx->opts->pause || mpctx->paused_for_cache;
  ------------------
  |  Branch (159:12): [True: 0, False: 104k]
  |  Branch (159:34): [True: 21, False: 104k]
  ------------------
  160|   104k|}
set_pause_state:
  164|  97.7k|{
  165|  97.7k|    struct MPOpts *opts = mpctx->opts;
  166|       |
  167|  97.7k|    opts->pause = user_pause;
  168|       |
  169|  97.7k|    bool internal_paused = get_internal_paused(mpctx);
  170|  97.7k|    if (internal_paused != mpctx->paused) {
  ------------------
  |  Branch (170:9): [True: 42, False: 97.7k]
  ------------------
  171|     42|        mpctx->paused = internal_paused;
  172|       |
  173|     42|        if (mpctx->ao) {
  ------------------
  |  Branch (173:13): [True: 0, False: 42]
  ------------------
  174|      0|            bool eof = mpctx->audio_status == STATUS_EOF;
  175|      0|            ao_set_paused(mpctx->ao, internal_paused, eof);
  176|      0|        }
  177|       |
  178|     42|        if (mpctx->video_out)
  ------------------
  |  Branch (178:13): [True: 42, False: 0]
  ------------------
  179|     42|            vo_set_paused(mpctx->video_out, internal_paused);
  180|       |
  181|     42|        mpctx->osd_function = 0;
  182|     42|        mpctx->osd_force_update = true;
  183|       |
  184|     42|        mp_wakeup_core(mpctx);
  185|       |
  186|     42|        if (internal_paused) {
  ------------------
  |  Branch (186:13): [True: 21, False: 21]
  ------------------
  187|     21|            mpctx->step_frames = 0;
  188|     21|            mpctx->time_frame -= get_relative_time(mpctx);
  189|     21|        } else {
  190|     21|            (void)get_relative_time(mpctx); // ignore time that passed during pause
  191|     21|        }
  192|     42|    }
  193|       |
  194|  97.7k|    update_core_idle_state(mpctx);
  195|       |
  196|  97.7k|    m_config_notify_change_opt_ptr(mpctx->mconfig, &opts->pause);
  197|  97.7k|}
update_internal_pause_state:
  200|  97.7k|{
  201|  97.7k|    set_pause_state(mpctx, mpctx->opts->pause);
  202|  97.7k|}
update_screensaver_state:
  205|  15.0k|{
  206|  15.0k|    if (!mpctx->video_out)
  ------------------
  |  Branch (206:9): [True: 8.20k, False: 6.88k]
  ------------------
  207|  8.20k|        return;
  208|       |
  209|  6.88k|    bool saver_state = (!mpctx->playback_active || !mpctx->opts->stop_screensaver) &&
  ------------------
  |  Branch (209:25): [True: 5.46k, False: 1.41k]
  |  Branch (209:52): [True: 0, False: 1.41k]
  ------------------
  210|  6.88k|                       mpctx->opts->stop_screensaver != 2;
  ------------------
  |  Branch (210:24): [True: 5.46k, False: 0]
  ------------------
  211|  6.88k|    vo_control_async(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
  ------------------
  |  Branch (211:40): [True: 5.46k, False: 1.41k]
  ------------------
  212|  6.88k|                                                   : VOCTRL_KILL_SCREENSAVER, NULL);
  213|  6.88k|}
reset_playback_state:
  241|  94.7k|{
  242|  94.7k|    mp_filter_reset(mpctx->filter_root);
  243|       |
  244|  94.7k|    reset_video_state(mpctx);
  245|  94.7k|    reset_audio_state(mpctx);
  246|  94.7k|    reset_subtitle_state(mpctx);
  247|       |
  248|  94.7k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (248:21): [True: 0, False: 94.7k]
  ------------------
  249|      0|        struct track *t = mpctx->tracks[n];
  250|       |        // (Often, but not always, this is redundant and also done elsewhere.)
  251|      0|        if (t->dec)
  ------------------
  |  Branch (251:13): [True: 0, False: 0]
  ------------------
  252|      0|            mp_decoder_wrapper_set_play_dir(t->dec, mpctx->play_dir);
  253|      0|        if (t->d_sub)
  ------------------
  |  Branch (253:13): [True: 0, False: 0]
  ------------------
  254|      0|            sub_set_play_dir(t->d_sub, mpctx->play_dir);
  255|      0|    }
  256|       |
  257|       |    // May need unpause first
  258|  94.7k|    if (mpctx->paused_for_cache)
  ------------------
  |  Branch (258:9): [True: 0, False: 94.7k]
  ------------------
  259|      0|        update_internal_pause_state(mpctx);
  260|       |
  261|  94.7k|    mpctx->hrseek_active = false;
  262|  94.7k|    mpctx->hrseek_lastframe = false;
  263|  94.7k|    mpctx->hrseek_backstep = false;
  264|  94.7k|    mpctx->current_seek = (struct seek_params){0};
  265|  94.7k|    mpctx->playback_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  94.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  266|  94.7k|    mpctx->step_frames = 0;
  267|  94.7k|    mpctx->ab_loop_clip = true;
  268|  94.7k|    mpctx->restart_complete = false;
  269|  94.7k|    mpctx->paused_for_cache = false;
  270|  94.7k|    mpctx->cache_buffer = 100;
  271|  94.7k|    mpctx->cache_update_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  94.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  272|       |
  273|  94.7k|    encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
  274|       |
  275|  94.7k|    update_internal_pause_state(mpctx);
  276|  94.7k|    update_core_idle_state(mpctx);
  277|  94.7k|}
execute_queued_seek:
  494|  93.3k|{
  495|  93.3k|    if (mpctx->seek.type) {
  ------------------
  |  Branch (495:9): [True: 0, False: 93.3k]
  ------------------
  496|      0|        bool queued_hr_seek = mpctx->seek.exact != MPSEEK_KEYFRAME;
  497|       |        // Let explicitly imprecise seeks cancel precise seeks:
  498|      0|        if (mpctx->hrseek_active && !queued_hr_seek)
  ------------------
  |  Branch (498:13): [True: 0, False: 0]
  |  Branch (498:37): [True: 0, False: 0]
  ------------------
  499|      0|            mpctx->start_timestamp = -1e9;
  500|       |        // If the user seeks continuously (keeps arrow key down) try to finish
  501|       |        // showing a frame from one location before doing another seek (instead
  502|       |        // of never updating the screen).
  503|      0|        if ((mpctx->seek.flags & MPSEEK_FLAG_DELAY) &&
  ------------------
  |  Branch (503:13): [True: 0, False: 0]
  ------------------
  504|      0|            mp_time_sec() - mpctx->start_timestamp < 0.3)
  ------------------
  |  Branch (504:13): [True: 0, False: 0]
  ------------------
  505|      0|        {
  506|       |            // Wait until a video frame is available and has been shown.
  507|      0|            if (mpctx->video_status < STATUS_PLAYING)
  ------------------
  |  Branch (507:17): [True: 0, False: 0]
  ------------------
  508|      0|                return;
  509|       |            // On A/V hr-seeks, always wait for the full result, to avoid corner
  510|       |            // cases when seeking past EOF (we want it to determine that EOF
  511|       |            // actually happened, instead of overwriting it with the new seek).
  512|      0|            if (mpctx->hrseek_active && queued_hr_seek && mpctx->vo_chain &&
  ------------------
  |  Branch (512:17): [True: 0, False: 0]
  |  Branch (512:41): [True: 0, False: 0]
  |  Branch (512:59): [True: 0, False: 0]
  ------------------
  513|      0|                mpctx->ao_chain && !mpctx->restart_complete)
  ------------------
  |  Branch (513:17): [True: 0, False: 0]
  |  Branch (513:36): [True: 0, False: 0]
  ------------------
  514|      0|                return;
  515|      0|        }
  516|      0|        mp_seek(mpctx, mpctx->seek);
  517|      0|        mpctx->seek = (struct seek_params){0};
  518|      0|    }
  519|  93.3k|}
get_time_length:
  523|   969k|{
  524|   969k|    struct demuxer *demuxer = mpctx->demuxer;
  525|   969k|    return demuxer && demuxer->duration >= 0 ? demuxer->duration : MP_NOPTS_VALUE;
  ------------------
  |  |   38|  1.11k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (525:12): [True: 969k, False: 0]
  |  Branch (525:23): [True: 967k, False: 1.11k]
  ------------------
  526|   969k|}
get_current_time:
  543|   180k|{
  544|   180k|    if (!mpctx->demuxer)
  ------------------
  |  Branch (544:9): [True: 0, False: 180k]
  ------------------
  545|      0|        return MP_NOPTS_VALUE;
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  546|   180k|    if (mpctx->playback_pts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|   180k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (546:9): [True: 149k, False: 30.6k]
  ------------------
  547|   149k|        return mpctx->playback_pts * mpctx->play_dir;
  548|  30.6k|    return mpctx->last_seek_pts;
  549|   180k|}
get_current_pos_ratio:
  569|  72.0k|{
  570|  72.0k|    struct demuxer *demuxer = mpctx->demuxer;
  571|  72.0k|    if (!demuxer)
  ------------------
  |  Branch (571:9): [True: 0, False: 72.0k]
  ------------------
  572|      0|        return -1;
  573|  72.0k|    double ret = -1;
  574|  72.0k|    double start = 0;
  575|  72.0k|    double len = get_time_length(mpctx);
  576|  72.0k|    if (use_range) {
  ------------------
  |  Branch (576:9): [True: 0, False: 72.0k]
  ------------------
  577|      0|        double startpos = get_play_start_pts(mpctx);
  578|      0|        double endpos = get_play_end_pts(mpctx);
  579|      0|        if (endpos > MPMAX(0, len))
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (579:13): [True: 0, False: 0]
  ------------------
  580|      0|            endpos = MPMAX(0, len);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  581|      0|        if (endpos < startpos)
  ------------------
  |  Branch (581:13): [True: 0, False: 0]
  ------------------
  582|      0|            endpos = startpos;
  583|      0|        start = startpos;
  584|      0|        len = endpos - startpos;
  585|      0|    }
  586|  72.0k|    double pos = get_current_time(mpctx);
  587|  72.0k|    if (len > 0)
  ------------------
  |  Branch (587:9): [True: 71.9k, False: 71]
  ------------------
  588|  71.9k|        ret = MPCLAMP((pos - start) / len, 0, 1);
  ------------------
  |  |   45|  71.9k|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 71.9k]
  |  |  |  Branch (45:56): [True: 0, False: 71.9k]
  |  |  ------------------
  ------------------
  589|  72.0k|    if (ret < 0) {
  ------------------
  |  Branch (589:9): [True: 71, False: 71.9k]
  ------------------
  590|     71|        int64_t size = demuxer->filesize;
  591|     71|        if (size > 0 && demuxer->filepos >= 0)
  ------------------
  |  Branch (591:13): [True: 71, False: 0]
  |  Branch (591:25): [True: 71, False: 0]
  ------------------
  592|     71|            ret = MPCLAMP(demuxer->filepos / (double)size, 0, 1);
  ------------------
  |  |   45|     71|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 71]
  |  |  |  Branch (45:56): [True: 0, False: 71]
  |  |  ------------------
  ------------------
  593|     71|    }
  594|  72.0k|    if (use_range) {
  ------------------
  |  Branch (594:9): [True: 0, False: 72.0k]
  ------------------
  595|      0|        if (mpctx->opts->play_frames > 0)
  ------------------
  |  Branch (595:13): [True: 0, False: 0]
  ------------------
  596|      0|            ret = MPMAX(ret, 1.0 -
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  597|      0|                    mpctx->max_frames / (double) mpctx->opts->play_frames);
  598|      0|    }
  599|  72.0k|    return ret;
  600|  72.0k|}
get_current_chapter:
  604|  90.3k|{
  605|  90.3k|    if (!mpctx->num_chapters)
  ------------------
  |  Branch (605:9): [True: 88.9k, False: 1.36k]
  ------------------
  606|  88.9k|        return -2;
  607|  1.36k|    double current_pts = get_current_time(mpctx);
  608|  1.36k|    int i;
  609|  2.84k|    for (i = 0; i < mpctx->num_chapters; i++)
  ------------------
  |  Branch (609:17): [True: 2.84k, False: 0]
  ------------------
  610|  2.84k|        if (current_pts < mpctx->chapters[i].pts)
  ------------------
  |  Branch (610:13): [True: 1.36k, False: 1.48k]
  ------------------
  611|  1.36k|            break;
  612|  1.36k|    return mpctx->last_chapter_flag ?
  ------------------
  |  Branch (612:12): [True: 0, False: 1.36k]
  ------------------
  613|  1.36k|        mpctx->last_chapter_seek : MPMAX(mpctx->last_chapter_seek, i - 1);
  ------------------
  |  |   43|  1.36k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 1.36k]
  |  |  ------------------
  ------------------
  614|  90.3k|}
update_ab_loop_clip:
  662|  2.96k|{
  663|  2.96k|    double pts = get_current_time(mpctx);
  664|  2.96k|    double ab[2];
  665|  2.96k|    mpctx->ab_loop_clip = pts != MP_NOPTS_VALUE &&
  ------------------
  |  |   38|  5.92k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (665:27): [True: 2.96k, False: 0]
  ------------------
  666|  2.96k|                          get_ab_loop_times(mpctx, ab) &&
  ------------------
  |  Branch (666:27): [True: 0, False: 2.96k]
  ------------------
  667|  2.96k|                          pts * mpctx->play_dir <= ab[1] * mpctx->play_dir;
  ------------------
  |  Branch (667:27): [True: 0, False: 0]
  ------------------
  668|  2.96k|}
handle_force_window:
 1022|   107k|{
 1023|       |    // True if we're either in idle mode, or loading of the file has finished.
 1024|       |    // It's also set via force in some stages during file loading.
 1025|   107k|    bool act = mpctx->stop_play || mpctx->playback_initialized || force;
  ------------------
  |  Branch (1025:16): [True: 7.38k, False: 99.6k]
  |  Branch (1025:36): [True: 90.3k, False: 9.31k]
  |  Branch (1025:67): [True: 1.84k, False: 7.46k]
  ------------------
 1026|       |
 1027|       |    // On the other hand, if a video track is selected, but no video is ever
 1028|       |    // decoded on it, then create the window.
 1029|   107k|    bool stalled_video = mpctx->playback_initialized && mpctx->restart_complete &&
  ------------------
  |  Branch (1029:26): [True: 90.3k, False: 16.6k]
  |  Branch (1029:57): [True: 77.9k, False: 12.3k]
  ------------------
 1030|   107k|                         mpctx->video_status == STATUS_EOF && mpctx->vo_chain &&
  ------------------
  |  Branch (1030:26): [True: 4.11k, False: 73.8k]
  |  Branch (1030:63): [True: 834, False: 3.28k]
  ------------------
 1031|   107k|                         !mpctx->video_out->config_ok;
  ------------------
  |  Branch (1031:26): [True: 833, False: 1]
  ------------------
 1032|       |
 1033|       |    // Don't interfere with real video playback
 1034|   107k|    if (mpctx->vo_chain && !stalled_video)
  ------------------
  |  Branch (1034:9): [True: 78.7k, False: 28.2k]
  |  Branch (1034:28): [True: 77.9k, False: 833]
  ------------------
 1035|  77.9k|        return 0;
 1036|       |
 1037|  29.1k|    if (!mpctx->opts->force_vo) {
  ------------------
  |  Branch (1037:9): [True: 29.1k, False: 0]
  ------------------
 1038|  29.1k|        if (act && !mpctx->vo_chain)
  ------------------
  |  Branch (1038:13): [True: 21.6k, False: 7.46k]
  |  Branch (1038:20): [True: 20.8k, False: 833]
  ------------------
 1039|  20.8k|            uninit_video_out(mpctx);
 1040|  29.1k|        return 0;
 1041|  29.1k|    }
 1042|       |
 1043|      0|    if (mpctx->opts->force_vo != 2 && !act)
  ------------------
  |  Branch (1043:9): [True: 0, False: 0]
  |  Branch (1043:39): [True: 0, False: 0]
  ------------------
 1044|      0|        return 0;
 1045|       |
 1046|      0|    if (!mpctx->video_out) {
  ------------------
  |  Branch (1046:9): [True: 0, False: 0]
  ------------------
 1047|      0|        struct vo_extra ex = {
 1048|      0|            .input_ctx = mpctx->input,
 1049|      0|            .osd = mpctx->osd,
 1050|      0|            .encode_lavc_ctx = mpctx->encode_lavc_ctx,
 1051|      0|            .wakeup_cb = mp_wakeup_core_cb,
 1052|      0|            .wakeup_ctx = mpctx,
 1053|      0|        };
 1054|      0|        mpctx->video_out = init_best_video_out(mpctx->global, &ex);
 1055|      0|        if (!mpctx->video_out)
  ------------------
  |  Branch (1055:13): [True: 0, False: 0]
  ------------------
 1056|      0|            goto err;
 1057|      0|        mpctx->mouse_cursor_visible = true;
 1058|      0|    }
 1059|       |
 1060|      0|    if (!mpctx->video_out->config_ok || force) {
  ------------------
  |  Branch (1060:9): [True: 0, False: 0]
  |  Branch (1060:41): [True: 0, False: 0]
  ------------------
 1061|      0|        struct vo *vo = mpctx->video_out;
 1062|       |        // Pick whatever works
 1063|      0|        int config_format = 0;
 1064|      0|        uint8_t fmts[IMGFMT_END - IMGFMT_START] = {0};
 1065|      0|        vo_query_formats(vo, fmts);
 1066|      0|        for (int fmt = IMGFMT_START; fmt < IMGFMT_END; fmt++) {
  ------------------
  |  Branch (1066:38): [True: 0, False: 0]
  ------------------
 1067|      0|            if (fmts[fmt - IMGFMT_START]) {
  ------------------
  |  Branch (1067:17): [True: 0, False: 0]
  ------------------
 1068|      0|                config_format = fmt;
 1069|      0|                break;
 1070|      0|            }
 1071|      0|        }
 1072|       |
 1073|       |        // Use a 16:9 aspect ratio so that fullscreen on a 16:9 screen will not
 1074|       |        // have vertical margins, which can lead to a different size or position
 1075|       |        // of subtitles than with 16:9 videos.
 1076|      0|        int w = 960;
 1077|      0|        int h = 540;
 1078|      0|        struct mp_image_params p = {
 1079|      0|            .imgfmt = config_format,
 1080|      0|            .w = w,   .h = h,
 1081|      0|            .p_w = 1, .p_h = 1,
 1082|      0|            .force_window = true,
 1083|      0|        };
 1084|      0|        if (vo_reconfig(vo, &p) < 0)
  ------------------
  |  Branch (1084:13): [True: 0, False: 0]
  ------------------
 1085|      0|            goto err;
 1086|      0|        struct track *track = mpctx->current_track[0][STREAM_VIDEO];
 1087|      0|        update_content_type(mpctx, track);
 1088|      0|        update_screensaver_state(mpctx);
 1089|      0|        vo_set_paused(vo, true);
 1090|      0|        vo_redraw(vo);
 1091|      0|        mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
 1092|      0|    }
 1093|       |
 1094|      0|    return 0;
 1095|       |
 1096|      0|err:
 1097|      0|    mpctx->opts->force_vo = 0;
 1098|      0|    m_config_notify_change_opt_ptr(mpctx->mconfig, &mpctx->opts->force_vo);
 1099|      0|    uninit_video_out(mpctx);
 1100|      0|    MP_FATAL(mpctx, "Error opening/initializing the VO window.\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1101|      0|    return -1;
 1102|      0|}
run_playloop:
 1252|  93.3k|{
 1253|  93.3k|    if (encode_lavc_didfail(mpctx->encode_lavc_ctx)) {
  ------------------
  |  Branch (1253:9): [True: 0, False: 93.3k]
  ------------------
 1254|      0|        mpctx->stop_play = PT_ERROR;
 1255|      0|        return;
 1256|      0|    }
 1257|       |
 1258|  93.3k|    update_demuxer_properties(mpctx);
 1259|       |
 1260|  93.3k|    handle_cursor_autohide(mpctx);
 1261|  93.3k|    handle_vo_events(mpctx);
 1262|  93.3k|    handle_command_updates(mpctx);
 1263|       |
 1264|  93.3k|    if (mpctx->lavfi && mp_filter_has_failed(mpctx->lavfi))
  ------------------
  |  Branch (1264:9): [True: 0, False: 93.3k]
  |  Branch (1264:25): [True: 0, False: 0]
  ------------------
 1265|      0|        mpctx->stop_play = AT_END_OF_FILE;
 1266|       |
 1267|  93.3k|    fill_audio_out_buffers(mpctx);
 1268|  93.3k|    write_video(mpctx);
 1269|       |
 1270|  93.3k|    handle_playback_restart(mpctx);
 1271|       |
 1272|  93.3k|    handle_playback_time(mpctx);
 1273|       |
 1274|  93.3k|    handle_dummy_ticks(mpctx);
 1275|       |
 1276|  93.3k|    handle_clipboard_updates(mpctx);
 1277|       |
 1278|  93.3k|    update_osd_msg(mpctx);
 1279|       |
 1280|  93.3k|    handle_update_subtitles(mpctx);
 1281|       |
 1282|  93.3k|    handle_each_frame_screenshot(mpctx);
 1283|       |
 1284|  93.3k|    handle_eof(mpctx);
 1285|       |
 1286|  93.3k|    handle_loop_file(mpctx);
 1287|       |
 1288|  93.3k|    handle_keep_open(mpctx);
 1289|       |
 1290|  93.3k|    handle_sstep(mpctx);
 1291|       |
 1292|  93.3k|    update_core_idle_state(mpctx);
 1293|       |
 1294|  93.3k|    execute_queued_seek(mpctx);
 1295|       |
 1296|  93.3k|    if (mpctx->stop_play)
  ------------------
  |  Branch (1296:9): [True: 2.96k, False: 90.3k]
  ------------------
 1297|  2.96k|        return;
 1298|       |
 1299|  90.3k|    handle_osd_redraw(mpctx);
 1300|       |
 1301|  90.3k|    if (mp_filter_graph_run(mpctx->filter_root))
  ------------------
  |  Branch (1301:9): [True: 77, False: 90.2k]
  ------------------
 1302|     77|        mp_wakeup_core(mpctx);
 1303|       |
 1304|  90.3k|    mp_wait_events(mpctx);
 1305|       |
 1306|  90.3k|    handle_update_cache(mpctx);
 1307|       |
 1308|  90.3k|    mp_process_input(mpctx);
 1309|       |
 1310|  90.3k|    handle_option_callbacks(mpctx);
 1311|       |
 1312|  90.3k|    handle_chapter_change(mpctx);
 1313|       |
 1314|  90.3k|    handle_force_window(mpctx, false);
 1315|  90.3k|}
mp_idle:
 1318|  46.9k|{
 1319|  46.9k|    handle_dummy_ticks(mpctx);
 1320|  46.9k|    handle_clipboard_updates(mpctx);
 1321|  46.9k|    mp_wait_events(mpctx);
 1322|  46.9k|    mp_process_input(mpctx);
 1323|  46.9k|    handle_option_callbacks(mpctx);
 1324|  46.9k|    handle_command_updates(mpctx);
 1325|  46.9k|    handle_update_cache(mpctx);
 1326|  46.9k|    handle_cursor_autohide(mpctx);
 1327|  46.9k|    handle_vo_events(mpctx);
 1328|  46.9k|    update_osd_msg(mpctx);
 1329|  46.9k|    handle_osd_redraw(mpctx);
 1330|  46.9k|}
idle_loop:
 1334|   100k|{
 1335|       |    // ================= idle loop (STOP state) =========================
 1336|   100k|    bool need_reinit = true;
 1337|   112k|    while (mpctx->opts->player_idle_mode && mpctx->stop_play == PT_STOP) {
  ------------------
  |  Branch (1337:12): [True: 112k, False: 0]
  |  Branch (1337:45): [True: 12.3k, False: 100k]
  ------------------
 1338|  12.3k|        if (need_reinit) {
  ------------------
  |  Branch (1338:13): [True: 6.49k, False: 5.81k]
  ------------------
 1339|  6.49k|            uninit_audio_out(mpctx);
 1340|  6.49k|            handle_force_window(mpctx, true);
 1341|  6.49k|            mp_wakeup_core(mpctx);
 1342|  6.49k|            mp_notify(mpctx, MPV_EVENT_IDLE, NULL);
 1343|  6.49k|            need_reinit = false;
 1344|  6.49k|        }
 1345|  12.3k|        mp_idle(mpctx);
 1346|  12.3k|    }
 1347|   100k|}
playloop.c:handle_cursor_autohide:
  842|   140k|{
  843|   140k|    struct MPOpts *opts = mpctx->opts;
  844|   140k|    struct vo *vo = mpctx->video_out;
  845|       |
  846|   140k|    if (!vo)
  ------------------
  |  Branch (846:9): [True: 54.7k, False: 85.4k]
  ------------------
  847|  54.7k|        return;
  848|       |
  849|  85.4k|    bool mouse_cursor_visible = mpctx->mouse_cursor_visible;
  850|  85.4k|    double now = mp_time_sec();
  851|       |
  852|  85.4k|    unsigned mouse_event_ts = mp_input_get_mouse_event_counter(mpctx->input);
  853|  85.4k|    if (mpctx->mouse_event_ts != mouse_event_ts) {
  ------------------
  |  Branch (853:9): [True: 0, False: 85.4k]
  ------------------
  854|      0|        mpctx->mouse_event_ts = mouse_event_ts;
  855|      0|        mpctx->mouse_timer = now + opts->cursor_autohide_delay / 1000.0;
  856|      0|        mouse_cursor_visible = true;
  857|      0|    }
  858|       |
  859|  85.4k|    if (mpctx->mouse_timer > now) {
  ------------------
  |  Branch (859:9): [True: 0, False: 85.4k]
  ------------------
  860|      0|        mp_set_timeout(mpctx, mpctx->mouse_timer - now);
  861|  85.4k|    } else {
  862|  85.4k|        mouse_cursor_visible = false;
  863|  85.4k|    }
  864|       |
  865|  85.4k|    if (opts->cursor_autohide_delay == -1)
  ------------------
  |  Branch (865:9): [True: 0, False: 85.4k]
  ------------------
  866|      0|        mouse_cursor_visible = true;
  867|       |
  868|  85.4k|    if (opts->cursor_autohide_delay == -2)
  ------------------
  |  Branch (868:9): [True: 0, False: 85.4k]
  ------------------
  869|      0|        mouse_cursor_visible = false;
  870|       |
  871|  85.4k|    if (opts->cursor_autohide_fs && !opts->vo->fullscreen)
  ------------------
  |  Branch (871:9): [True: 0, False: 85.4k]
  |  Branch (871:37): [True: 0, False: 0]
  ------------------
  872|      0|        mouse_cursor_visible = true;
  873|       |
  874|  85.4k|    if (mouse_cursor_visible != mpctx->mouse_cursor_visible)
  ------------------
  |  Branch (874:9): [True: 1.88k, False: 83.6k]
  ------------------
  875|  1.88k|        vo_control(vo, VOCTRL_SET_CURSOR_VISIBILITY, &mouse_cursor_visible);
  876|  85.4k|    mpctx->mouse_cursor_visible = mouse_cursor_visible;
  877|  85.4k|}
playloop.c:handle_vo_events:
  880|   140k|{
  881|   140k|    struct vo *vo = mpctx->video_out;
  882|   140k|    int events = vo ? vo_query_and_reset_events(vo, VO_EVENTS_USER) : 0;
  ------------------
  |  Branch (882:18): [True: 85.4k, False: 54.7k]
  ------------------
  883|   140k|    if (events & VO_EVENT_RESIZE)
  ------------------
  |  Branch (883:9): [True: 0, False: 140k]
  ------------------
  884|      0|        mp_notify(mpctx, MP_EVENT_WIN_RESIZE, NULL);
  885|   140k|    if (events & VO_EVENT_WIN_STATE)
  ------------------
  |  Branch (885:9): [True: 1.88k, False: 138k]
  ------------------
  886|  1.88k|        mp_notify(mpctx, MP_EVENT_WIN_STATE, NULL);
  887|   140k|    if (events & VO_EVENT_DPI)
  ------------------
  |  Branch (887:9): [True: 0, False: 140k]
  ------------------
  888|      0|        mp_notify(mpctx, MP_EVENT_WIN_STATE2, NULL);
  889|   140k|    if (events & VO_EVENT_FOCUS)
  ------------------
  |  Branch (889:9): [True: 0, False: 140k]
  ------------------
  890|      0|        mp_notify(mpctx, MP_EVENT_FOCUS, NULL);
  891|   140k|    if (events & VO_EVENT_AMBIENT_LIGHTING_CHANGED)
  ------------------
  |  Branch (891:9): [True: 0, False: 140k]
  ------------------
  892|      0|        mp_notify(mpctx, MP_EVENT_AMBIENT_LIGHTING_CHANGED, NULL);
  893|   140k|}
playloop.c:handle_playback_restart:
 1145|  93.3k|{
 1146|  93.3k|    struct MPOpts *opts = mpctx->opts;
 1147|       |
 1148|  93.3k|    if (mpctx->audio_status < STATUS_READY ||
  ------------------
  |  Branch (1148:9): [True: 10.0k, False: 83.2k]
  ------------------
 1149|  93.3k|        mpctx->video_status < STATUS_READY)
  ------------------
  |  Branch (1149:9): [True: 2.34k, False: 80.9k]
  ------------------
 1150|  12.3k|        return;
 1151|       |
 1152|  80.9k|    handle_update_cache(mpctx);
 1153|       |
 1154|  80.9k|    if (mpctx->video_status == STATUS_READY) {
  ------------------
  |  Branch (1154:9): [True: 561, False: 80.3k]
  ------------------
 1155|    561|        mpctx->video_status = STATUS_PLAYING;
 1156|    561|        get_relative_time(mpctx);
 1157|    561|        mp_wakeup_core(mpctx);
 1158|    561|        MP_DBG(mpctx, "starting video playback\n");
  ------------------
  |  |   89|    561|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    561|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1159|    561|    }
 1160|       |
 1161|  80.9k|    if (mpctx->audio_status == STATUS_READY) {
  ------------------
  |  Branch (1161:9): [True: 732, False: 80.2k]
  ------------------
 1162|       |        // If a new seek is queued while the current one finishes, don't
 1163|       |        // actually play the audio, but resume seeking immediately.
 1164|    732|        if (mpctx->seek.type && mpctx->video_status == STATUS_PLAYING) {
  ------------------
  |  Branch (1164:13): [True: 0, False: 732]
  |  Branch (1164:33): [True: 0, False: 0]
  ------------------
 1165|      0|            handle_playback_time(mpctx);
 1166|      0|            mpctx->seek.flags &= ~MPSEEK_FLAG_DELAY; // immediately
 1167|      0|            execute_queued_seek(mpctx);
 1168|      0|            return;
 1169|      0|        }
 1170|       |
 1171|    732|        audio_start_ao(mpctx);
 1172|    732|    }
 1173|       |
 1174|  80.9k|    if (!mpctx->restart_complete) {
  ------------------
  |  Branch (1174:9): [True: 2.96k, False: 77.9k]
  ------------------
 1175|  2.96k|        mpctx->hrseek_active = false;
 1176|  2.96k|        mpctx->restart_complete = true;
 1177|  2.96k|        mpctx->current_seek = (struct seek_params){0};
 1178|  2.96k|        handle_playback_time(mpctx);
 1179|  2.96k|        mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL);
 1180|  2.96k|        update_core_idle_state(mpctx);
 1181|  2.96k|        if (!mpctx->playing_msg_shown) {
  ------------------
  |  Branch (1181:13): [True: 2.96k, False: 0]
  ------------------
 1182|  2.96k|            if (opts->playing_msg && opts->playing_msg[0]) {
  ------------------
  |  Branch (1182:17): [True: 0, False: 2.96k]
  |  Branch (1182:38): [True: 0, False: 0]
  ------------------
 1183|      0|                char *msg =
 1184|      0|                    mp_property_expand_escaped_string(mpctx, opts->playing_msg);
 1185|      0|                struct mp_log *log = mp_log_new(NULL, mpctx->log, "!term-msg");
 1186|      0|                mp_info(log, "%s\n", msg);
  ------------------
  |  |   74|      0|#define mp_info(log, ...)       mp_msg(log, MSGL_INFO, __VA_ARGS__)
  ------------------
 1187|      0|                talloc_free(log);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1188|      0|                talloc_free(msg);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1189|      0|            }
 1190|  2.96k|            if (opts->osd_playing_msg && opts->osd_playing_msg[0]) {
  ------------------
  |  Branch (1190:17): [True: 0, False: 2.96k]
  |  Branch (1190:42): [True: 0, False: 0]
  ------------------
 1191|      0|                char *msg =
 1192|      0|                    mp_property_expand_escaped_string(mpctx, opts->osd_playing_msg);
 1193|      0|                set_osd_msg(mpctx, 1, opts->osd_playing_msg_duration ?
  ------------------
  |  Branch (1193:39): [True: 0, False: 0]
  ------------------
 1194|      0|                            opts->osd_playing_msg_duration : opts->osd_duration,
 1195|      0|                            "%s", msg);
 1196|      0|                talloc_free(msg);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1197|      0|            }
 1198|  2.96k|        }
 1199|  2.96k|        mpctx->playing_msg_shown = true;
 1200|  2.96k|        mp_wakeup_core(mpctx);
 1201|  2.96k|        update_ab_loop_clip(mpctx);
 1202|  2.96k|        MP_VERBOSE(mpctx, "playback restart complete @ %f, audio=%s, video=%s%s\n",
  ------------------
  |  |   88|  2.96k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  5.92k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 2.96k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1203|  2.96k|                   mpctx->playback_pts, mp_status_str(mpctx->audio_status),
 1204|  2.96k|                   mp_status_str(mpctx->video_status),
 1205|  2.96k|                   get_internal_paused(mpctx) ? " (paused)" : "");
 1206|       |
 1207|       |        // To avoid strange effects when using relative seeks, especially if
 1208|       |        // there are no proper audio & video timestamps (seeks after EOF).
 1209|  2.96k|        double length = get_time_length(mpctx);
 1210|  2.96k|        if (mpctx->last_seek_pts != MP_NOPTS_VALUE && length >= 0)
  ------------------
  |  |   38|  5.92k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1210:13): [True: 2.96k, False: 0]
  |  Branch (1210:55): [True: 2.75k, False: 209]
  ------------------
 1211|  2.75k|            mpctx->last_seek_pts = MPCLAMP(mpctx->last_seek_pts, 0, length);
  ------------------
  |  |   45|  2.75k|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 2.75k]
  |  |  |  Branch (45:56): [True: 0, False: 2.75k]
  |  |  ------------------
  ------------------
 1212|       |
 1213|       |        // Continuous seeks past EOF => treat as EOF instead of repeating seek.
 1214|  2.96k|        if (mpctx->seek.type == MPSEEK_RELATIVE && mpctx->seek.amount > 0 &&
  ------------------
  |  Branch (1214:13): [True: 0, False: 2.96k]
  |  Branch (1214:52): [True: 0, False: 0]
  ------------------
 1215|  2.96k|            mpctx->video_status == STATUS_EOF &&
  ------------------
  |  Branch (1215:13): [True: 0, False: 0]
  ------------------
 1216|  2.96k|            mpctx->audio_status == STATUS_EOF)
  ------------------
  |  Branch (1216:13): [True: 0, False: 0]
  ------------------
 1217|      0|            mpctx->seek = (struct seek_params){0};
 1218|  2.96k|    }
 1219|  80.9k|}
playloop.c:handle_playback_time:
 1120|  96.2k|{
 1121|  96.2k|    if (mpctx->vo_chain &&
  ------------------
  |  Branch (1121:9): [True: 82.8k, False: 13.4k]
  ------------------
 1122|  96.2k|        !mpctx->vo_chain->is_sparse &&
  ------------------
  |  Branch (1122:9): [True: 82.8k, False: 0]
  ------------------
 1123|  96.2k|        mpctx->video_status >= STATUS_PLAYING &&
  ------------------
  |  Branch (1123:9): [True: 78.7k, False: 4.05k]
  ------------------
 1124|  96.2k|        mpctx->video_status < STATUS_EOF)
  ------------------
  |  Branch (1124:9): [True: 74.4k, False: 4.33k]
  ------------------
 1125|  74.4k|    {
 1126|  74.4k|        mpctx->playback_pts = mpctx->video_pts;
 1127|  74.4k|    } else if (mpctx->audio_status >= STATUS_PLAYING &&
  ------------------
  |  Branch (1127:16): [True: 11.8k, False: 10.0k]
  ------------------
 1128|  21.8k|               mpctx->audio_status < STATUS_EOF)
  ------------------
  |  Branch (1128:16): [True: 5.67k, False: 6.14k]
  ------------------
 1129|  5.67k|    {
 1130|  5.67k|        mpctx->playback_pts = playing_audio_pts(mpctx);
 1131|  16.1k|    } else if (mpctx->video_status == STATUS_EOF &&
  ------------------
  |  Branch (1131:16): [True: 12.1k, False: 4.05k]
  ------------------
 1132|  16.1k|               mpctx->audio_status == STATUS_EOF)
  ------------------
  |  Branch (1132:16): [True: 3.79k, False: 8.32k]
  ------------------
 1133|  3.79k|    {
 1134|  3.79k|        double apts = playing_audio_pts(mpctx);
 1135|  3.79k|        double vpts = mpctx->video_pts;
 1136|  3.79k|        double mpts = MP_PTS_MAX(apts, vpts);
  ------------------
  |  |   64|  3.79k|#define MP_PTS_MAX(a, b) MPMAX(MP_PTS_OR_DEF(a, b), MP_PTS_OR_DEF(b, a))
  |  |  ------------------
  |  |  |  |   43|  7.59k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (43:22): [True: 0, False: 3.79k]
  |  |  |  |  |  Branch (43:23): [True: 3.12k, False: 675]
  |  |  |  |  |  Branch (43:29): [True: 3.23k, False: 561]
  |  |  |  |  |  Branch (43:35): [True: 0, False: 0]
  |  |  |  |  |  Branch (43:41): [True: 3.23k, False: 561]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1137|  3.79k|        if (mpts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  3.79k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (1137:13): [True: 1.23k, False: 2.56k]
  ------------------
 1138|  1.23k|            mpctx->playback_pts = mpts;
 1139|  3.79k|    }
 1140|  96.2k|}
playloop.c:handle_dummy_ticks:
 1106|   140k|{
 1107|   140k|    if ((mpctx->video_status != STATUS_PLAYING &&
  ------------------
  |  Branch (1107:10): [True: 67.0k, False: 73.1k]
  ------------------
 1108|   140k|         mpctx->video_status != STATUS_DRAINING) ||
  ------------------
  |  Branch (1108:10): [True: 66.3k, False: 680]
  ------------------
 1109|   140k|         mpctx->paused)
  ------------------
  |  Branch (1109:10): [True: 95, False: 73.7k]
  ------------------
 1110|  66.4k|    {
 1111|  66.4k|        if (mp_time_sec() - mpctx->last_idle_tick > 0.050) {
  ------------------
  |  Branch (1111:13): [True: 7.62k, False: 58.8k]
  ------------------
 1112|  7.62k|            mpctx->last_idle_tick = mp_time_sec();
 1113|  7.62k|            mp_notify(mpctx, MPV_EVENT_TICK, NULL);
 1114|  7.62k|        }
 1115|  66.4k|    }
 1116|   140k|}
playloop.c:handle_clipboard_updates:
 1246|   140k|{
 1247|   140k|    if (mp_clipboard_data_changed(mpctx->clipboard))
  ------------------
  |  Branch (1247:9): [True: 0, False: 140k]
  ------------------
 1248|      0|        mp_notify_property(mpctx, "clipboard");
 1249|   140k|}
playloop.c:handle_update_subtitles:
  826|  93.3k|{
  827|  93.3k|    if (mpctx->video_status == STATUS_EOF) {
  ------------------
  |  Branch (827:9): [True: 15.3k, False: 77.9k]
  ------------------
  828|  15.3k|        update_subtitles(mpctx, mpctx->playback_pts);
  829|  15.3k|        return;
  830|  15.3k|    }
  831|       |
  832|   157k|    for (int n = 0; n < mpctx->num_tracks; n++) {
  ------------------
  |  Branch (832:21): [True: 79.6k, False: 77.9k]
  ------------------
  833|  79.6k|        struct track *track = mpctx->tracks[n];
  834|  79.6k|        if (track->type == STREAM_SUB && !track->demuxer_ready) {
  ------------------
  |  Branch (834:13): [True: 0, False: 79.6k]
  |  Branch (834:42): [True: 0, False: 0]
  ------------------
  835|      0|            update_subtitles(mpctx, mpctx->playback_pts);
  836|      0|            break;
  837|      0|        }
  838|  79.6k|    }
  839|  77.9k|}
playloop.c:handle_eof:
 1222|  93.3k|{
 1223|  93.3k|    if (mpctx->seek.type)
  ------------------
  |  Branch (1223:9): [True: 0, False: 93.3k]
  ------------------
 1224|      0|        return; // for proper keep-open operation
 1225|       |
 1226|       |    /* Don't quit while paused and we're displaying the last video frame. On the
 1227|       |     * other hand, if we don't have a video frame, then the user probably seeked
 1228|       |     * outside of the video, and we do want to quit. */
 1229|  93.3k|    bool prevent_eof =
 1230|  93.3k|        mpctx->paused && mpctx->video_out && vo_has_frame(mpctx->video_out) &&
  ------------------
  |  Branch (1230:9): [True: 95, False: 93.2k]
  |  Branch (1230:26): [True: 95, False: 0]
  |  Branch (1230:46): [True: 95, False: 0]
  ------------------
 1231|  93.3k|        !mpctx->vo_chain->is_coverart;
  ------------------
  |  Branch (1231:9): [True: 95, False: 0]
  ------------------
 1232|       |    /* It's possible for the user to simultaneously switch both audio
 1233|       |     * and video streams to "disabled" at runtime. Handle this by waiting
 1234|       |     * rather than immediately stopping playback due to EOF.
 1235|       |     */
 1236|  93.3k|    if ((mpctx->ao_chain || mpctx->vo_chain) && !prevent_eof &&
  ------------------
  |  Branch (1236:10): [True: 15.9k, False: 77.3k]
  |  Branch (1236:29): [True: 77.3k, False: 3]
  |  Branch (1236:49): [True: 93.2k, False: 95]
  ------------------
 1237|  93.3k|        mpctx->audio_status == STATUS_EOF &&
  ------------------
  |  Branch (1237:9): [True: 79.0k, False: 14.1k]
  ------------------
 1238|  93.3k|        mpctx->video_status == STATUS_EOF &&
  ------------------
  |  Branch (1238:9): [True: 2.95k, False: 76.0k]
  ------------------
 1239|  93.3k|        !mpctx->stop_play)
  ------------------
  |  Branch (1239:9): [True: 2.95k, False: 0]
  ------------------
 1240|  2.95k|    {
 1241|  2.95k|        mpctx->stop_play = AT_END_OF_FILE;
 1242|  2.95k|    }
 1243|  93.3k|}
playloop.c:handle_loop_file:
  915|  93.3k|{
  916|  93.3k|    if (mpctx->stop_play != AT_END_OF_FILE)
  ------------------
  |  Branch (916:9): [True: 90.3k, False: 2.95k]
  ------------------
  917|  90.3k|        return;
  918|       |
  919|  2.95k|    double target = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  2.95k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  920|  2.95k|    enum seek_precision prec = MPSEEK_DEFAULT;
  921|       |
  922|  2.95k|    double ab[2];
  923|  2.95k|    if (get_ab_loop_times(mpctx, ab) && mpctx->ab_loop_clip) {
  ------------------
  |  Branch (923:9): [True: 0, False: 2.95k]
  |  Branch (923:41): [True: 0, False: 0]
  ------------------
  924|      0|        if (mpctx->remaining_ab_loops > 0) {
  ------------------
  |  Branch (924:13): [True: 0, False: 0]
  ------------------
  925|      0|            mpctx->remaining_ab_loops--;
  926|      0|            mp_notify_property(mpctx, "remaining-ab-loops");
  927|      0|        }
  928|      0|        target = ab[0];
  929|      0|        prec = MPSEEK_EXACT;
  930|  2.95k|    } else if (mpctx->remaining_file_loops) {
  ------------------
  |  Branch (930:16): [True: 0, False: 2.95k]
  ------------------
  931|      0|        if (mpctx->remaining_file_loops > 0) {
  ------------------
  |  Branch (931:13): [True: 0, False: 0]
  ------------------
  932|      0|            mpctx->remaining_file_loops--;
  933|      0|            mp_notify_property(mpctx, "remaining-file-loops");
  934|      0|        }
  935|      0|        target = get_start_time(mpctx, mpctx->play_dir);
  936|      0|    }
  937|       |
  938|  2.95k|    if (target != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  2.95k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (938:9): [True: 0, False: 2.95k]
  ------------------
  939|      0|        if (!mpctx->shown_aframes && !mpctx->shown_vframes) {
  ------------------
  |  Branch (939:13): [True: 0, False: 0]
  |  Branch (939:38): [True: 0, False: 0]
  ------------------
  940|      0|            MP_WARN(mpctx, "No media data to loop.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  941|      0|            return;
  942|      0|        }
  943|       |
  944|      0|        mpctx->stop_play = KEEP_PLAYING;
  945|      0|        set_osd_function(mpctx, OSD_FFW);
  946|      0|        mark_seek(mpctx);
  947|       |
  948|       |        // Assumes execute_queued_seek() happens before next audio/video is
  949|       |        // attempted to be decoded or filtered.
  950|      0|        queue_seek(mpctx, MPSEEK_ABSOLUTE, target, prec, MPSEEK_FLAG_NOFLUSH);
  951|      0|    }
  952|  2.95k|}
playloop.c:handle_keep_open:
  984|  93.3k|{
  985|  93.3k|    struct MPOpts *opts = mpctx->opts;
  986|  93.3k|    if (opts->keep_open && mpctx->stop_play == AT_END_OF_FILE &&
  ------------------
  |  Branch (986:9): [True: 0, False: 93.3k]
  |  Branch (986:28): [True: 0, False: 0]
  ------------------
  987|  93.3k|        (opts->keep_open == 2 ||
  ------------------
  |  Branch (987:10): [True: 0, False: 0]
  ------------------
  988|      0|        (!playlist_get_next(mpctx->playlist, 1) && opts->loop_times == 1)))
  ------------------
  |  Branch (988:10): [True: 0, False: 0]
  |  Branch (988:52): [True: 0, False: 0]
  ------------------
  989|      0|    {
  990|      0|        mpctx->stop_play = KEEP_PLAYING;
  991|      0|        if (mpctx->vo_chain) {
  ------------------
  |  Branch (991:13): [True: 0, False: 0]
  ------------------
  992|      0|            if (!vo_has_frame(mpctx->video_out)) { // EOF not reached normally
  ------------------
  |  Branch (992:17): [True: 0, False: 0]
  ------------------
  993|      0|                seek_to_last_frame(mpctx);
  994|      0|                mpctx->audio_status = STATUS_EOF;
  995|      0|                mpctx->video_status = STATUS_EOF;
  996|      0|            }
  997|      0|        }
  998|      0|        if (opts->keep_open_pause) {
  ------------------
  |  Branch (998:13): [True: 0, False: 0]
  ------------------
  999|      0|            if (mpctx->ao && ao_is_playing(mpctx->ao))
  ------------------
  |  Branch (999:17): [True: 0, False: 0]
  |  Branch (999:30): [True: 0, False: 0]
  ------------------
 1000|      0|                return;
 1001|      0|            set_pause_state(mpctx, true);
 1002|      0|        }
 1003|      0|    }
 1004|  93.3k|}
playloop.c:handle_sstep:
  896|  93.3k|{
  897|  93.3k|    struct MPOpts *opts = mpctx->opts;
  898|  93.3k|    if (mpctx->stop_play || !mpctx->restart_complete)
  ------------------
  |  Branch (898:9): [True: 2.96k, False: 90.3k]
  |  Branch (898:29): [True: 12.3k, False: 77.9k]
  ------------------
  899|  15.3k|        return;
  900|       |
  901|  77.9k|    if (opts->step_sec > 0 && !mpctx->paused) {
  ------------------
  |  Branch (901:9): [True: 0, False: 77.9k]
  |  Branch (901:31): [True: 0, False: 0]
  ------------------
  902|      0|        set_osd_function(mpctx, OSD_FFW);
  903|      0|        queue_seek(mpctx, MPSEEK_RELATIVE, opts->step_sec, MPSEEK_DEFAULT, 0);
  904|      0|    }
  905|       |
  906|  77.9k|    if (mpctx->video_status >= STATUS_EOF) {
  ------------------
  |  Branch (906:9): [True: 4.11k, False: 73.8k]
  ------------------
  907|  4.11k|        if (mpctx->max_frames >= 0 && !mpctx->stop_play)
  ------------------
  |  Branch (907:13): [True: 0, False: 4.11k]
  |  Branch (907:39): [True: 0, False: 0]
  ------------------
  908|      0|            mpctx->stop_play = AT_END_OF_FILE; // force EOF even if audio left
  909|  4.11k|        if (mpctx->step_frames > 0 && !mpctx->paused)
  ------------------
  |  Branch (909:13): [True: 0, False: 4.11k]
  |  Branch (909:39): [True: 0, False: 0]
  ------------------
  910|      0|            set_pause_state(mpctx, true);
  911|  4.11k|    }
  912|  77.9k|}
playloop.c:handle_osd_redraw:
  671|   137k|{
  672|   137k|    if (!mpctx->video_out || !mpctx->video_out->config_ok || (mpctx->playing && mpctx->stop_play))
  ------------------
  |  Branch (672:9): [True: 53.7k, False: 83.4k]
  |  Branch (672:30): [True: 8.43k, False: 75.0k]
  |  Branch (672:63): [True: 75.0k, False: 0]
  |  Branch (672:81): [True: 1.12k, False: 73.9k]
  ------------------
  673|  63.3k|        return;
  674|       |    // If we're playing normally, let OSD be redrawn naturally as part of
  675|       |    // video display.
  676|  73.9k|    if (!mpctx->paused) {
  ------------------
  |  Branch (676:9): [True: 73.8k, False: 95]
  ------------------
  677|  73.8k|        if (mpctx->sleeptime < 0.1 && mpctx->video_status == STATUS_PLAYING)
  ------------------
  |  Branch (677:13): [True: 73.6k, False: 171]
  |  Branch (677:39): [True: 72.9k, False: 722]
  ------------------
  678|  72.9k|            return;
  679|  73.8k|    }
  680|       |    // Don't redraw immediately during a seek (makes it significantly slower).
  681|    988|    bool use_video = mpctx->vo_chain && !mpctx->vo_chain->is_sparse;
  ------------------
  |  Branch (681:22): [True: 959, False: 29]
  |  Branch (681:41): [True: 959, False: 0]
  ------------------
  682|    988|    if (use_video && mp_time_sec() - mpctx->start_timestamp < 0.1) {
  ------------------
  |  Branch (682:9): [True: 959, False: 29]
  |  Branch (682:22): [True: 0, False: 959]
  ------------------
  683|      0|        mp_set_timeout(mpctx, 0.1);
  684|      0|        return;
  685|      0|    }
  686|    988|    bool want_redraw = osd_query_and_reset_want_redraw(mpctx->osd) ||
  ------------------
  |  Branch (686:24): [True: 544, False: 444]
  ------------------
  687|    988|                       vo_want_redraw(mpctx->video_out);
  ------------------
  |  Branch (687:24): [True: 0, False: 444]
  ------------------
  688|    988|    if (!want_redraw)
  ------------------
  |  Branch (688:9): [True: 444, False: 544]
  ------------------
  689|    444|        return;
  690|    544|    vo_redraw(mpctx->video_out);
  691|    544|}
playloop.c:handle_update_cache:
  707|   218k|{
  708|   218k|    bool force_update = false;
  709|   218k|    struct MPOpts *opts = mpctx->opts;
  710|       |
  711|   218k|    if (!mpctx->demuxer || mpctx->encode_lavc_ctx) {
  ------------------
  |  Branch (711:9): [True: 42.2k, False: 175k]
  |  Branch (711:28): [True: 0, False: 175k]
  ------------------
  712|  42.2k|        clear_underruns(mpctx);
  713|  42.2k|        return;
  714|  42.2k|    }
  715|       |
  716|   175k|    double now = mp_time_sec();
  717|       |
  718|   175k|    struct demux_reader_state s;
  719|   175k|    demux_get_reader_state(mpctx->demuxer, &s);
  720|       |
  721|   175k|    mpctx->demux_underrun |= s.underrun;
  722|       |
  723|   175k|    int cache_buffer = 100;
  724|   175k|    bool use_pause_on_low_cache = opts->cache_pause && mpctx->play_dir > 0;
  ------------------
  |  Branch (724:35): [True: 175k, False: 0]
  |  Branch (724:56): [True: 175k, False: 0]
  ------------------
  725|       |
  726|   175k|    if (!mpctx->restart_complete) {
  ------------------
  |  Branch (726:9): [True: 19.9k, False: 155k]
  ------------------
  727|       |        // Audio or video is restarting, and initial buffering is enabled. Make
  728|       |        // sure we actually restart them in paused mode, so no audio gets
  729|       |        // dropped and video technically doesn't start yet.
  730|  19.9k|        use_pause_on_low_cache &= opts->cache_pause_initial &&
  ------------------
  |  Branch (730:35): [True: 0, False: 19.9k]
  ------------------
  731|  19.9k|                                    (mpctx->video_status == STATUS_READY ||
  ------------------
  |  Branch (731:38): [True: 0, False: 0]
  ------------------
  732|      0|                                     mpctx->audio_status == STATUS_READY);
  ------------------
  |  Branch (732:38): [True: 0, False: 0]
  ------------------
  733|  19.9k|    }
  734|       |
  735|   175k|    bool is_low = use_pause_on_low_cache && !s.idle &&
  ------------------
  |  Branch (735:19): [True: 155k, False: 19.9k]
  |  Branch (735:45): [True: 3.47k, False: 152k]
  ------------------
  736|   175k|                  s.ts_info.duration < opts->cache_pause_wait;
  ------------------
  |  Branch (736:19): [True: 3.46k, False: 3]
  ------------------
  737|       |
  738|       |    // Enter buffering state only if there actually was an underrun (or if
  739|       |    // initial caching before playback restart is used).
  740|   175k|    bool need_wait = is_low;
  741|   175k|    if (is_low && !mpctx->paused_for_cache && mpctx->restart_complete) {
  ------------------
  |  Branch (741:9): [True: 3.46k, False: 172k]
  |  Branch (741:19): [True: 3.31k, False: 151]
  |  Branch (741:47): [True: 3.31k, False: 0]
  ------------------
  742|       |        // Wait only if an output underrun was registered. (Or if there is no
  743|       |        // underrun detection.)
  744|  3.31k|        bool output_underrun = false;
  745|       |
  746|  3.31k|        if (mpctx->ao_chain)
  ------------------
  |  Branch (746:13): [True: 1.35k, False: 1.96k]
  ------------------
  747|  1.35k|            output_underrun |= mpctx->ao_chain->underrun;
  748|  3.31k|        if (mpctx->vo_chain)
  ------------------
  |  Branch (748:13): [True: 1.96k, False: 1.35k]
  ------------------
  749|  1.96k|            output_underrun |= mpctx->vo_chain->underrun;
  750|       |
  751|       |        // Output underruns could be sporadic (unrelated to demuxer buffer state
  752|       |        // and for example caused by slow decoding), so use a past demuxer
  753|       |        // underrun as indication that the underrun was possibly due to a
  754|       |        // demuxer underrun.
  755|  3.31k|        need_wait = mpctx->demux_underrun && output_underrun;
  ------------------
  |  Branch (755:21): [True: 2.73k, False: 580]
  |  Branch (755:46): [True: 21, False: 2.71k]
  ------------------
  756|  3.31k|    }
  757|       |
  758|       |    // Let the underrun flag "stick" around until the cache has fully recovered.
  759|       |    // See logic where demux_underrun is used.
  760|   175k|    if (!is_low)
  ------------------
  |  Branch (760:9): [True: 172k, False: 3.46k]
  ------------------
  761|   172k|        mpctx->demux_underrun = false;
  762|       |
  763|   175k|    if (mpctx->paused_for_cache != need_wait) {
  ------------------
  |  Branch (763:9): [True: 42, False: 175k]
  ------------------
  764|     42|        mpctx->paused_for_cache = need_wait;
  765|     42|        update_internal_pause_state(mpctx);
  766|     42|        force_update = true;
  767|     42|        if (mpctx->paused_for_cache)
  ------------------
  |  Branch (767:13): [True: 21, False: 21]
  ------------------
  768|     21|            mpctx->cache_stop_time = now;
  769|     42|    }
  770|       |
  771|   175k|    if (!mpctx->paused_for_cache)
  ------------------
  |  Branch (771:9): [True: 175k, False: 172]
  ------------------
  772|   175k|        clear_underruns(mpctx);
  773|       |
  774|   175k|    if (mpctx->paused_for_cache) {
  ------------------
  |  Branch (774:9): [True: 172, False: 175k]
  ------------------
  775|    172|        cache_buffer =
  776|    172|            100 * MPCLAMP(s.ts_info.duration / opts->cache_pause_wait, 0, 0.99);
  ------------------
  |  |   45|    172|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 172]
  |  |  |  Branch (45:56): [True: 1, False: 171]
  |  |  ------------------
  ------------------
  777|    172|        mp_set_timeout(mpctx, 0.2);
  778|    172|    }
  779|       |
  780|       |    // Also update cache properties.
  781|   175k|    bool busy = !s.idle;
  782|   175k|    if (fabs(mpctx->cache_update_pts - mpctx->playback_pts) >= 1.0)
  ------------------
  |  Branch (782:9): [True: 145k, False: 30.2k]
  ------------------
  783|   145k|        busy = true;
  784|   175k|    if (busy || mpctx->next_cache_update > 0) {
  ------------------
  |  Branch (784:9): [True: 152k, False: 23.8k]
  |  Branch (784:17): [True: 18.0k, False: 5.73k]
  ------------------
  785|   170k|        if (mpctx->next_cache_update <= now) {
  ------------------
  |  Branch (785:13): [True: 3.02k, False: 167k]
  ------------------
  786|  3.02k|            mpctx->next_cache_update = busy ? now + 0.25 : 0;
  ------------------
  |  Branch (786:40): [True: 2.94k, False: 80]
  ------------------
  787|  3.02k|            force_update = true;
  788|  3.02k|        }
  789|   170k|        if (mpctx->next_cache_update > 0)
  ------------------
  |  Branch (789:13): [True: 170k, False: 80]
  ------------------
  790|   170k|            mp_set_timeout(mpctx, mpctx->next_cache_update - now);
  791|   170k|    }
  792|       |
  793|   175k|    if (mpctx->cache_buffer != cache_buffer) {
  ------------------
  |  Branch (793:9): [True: 153, False: 175k]
  ------------------
  794|    153|        if ((mpctx->cache_buffer == 100) != (cache_buffer == 100)) {
  ------------------
  |  Branch (794:13): [True: 42, False: 111]
  ------------------
  795|     42|            if (cache_buffer < 100) {
  ------------------
  |  Branch (795:17): [True: 21, False: 21]
  ------------------
  796|     21|                MP_VERBOSE(mpctx, "Enter buffering (buffer went from %d%% -> %d%%) [%fs].\n",
  ------------------
  |  |   88|     21|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     21|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  797|     21|                           mpctx->cache_buffer, cache_buffer, s.ts_info.duration);
  798|     21|            } else {
  799|     21|                double t = now - mpctx->cache_stop_time;
  800|     21|                MP_VERBOSE(mpctx, "End buffering (waited %f secs) [%fs].\n",
  ------------------
  |  |   88|     21|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     21|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  801|     21|                           t, s.ts_info.duration);
  802|     21|            }
  803|    111|        } else {
  804|    111|            MP_VERBOSE(mpctx, "Still buffering (buffer went from %d%% -> %d%%) [%fs].\n",
  ------------------
  |  |   88|    111|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    111|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  805|    111|                       mpctx->cache_buffer, cache_buffer, s.ts_info.duration);
  806|    111|        }
  807|    153|        mpctx->cache_buffer = cache_buffer;
  808|    153|        force_update = true;
  809|    153|    }
  810|       |
  811|   175k|    if (s.eof && !busy)
  ------------------
  |  Branch (811:9): [True: 86.4k, False: 89.4k]
  |  Branch (811:18): [True: 10.3k, False: 76.0k]
  ------------------
  812|  10.3k|        prefetch_next(mpctx);
  813|       |
  814|   175k|    if (force_update) {
  ------------------
  |  Branch (814:9): [True: 3.17k, False: 172k]
  ------------------
  815|  3.17k|        mpctx->cache_update_pts = mpctx->playback_pts;
  816|  3.17k|        mp_notify(mpctx, MP_EVENT_CACHE_UPDATE, NULL);
  817|  3.17k|    }
  818|   175k|}
playloop.c:clear_underruns:
  694|   218k|{
  695|   218k|    if (mpctx->ao_chain && mpctx->ao_chain->underrun) {
  ------------------
  |  Branch (695:9): [True: 20.0k, False: 197k]
  |  Branch (695:28): [True: 0, False: 20.0k]
  ------------------
  696|      0|        mpctx->ao_chain->underrun = false;
  697|      0|        mp_wakeup_core(mpctx);
  698|      0|    }
  699|       |
  700|   218k|    if (mpctx->vo_chain && mpctx->vo_chain->underrun) {
  ------------------
  |  Branch (700:9): [True: 155k, False: 62.7k]
  |  Branch (700:28): [True: 30, False: 155k]
  ------------------
  701|     30|        mpctx->vo_chain->underrun = false;
  702|     30|        mp_wakeup_core(mpctx);
  703|     30|    }
  704|   218k|}
playloop.c:mp_process_input:
  110|   137k|{
  111|   137k|    bool notify = false;
  112|   137k|    for (;;) {
  113|   137k|        mp_cmd_t *cmd = mp_input_read_cmd(mpctx->input);
  114|   137k|        if (!cmd)
  ------------------
  |  Branch (114:13): [True: 137k, False: 0]
  ------------------
  115|   137k|            break;
  116|      0|        if (cmd->notify_event)
  ------------------
  |  Branch (116:13): [True: 0, False: 0]
  ------------------
  117|      0|            notify = true;
  118|      0|        run_command(mpctx, cmd, NULL, NULL, NULL);
  119|      0|    }
  120|   137k|    mp_set_timeout(mpctx, mp_input_get_delay(mpctx->input));
  121|   137k|    if (notify)
  ------------------
  |  Branch (121:9): [True: 0, False: 137k]
  ------------------
  122|      0|        mp_notify(mpctx, MP_EVENT_INPUT_PROCESSED, NULL);
  123|   137k|}
playloop.c:handle_chapter_change:
 1007|  90.3k|{
 1008|  90.3k|    int chapter = get_current_chapter(mpctx);
 1009|  90.3k|    if (chapter != mpctx->last_chapter) {
  ------------------
  |  Branch (1009:9): [True: 425, False: 89.9k]
  ------------------
 1010|    425|        mpctx->last_chapter = chapter;
 1011|    425|        mp_notify(mpctx, MP_EVENT_CHAPTER_CHANGE, NULL);
 1012|    425|    }
 1013|  90.3k|}

screenshot_init:
   61|  5.81k|{
   62|  5.81k|    mpctx->screenshot_ctx = talloc(mpctx, screenshot_ctx);
  ------------------
  |  |   26|  5.81k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  5.81k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   63|  5.81k|    *mpctx->screenshot_ctx = (screenshot_ctx) {
   64|  5.81k|        .mpctx = mpctx,
   65|  5.81k|        .frameno = 1,
   66|  5.81k|        .log = mp_log_new(mpctx, mpctx->log, "screenshot")
   67|  5.81k|    };
   68|  5.81k|}
handle_each_frame_screenshot:
  599|  93.3k|{
  600|  93.3k|    screenshot_ctx *ctx = mpctx->screenshot_ctx;
  601|       |
  602|  93.3k|    if (!ctx->each_frame)
  ------------------
  |  Branch (602:9): [True: 93.3k, False: 0]
  ------------------
  603|  93.3k|        return;
  604|       |
  605|      0|    if (ctx->last_frame_count == mpctx->shown_vframes)
  ------------------
  |  Branch (605:9): [True: 0, False: 0]
  ------------------
  606|      0|        return;
  607|      0|    ctx->last_frame_count = mpctx->shown_vframes;
  608|       |
  609|      0|    struct mp_waiter wait = MP_WAITER_INITIALIZER;
  ------------------
  |  |   19|      0|#define MP_WAITER_INITIALIZER { \
  |  |   20|      0|    .lock = MP_STATIC_MUTEX_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  106|      0|#define MP_STATIC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
  |  |  ------------------
  |  |   21|      0|    .wakeup = MP_STATIC_COND_INITIALIZER, \
  |  |  ------------------
  |  |  |  |  105|      0|#define MP_STATIC_COND_INITIALIZER { .cond = PTHREAD_COND_INITIALIZER, .clk_id = CLOCK_REALTIME }
  |  |  ------------------
  |  |   22|      0|    }
  ------------------
  610|      0|    void *a[] = {mpctx, &wait};
  611|      0|    run_command(mpctx, mp_cmd_clone(ctx->each_frame), NULL, screenshot_fin, a);
  612|       |
  613|       |    // Block (in a reentrant way) until the screenshot was written. Otherwise,
  614|       |    // we could pile up screenshot requests forever.
  615|      0|    while (!mp_waiter_poll(&wait))
  ------------------
  |  Branch (615:12): [True: 0, False: 0]
  ------------------
  616|      0|        mp_idle(mpctx);
  617|       |
  618|      0|    mp_waiter_wait(&wait);
  619|      0|}

mp_load_builtin_scripts:
  263|  5.81k|{
  264|  5.81k|    load_builtin_script(mpctx, 0, mpctx->opts->lua_load_osc, "@osc.lua");
  265|  5.81k|    load_builtin_script(mpctx, 1, mpctx->opts->lua_load_ytdl, "@ytdl_hook.lua");
  266|  5.81k|    load_builtin_script(mpctx, 2, mpctx->opts->lua_load_stats, "@stats.lua");
  267|  5.81k|    load_builtin_script(mpctx, 3, mpctx->opts->lua_load_console, "@console.lua");
  268|  5.81k|    load_builtin_script(mpctx, 4, mpctx->opts->lua_load_auto_profiles,
  269|  5.81k|                        "@auto_profiles.lua");
  270|  5.81k|    load_builtin_script(mpctx, 5, mpctx->opts->lua_load_select, "@select.lua");
  271|  5.81k|    load_builtin_script(mpctx, 6, mpctx->opts->lua_load_positioning, "@positioning.lua");
  272|  5.81k|    load_builtin_script(mpctx, 7, mpctx->opts->lua_load_commands, "@commands.lua");
  273|  5.81k|}
mp_load_scripts:
  276|  5.81k|{
  277|  5.81k|    bool ok = true;
  278|       |
  279|       |    // Load scripts from options
  280|  5.81k|    char **files = mpctx->opts->script_files;
  281|  5.81k|    for (int n = 0; files && files[n]; n++) {
  ------------------
  |  Branch (281:21): [True: 0, False: 5.81k]
  |  Branch (281:30): [True: 0, False: 0]
  ------------------
  282|      0|        if (files[n][0])
  ------------------
  |  Branch (282:13): [True: 0, False: 0]
  ------------------
  283|      0|            ok &= mp_load_user_script(mpctx, files[n]) >= 0;
  284|      0|    }
  285|  5.81k|    if (!mpctx->opts->auto_load_scripts)
  ------------------
  |  Branch (285:9): [True: 0, False: 5.81k]
  ------------------
  286|      0|        return ok;
  287|       |
  288|       |    // Load all scripts
  289|  5.81k|    void *tmp = talloc_new(NULL);
  ------------------
  |  |   40|  5.81k|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|  5.81k|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  290|  5.81k|    char **scriptsdir = mp_find_all_config_files(tmp, mpctx->global, "scripts");
  291|  5.81k|    for (int i = 0; scriptsdir && scriptsdir[i]; i++) {
  ------------------
  |  Branch (291:21): [True: 5.81k, False: 0]
  |  Branch (291:35): [True: 0, False: 5.81k]
  ------------------
  292|      0|        files = list_script_files(tmp, scriptsdir[i]);
  293|      0|        for (int n = 0; files && files[n]; n++)
  ------------------
  |  Branch (293:25): [True: 0, False: 0]
  |  Branch (293:34): [True: 0, False: 0]
  ------------------
  294|      0|            ok &= mp_load_script(mpctx, files[n]) >= 0;
  295|      0|    }
  296|  5.81k|    talloc_free(tmp);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  297|       |
  298|  5.81k|    return ok;
  299|  5.81k|}
scripting.c:load_builtin_script:
  243|  46.4k|{
  244|  46.4k|    mp_assert(slot < MP_ARRAY_SIZE(mpctx->builtin_script_ids));
  ------------------
  |  |   41|  46.4k|#define mp_assert assert
  ------------------
  245|  46.4k|    int64_t *pid = &mpctx->builtin_script_ids[slot];
  246|  46.4k|    if (*pid > 0 && !mp_client_id_exists(mpctx, *pid)) {
  ------------------
  |  Branch (246:9): [True: 0, False: 46.4k]
  |  Branch (246:21): [True: 0, False: 0]
  ------------------
  247|      0|        MP_DBG(mpctx, "Client for script %s is no longer alive. Marking as unloaded.\n", fname);
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  248|      0|        *pid = 0; // died
  249|      0|    }
  250|  46.4k|    if ((*pid > 0) != enable) {
  ------------------
  |  Branch (250:9): [True: 0, False: 46.4k]
  ------------------
  251|      0|        if (enable) {
  ------------------
  |  Branch (251:13): [True: 0, False: 0]
  ------------------
  252|      0|            *pid = mp_load_script(mpctx, fname);
  253|      0|        } else {
  254|      0|            char *name = mp_tprintf(22, "@%"PRIi64, *pid);
  ------------------
  |  |  165|      0|    mp_tprintf_buf((char[SIZE]){0}, (SIZE), (format), __VA_ARGS__)
  ------------------
  255|      0|            MP_DBG(mpctx, "Unloading script %s (disabled by option)\n", fname);
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  256|      0|            mp_client_send_event(mpctx, name, 0, MPV_EVENT_SHUTDOWN, NULL);
  257|       |            // note: there is no synchronization of script exit
  258|      0|        }
  259|      0|    }
  260|  46.4k|}

redraw_subs:
   57|  8.77k|{
   58|  26.3k|    for (int n = 0; n < num_ptracks[STREAM_SUB]; n++) {
  ------------------
  |  Branch (58:21): [True: 17.5k, False: 8.77k]
  ------------------
   59|  17.5k|        if (mpctx->current_track[n][STREAM_SUB] &&
  ------------------
  |  Branch (59:13): [True: 0, False: 17.5k]
  ------------------
   60|  17.5k|            mpctx->current_track[n][STREAM_SUB]->d_sub)
  ------------------
  |  Branch (60:13): [True: 0, False: 0]
  ------------------
   61|      0|        {
   62|      0|            mpctx->current_track[n][STREAM_SUB]->redraw_subs = true;
   63|      0|        }
   64|  17.5k|    }
   65|  8.77k|}
reset_subtitle_state:
   68|  94.7k|{
   69|  94.7k|    for (int n = 0; n < mpctx->num_tracks; n++)
  ------------------
  |  Branch (69:21): [True: 0, False: 94.7k]
  ------------------
   70|      0|        reset_subtitles(mpctx, mpctx->tracks[n]);
   71|  94.7k|    term_osd_clear_subs(mpctx);
   72|  94.7k|}
uninit_sub:
   75|  5.22k|{
   76|  5.22k|    if (track && track->d_sub) {
  ------------------
  |  Branch (76:9): [True: 5.22k, False: 0]
  |  Branch (76:18): [True: 0, False: 5.22k]
  ------------------
   77|      0|        int order = get_order(mpctx, track);
   78|      0|        reset_subtitles(mpctx, track);
   79|      0|        sub_select(track->d_sub, false);
   80|      0|        if (order >= 0) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            term_osd_set_subs(mpctx, NULL, order);
   82|      0|            osd_set_sub(mpctx->osd, order, NULL);
   83|      0|        }
   84|      0|        sub_destroy(track->d_sub);
   85|      0|        track->d_sub = NULL;
   86|      0|    }
   87|  5.22k|}
uninit_sub_all:
   90|  94.7k|{
   91|  99.9k|    for (int n = 0; n < mpctx->num_tracks; n++)
  ------------------
  |  Branch (91:21): [True: 5.22k, False: 94.7k]
  ------------------
   92|  5.22k|        uninit_sub(mpctx, mpctx->tracks[n]);
   93|  94.7k|}
update_subtitles:
  166|  87.7k|{
  167|  87.7k|    bool ok = true;
  168|   263k|    for (int n = 0; n < num_ptracks[STREAM_SUB]; n++)
  ------------------
  |  Branch (168:21): [True: 175k, False: 87.7k]
  ------------------
  169|   175k|        ok &= update_subtitle(mpctx, video_pts, mpctx->current_track[n][STREAM_SUB]);
  170|  87.7k|    return ok;
  171|  87.7k|}
reinit_sub:
  219|  9.07k|{
  220|  9.07k|    if (!track || !track->stream || track->stream->type != STREAM_SUB)
  ------------------
  |  Branch (220:9): [True: 9.07k, False: 0]
  |  Branch (220:19): [True: 0, False: 0]
  |  Branch (220:37): [True: 0, False: 0]
  ------------------
  221|  9.07k|        return;
  222|       |
  223|      0|    mp_assert(!track->d_sub);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  224|       |
  225|      0|    if (!init_subdec(mpctx, track)) {
  ------------------
  |  Branch (225:9): [True: 0, False: 0]
  ------------------
  226|      0|        error_on_track(mpctx, track);
  227|      0|        return;
  228|      0|    }
  229|       |
  230|      0|    sub_select(track->d_sub, true);
  231|      0|    int order = get_order(mpctx, track);
  232|      0|    osd_set_sub(mpctx->osd, order, track->d_sub);
  233|       |
  234|       |    // When paused we have to wait for packets to be available.
  235|       |    // Retry on a timeout until we get a packet. If still not successful,
  236|       |    // then queue it for later in the playloop (but this will have a delay).
  237|      0|    if (mpctx->playback_initialized) {
  ------------------
  |  Branch (237:9): [True: 0, False: 0]
  ------------------
  238|      0|        track->demuxer_ready = false;
  239|      0|        int64_t end = mp_time_ns() + MP_TIME_MS_TO_NS(50);
  ------------------
  |  |   60|      0|#define MP_TIME_MS_TO_NS(ms) ((ms) * INT64_C(1000000))
  ------------------
  240|      0|        while (!track->demuxer_ready && mp_time_ns() < end)
  ------------------
  |  Branch (240:16): [True: 0, False: 0]
  |  Branch (240:41): [True: 0, False: 0]
  ------------------
  241|      0|            track->demuxer_ready = update_subtitles(mpctx, mpctx->playback_pts) ||
  ------------------
  |  Branch (241:36): [True: 0, False: 0]
  ------------------
  242|      0|                                  !mpctx->paused;
  ------------------
  |  Branch (242:35): [True: 0, False: 0]
  ------------------
  243|      0|        if (!track->demuxer_ready)
  ------------------
  |  Branch (243:13): [True: 0, False: 0]
  ------------------
  244|      0|            mp_wakeup_core(mpctx);
  245|       |
  246|      0|    }
  247|      0|}
reinit_sub_all:
  250|  4.53k|{
  251|  13.6k|    for (int n = 0; n < num_ptracks[STREAM_SUB]; n++)
  ------------------
  |  Branch (251:21): [True: 9.07k, False: 4.53k]
  ------------------
  252|  9.07k|        reinit_sub(mpctx, mpctx->current_track[n][STREAM_SUB]);
  253|  4.53k|}
sub.c:update_subtitle:
   97|   175k|{
   98|   175k|    struct dec_sub *dec_sub = track ? track->d_sub : NULL;
  ------------------
  |  Branch (98:31): [True: 0, False: 175k]
  ------------------
   99|       |
  100|   175k|    if (!dec_sub)
  ------------------
  |  Branch (100:9): [True: 175k, False: 0]
  ------------------
  101|   175k|        return true;
  102|       |
  103|      0|    if (mpctx->vo_chain) {
  ------------------
  |  Branch (103:9): [True: 0, False: 0]
  ------------------
  104|      0|        struct mp_image_params params = mpctx->vo_chain->filter->input_params;
  105|      0|        if (params.imgfmt)
  ------------------
  |  Branch (105:13): [True: 0, False: 0]
  ------------------
  106|      0|            sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, &params);
  107|      0|    }
  108|       |
  109|       |    // Checking if packets have special animations is relatively expensive.
  110|       |    // This is only needed if we are rendering ASS subtitles with no video
  111|       |    // being played.
  112|      0|    bool still_image = mpctx->video_out && ((mpctx->video_status == STATUS_EOF &&
  ------------------
  |  Branch (112:24): [True: 0, False: 0]
  |  Branch (112:46): [True: 0, False: 0]
  ------------------
  113|      0|                       mpctx->opts->subs_rend->sub_past_video_end) ||
  ------------------
  |  Branch (113:24): [True: 0, False: 0]
  ------------------
  114|      0|                       !mpctx->current_track[0][STREAM_VIDEO] ||
  ------------------
  |  Branch (114:24): [True: 0, False: 0]
  ------------------
  115|      0|                       mpctx->current_track[0][STREAM_VIDEO]->image);
  ------------------
  |  Branch (115:24): [True: 0, False: 0]
  ------------------
  116|      0|    sub_control(dec_sub, SD_CTRL_SET_ANIMATED_CHECK, &still_image);
  117|       |
  118|      0|    if (track->demuxer->fully_read && sub_can_preload(dec_sub)) {
  ------------------
  |  Branch (118:9): [True: 0, False: 0]
  |  Branch (118:39): [True: 0, False: 0]
  ------------------
  119|       |        // Assume fully_read implies no interleaved audio/video streams.
  120|       |        // (Reading packets will change the demuxer position.)
  121|      0|        demux_seek(track->demuxer, 0, 0);
  122|      0|        sub_preload(dec_sub);
  123|      0|    }
  124|       |
  125|      0|    bool packets_read = false;
  126|      0|    bool sub_updated = false;
  127|      0|    sub_read_packets(dec_sub, video_pts, mpctx->paused, &packets_read, &sub_updated);
  128|       |
  129|      0|    double osd_pts = osd_get_force_video_pts(mpctx->osd);
  130|       |
  131|       |    // Check if we need to update subtitles for these special cases. Always
  132|       |    // update on discontinuities like seeking or a new file.
  133|      0|    if (sub_updated || track->redraw_subs || osd_pts == MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (133:9): [True: 0, False: 0]
  |  Branch (133:24): [True: 0, False: 0]
  |  Branch (133:46): [True: 0, False: 0]
  ------------------
  134|       |        // Always force a redecode of all packets if we seek on a still image.
  135|      0|        if (track->redraw_subs && still_image)
  ------------------
  |  Branch (135:13): [True: 0, False: 0]
  |  Branch (135:35): [True: 0, False: 0]
  ------------------
  136|      0|            sub_redecode_cached_packets(dec_sub);
  137|       |
  138|       |        // Handle displaying subtitles on terminal.
  139|      0|        if (track->selected && track->type == STREAM_SUB && !mpctx->video_out) {
  ------------------
  |  Branch (139:13): [True: 0, False: 0]
  |  Branch (139:32): [True: 0, False: 0]
  |  Branch (139:61): [True: 0, False: 0]
  ------------------
  140|      0|            char *text = sub_get_text(dec_sub, video_pts, SD_TEXT_TYPE_PLAIN);
  141|      0|            int order = get_order(mpctx, track);
  142|      0|            if (order >= 0)
  ------------------
  |  Branch (142:17): [True: 0, False: 0]
  ------------------
  143|      0|                term_osd_set_subs(mpctx, text, order);
  144|      0|            talloc_free(text);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  145|      0|        }
  146|       |
  147|       |        // Handle displaying subtitles on VO with no video being played. This is
  148|       |        // quite different, because normally subtitles are redrawn on new video
  149|       |        // frames, using the video frames' timestamps.
  150|      0|        if (still_image) {
  ------------------
  |  Branch (150:13): [True: 0, False: 0]
  ------------------
  151|      0|            if (osd_pts != video_pts) {
  ------------------
  |  Branch (151:17): [True: 0, False: 0]
  ------------------
  152|      0|                osd_set_force_video_pts(mpctx->osd, video_pts);
  153|      0|                osd_query_and_reset_want_redraw(mpctx->osd);
  154|      0|                vo_redraw(mpctx->video_out);
  155|      0|            }
  156|      0|        }
  157|      0|    }
  158|       |
  159|      0|    track->redraw_subs = false;
  160|      0|    return packets_read;
  161|   175k|}

reset_video_state:
   99|  99.7k|{
  100|  99.7k|    if (mpctx->vo_chain) {
  ------------------
  |  Branch (100:9): [True: 4.95k, False: 94.7k]
  ------------------
  101|  4.95k|        vo_chain_reset_state(mpctx->vo_chain);
  102|  4.95k|        struct track *t = mpctx->vo_chain->track;
  103|  4.95k|        if (t && t->dec)
  ------------------
  |  Branch (103:13): [True: 4.95k, False: 0]
  |  Branch (103:18): [True: 4.95k, False: 0]
  ------------------
  104|  4.95k|            mp_decoder_wrapper_set_play_dir(t->dec, mpctx->play_dir);
  105|  4.95k|    }
  106|       |
  107|  99.7k|    for (int n = 0; n < mpctx->num_next_frames; n++)
  ------------------
  |  Branch (107:21): [True: 0, False: 99.7k]
  ------------------
  108|      0|        mp_image_unrefp(&mpctx->next_frames[n]);
  109|  99.7k|    mpctx->num_next_frames = 0;
  110|  99.7k|    mp_image_unrefp(&mpctx->saved_frame);
  111|       |
  112|  99.7k|    mpctx->delay = 0;
  113|  99.7k|    mpctx->time_frame = 0;
  114|  99.7k|    mpctx->video_pts = MP_NOPTS_VALUE;
  ------------------
  |  |   38|  99.7k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  115|  99.7k|    mpctx->last_frame_duration = 0;
  116|  99.7k|    mpctx->num_past_frames = 0;
  117|  99.7k|    mpctx->total_avsync_change = 0;
  118|  99.7k|    mpctx->last_av_difference = 0;
  119|  99.7k|    mpctx->mistimed_frames_total = 0;
  120|  99.7k|    mpctx->drop_message_shown = 0;
  121|  99.7k|    mpctx->display_sync_drift_dir = 0;
  122|  99.7k|    mpctx->display_sync_error = 0;
  123|  99.7k|    mpctx->display_sync_active = 0;
  124|       |
  125|  99.7k|    mpctx->video_status = mpctx->vo_chain ? STATUS_SYNCING : STATUS_EOF;
  ------------------
  |  Branch (125:27): [True: 4.95k, False: 94.7k]
  ------------------
  126|  99.7k|}
uninit_video_out:
  129|  26.6k|{
  130|  26.6k|    uninit_video_chain(mpctx);
  131|  26.6k|    if (mpctx->video_out) {
  ------------------
  |  Branch (131:9): [True: 2.78k, False: 23.8k]
  ------------------
  132|  2.78k|        vo_destroy(mpctx->video_out);
  133|  2.78k|        mpctx->video_out = NULL;
  134|  2.78k|        mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
  135|  2.78k|    }
  136|  26.6k|}
uninit_video_chain:
  159|   123k|{
  160|   123k|    if (mpctx->vo_chain) {
  ------------------
  |  Branch (160:9): [True: 2.93k, False: 120k]
  ------------------
  161|  2.93k|        reset_video_state(mpctx);
  162|  2.93k|        vo_chain_uninit(mpctx->vo_chain);
  163|  2.93k|        mpctx->vo_chain = NULL;
  164|       |
  165|  2.93k|        mpctx->video_status = STATUS_EOF;
  166|       |
  167|  2.93k|        mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
  168|  2.93k|    }
  169|   123k|}
init_video_decoder:
  172|  2.93k|{
  173|  2.93k|    mp_assert(!track->dec);
  ------------------
  |  |   41|  2.93k|#define mp_assert assert
  ------------------
  174|  2.93k|    if (!track->stream)
  ------------------
  |  Branch (174:9): [True: 0, False: 2.93k]
  ------------------
  175|      0|        goto err_out;
  176|       |
  177|  2.93k|    struct mp_filter *parent = mpctx->filter_root;
  178|       |
  179|       |    // If possible, set this as parent so the decoder gets the hwdec and DR
  180|       |    // interfaces.
  181|       |    // Note: We rely on being able to get rid of all references to the VO by
  182|       |    //       destroying the VO chain. Thus, decoders not linked to vo_chain
  183|       |    //       must not use the hwdec context.
  184|  2.93k|    if (track->vo_c)
  ------------------
  |  Branch (184:9): [True: 2.93k, False: 0]
  ------------------
  185|  2.93k|        parent = track->vo_c->filter->f;
  186|       |
  187|  2.93k|    track->dec = mp_decoder_wrapper_create(parent, track->stream);
  188|  2.93k|    if (!track->dec)
  ------------------
  |  Branch (188:9): [True: 0, False: 2.93k]
  ------------------
  189|      0|        goto err_out;
  190|       |
  191|  2.93k|    if (!mp_decoder_wrapper_reinit(track->dec))
  ------------------
  |  Branch (191:9): [True: 903, False: 2.02k]
  ------------------
  192|    903|        goto err_out;
  193|       |
  194|  2.02k|    return 1;
  195|       |
  196|    903|err_out:
  197|    903|    if (track->sink)
  ------------------
  |  Branch (197:9): [True: 0, False: 903]
  ------------------
  198|      0|        mp_pin_disconnect(track->sink);
  199|    903|    track->sink = NULL;
  200|    903|    error_on_track(mpctx, track);
  201|    903|    return 0;
  202|  2.93k|}
reinit_video_chain:
  205|  5.44k|{
  206|  5.44k|    struct track *track = mpctx->current_track[0][STREAM_VIDEO];
  207|  5.44k|    if (!track || !track->stream) {
  ------------------
  |  Branch (207:9): [True: 2.51k, False: 2.93k]
  |  Branch (207:19): [True: 0, False: 2.93k]
  ------------------
  208|  2.51k|        error_on_track(mpctx, track);
  209|  2.51k|        return;
  210|  2.51k|    }
  211|  2.93k|    reinit_video_chain_src(mpctx, track);
  212|  2.93k|}
reinit_video_chain_src:
  224|  2.93k|{
  225|  2.93k|    mp_assert(!mpctx->vo_chain);
  ------------------
  |  |   41|  2.93k|#define mp_assert assert
  ------------------
  226|       |
  227|  2.93k|    if (!mpctx->video_out) {
  ------------------
  |  Branch (227:9): [True: 2.78k, False: 151]
  ------------------
  228|  2.78k|        struct vo_extra ex = {
  229|  2.78k|            .input_ctx = mpctx->input,
  230|  2.78k|            .osd = mpctx->osd,
  231|  2.78k|            .encode_lavc_ctx = mpctx->encode_lavc_ctx,
  232|  2.78k|            .wakeup_cb = mp_wakeup_core_cb,
  233|  2.78k|            .wakeup_ctx = mpctx,
  234|  2.78k|        };
  235|  2.78k|        mpctx->video_out = init_best_video_out(mpctx->global, &ex);
  236|  2.78k|        if (!mpctx->video_out) {
  ------------------
  |  Branch (236:13): [True: 0, False: 2.78k]
  ------------------
  237|      0|            MP_FATAL(mpctx, "Error opening/initializing "
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  238|      0|                    "the selected video_out (--vo) device.\n");
  239|      0|            mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
  240|      0|            goto err_out;
  241|      0|        }
  242|  2.78k|        mpctx->mouse_cursor_visible = true;
  243|  2.78k|    }
  244|       |
  245|  2.93k|    update_window_title(mpctx, true);
  246|       |
  247|  2.93k|    struct vo_chain *vo_c = talloc_zero(NULL, struct vo_chain);
  ------------------
  |  |   27|  2.93k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  2.93k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  2.93k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  248|  2.93k|    mpctx->vo_chain = vo_c;
  249|  2.93k|    vo_c->log = mpctx->log;
  250|  2.93k|    vo_c->vo = mpctx->video_out;
  251|  2.93k|    vo_c->filter =
  252|  2.93k|        mp_output_chain_create(mpctx->filter_root, MP_OUTPUT_CHAIN_VIDEO);
  253|  2.93k|    mp_output_chain_set_vo(vo_c->filter, vo_c->vo);
  254|  2.93k|    vo_c->filter->update_subtitles = filter_update_subtitles;
  255|  2.93k|    vo_c->filter->update_subtitles_ctx = mpctx;
  256|       |
  257|  2.93k|    if (track) {
  ------------------
  |  Branch (257:9): [True: 2.93k, False: 0]
  ------------------
  258|  2.93k|        vo_c->track = track;
  259|  2.93k|        track->vo_c = vo_c;
  260|  2.93k|        if (!init_video_decoder(mpctx, track))
  ------------------
  |  Branch (260:13): [True: 903, False: 2.02k]
  ------------------
  261|    903|            goto err_out;
  262|       |
  263|  2.02k|        vo_c->dec_src = track->dec->f->pins[0];
  264|  2.02k|        vo_c->filter->container_fps =
  265|  2.02k|            mp_decoder_wrapper_get_container_fps(track->dec);
  266|  2.02k|        vo_c->is_coverart = !!track->attached_picture;
  267|  2.02k|        vo_c->is_sparse = track->stream->still_image || vo_c->is_coverart;
  ------------------
  |  Branch (267:27): [True: 0, False: 2.02k]
  |  Branch (267:57): [True: 0, False: 2.02k]
  ------------------
  268|       |
  269|  2.02k|        if (vo_c->is_coverart)
  ------------------
  |  Branch (269:13): [True: 0, False: 2.02k]
  ------------------
  270|      0|            mp_decoder_wrapper_set_coverart_flag(track->dec, true);
  271|       |
  272|  2.02k|        track->vo_c = vo_c;
  273|  2.02k|        vo_c->track = track;
  274|       |
  275|  2.02k|        mp_pin_connect(vo_c->filter->f->pins[0], vo_c->dec_src);
  276|  2.02k|    }
  277|       |
  278|  2.02k|    if (!recreate_video_filters(mpctx))
  ------------------
  |  Branch (278:9): [True: 0, False: 2.02k]
  ------------------
  279|      0|        goto err_out;
  280|       |
  281|  2.02k|    update_content_type(mpctx, track);
  282|  2.02k|    update_screensaver_state(mpctx);
  283|       |
  284|  2.02k|    vo_set_paused(vo_c->vo, get_internal_paused(mpctx));
  285|       |
  286|  2.02k|    reset_video_state(mpctx);
  287|  2.02k|    term_osd_clear_subs(mpctx);
  288|       |
  289|  2.02k|    return;
  290|       |
  291|    903|err_out:
  292|    903|    uninit_video_chain(mpctx);
  293|    903|    error_on_track(mpctx, track);
  294|    903|    handle_force_window(mpctx, true);
  295|    903|}
write_video:
 1049|  93.3k|{
 1050|  93.3k|    struct MPOpts *opts = mpctx->opts;
 1051|       |
 1052|  93.3k|    if (!mpctx->vo_chain)
  ------------------
  |  Branch (1052:9): [True: 12.5k, False: 80.7k]
  ------------------
 1053|  12.5k|        return;
 1054|  80.7k|    struct track *track = mpctx->vo_chain->track;
 1055|  80.7k|    struct vo_chain *vo_c = mpctx->vo_chain;
 1056|  80.7k|    struct vo *vo = vo_c->vo;
 1057|       |
 1058|  80.7k|    if (vo_c->filter->reconfig_happened) {
  ------------------
  |  Branch (1058:9): [True: 9.26k, False: 71.5k]
  ------------------
 1059|  9.26k|        mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
 1060|  9.26k|        vo_c->filter->reconfig_happened = false;
 1061|  9.26k|    }
 1062|       |
 1063|       |    // Actual playback starts when both audio and video are ready.
 1064|  80.7k|    if (mpctx->video_status == STATUS_READY)
  ------------------
  |  Branch (1064:9): [True: 0, False: 80.7k]
  ------------------
 1065|      0|        return;
 1066|       |
 1067|  80.7k|    if (mpctx->paused && mpctx->video_status >= STATUS_READY)
  ------------------
  |  Branch (1067:9): [True: 77, False: 80.6k]
  |  Branch (1067:26): [True: 77, False: 0]
  ------------------
 1068|     77|        return;
 1069|       |
 1070|  80.6k|    bool logical_eof = false;
 1071|  80.6k|    int r = video_output_image(mpctx, &logical_eof);
 1072|  80.6k|    MP_TRACE(mpctx, "video_output_image: r=%d/eof=%d/st=%s\n", r, logical_eof,
  ------------------
  |  |   90|  80.6k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  80.6k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1073|  80.6k|             mp_status_str(mpctx->video_status));
 1074|       |
 1075|  80.6k|    if (r < 0)
  ------------------
  |  Branch (1075:9): [True: 0, False: 80.6k]
  ------------------
 1076|      0|        goto error;
 1077|       |
 1078|  80.6k|    if (r == VD_WAIT) {
  ------------------
  |  Branch (1078:9): [True: 4.84k, False: 75.8k]
  ------------------
 1079|       |        // Heuristic to detect underruns.
 1080|  4.84k|        if (mpctx->video_status == STATUS_PLAYING && !vo_still_displaying(vo) &&
  ------------------
  |  Branch (1080:13): [True: 798, False: 4.05k]
  |  Branch (1080:54): [True: 798, False: 0]
  ------------------
 1081|  4.84k|            !vo_c->underrun_signaled)
  ------------------
  |  Branch (1081:13): [True: 30, False: 768]
  ------------------
 1082|     30|        {
 1083|     30|            vo_c->underrun = true;
 1084|     30|            vo_c->underrun_signaled = true;
 1085|     30|        }
 1086|       |        // Demuxer will wake us up for more packets to decode.
 1087|  4.84k|        return;
 1088|  4.84k|    }
 1089|       |
 1090|  75.8k|    if (r == VD_EOF) {
  ------------------
  |  Branch (1090:9): [True: 3.54k, False: 72.3k]
  ------------------
 1091|  3.54k|        if (check_for_hwdec_fallback(mpctx))
  ------------------
  |  Branch (1091:13): [True: 0, False: 3.54k]
  ------------------
 1092|      0|            return;
 1093|  3.54k|        if (check_for_forced_eof(mpctx)) {
  ------------------
  |  Branch (1093:13): [True: 0, False: 3.54k]
  ------------------
 1094|      0|            uninit_video_chain(mpctx);
 1095|      0|            handle_force_window(mpctx, true);
 1096|      0|            return;
 1097|      0|        }
 1098|  3.54k|        if (vo_c->filter->failed_output_conversion)
  ------------------
  |  Branch (1098:13): [True: 0, False: 3.54k]
  ------------------
 1099|      0|            goto error;
 1100|       |
 1101|  3.54k|        mpctx->delay = 0;
 1102|  3.54k|        mpctx->last_av_difference = 0;
 1103|       |
 1104|  3.54k|        if (mpctx->video_status <= STATUS_PLAYING) {
  ------------------
  |  Branch (1104:13): [True: 2.02k, False: 1.51k]
  ------------------
 1105|  2.02k|            mpctx->video_status = STATUS_DRAINING;
 1106|  2.02k|            get_relative_time(mpctx);
 1107|  2.02k|            if (vo_c->is_sparse && !mpctx->ao_chain) {
  ------------------
  |  Branch (1107:17): [True: 0, False: 2.02k]
  |  Branch (1107:36): [True: 0, False: 0]
  ------------------
 1108|      0|                MP_VERBOSE(mpctx, "assuming this is an image\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1109|      0|                mpctx->time_frame += opts->image_display_duration;
 1110|  2.02k|            } else if (mpctx->last_frame_duration > 0) {
  ------------------
  |  Branch (1110:24): [True: 542, False: 1.48k]
  ------------------
 1111|    542|                MP_VERBOSE(mpctx, "using demuxer frame duration for last frame\n");
  ------------------
  |  |   88|    542|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    542|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1112|    542|                mpctx->time_frame += mpctx->last_frame_duration;
 1113|  1.48k|            } else {
 1114|  1.48k|                mpctx->time_frame = 0;
 1115|  1.48k|            }
 1116|       |            // Encode mode can't honor this; it'll only delay finishing.
 1117|  2.02k|            if (mpctx->encode_lavc_ctx)
  ------------------
  |  Branch (1117:17): [True: 0, False: 2.02k]
  ------------------
 1118|      0|                mpctx->time_frame = 0;
 1119|  2.02k|        }
 1120|       |
 1121|       |        // Wait for the VO to signal actual EOF, then exit if the frame timer
 1122|       |        // has expired.
 1123|  3.54k|        bool has_frame = vo_has_frame(vo); // maybe not configured
 1124|  3.54k|        if (mpctx->video_status == STATUS_DRAINING &&
  ------------------
  |  Branch (1124:13): [True: 2.70k, False: 838]
  ------------------
 1125|  3.54k|            (vo_is_ready_for_frame(vo, -1) || !has_frame))
  ------------------
  |  Branch (1125:14): [True: 1.22k, False: 1.47k]
  |  Branch (1125:47): [True: 1.46k, False: 14]
  ------------------
 1126|  2.69k|        {
 1127|  2.69k|            mpctx->time_frame -= get_relative_time(mpctx);
 1128|  2.69k|            mp_set_timeout(mpctx, mpctx->time_frame);
 1129|  2.69k|            if (mpctx->time_frame <= 0 || !has_frame) {
  ------------------
  |  Branch (1129:17): [True: 2.02k, False: 666]
  |  Branch (1129:43): [True: 0, False: 666]
  ------------------
 1130|  2.02k|                MP_VERBOSE(mpctx, "video EOF reached\n");
  ------------------
  |  |   88|  2.02k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  2.02k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1131|  2.02k|                mpctx->video_status = STATUS_EOF;
 1132|  2.02k|            }
 1133|  2.69k|        }
 1134|       |
 1135|       |        // Avoid pointlessly spamming the logs every frame.
 1136|  3.54k|        if (!vo_c->is_sparse || !vo_c->sparse_eof_signalled) {
  ------------------
  |  Branch (1136:13): [True: 3.54k, False: 0]
  |  Branch (1136:33): [True: 0, False: 0]
  ------------------
 1137|  3.54k|            MP_DBG(mpctx, "video EOF (status=%d)\n", mpctx->video_status);
  ------------------
  |  |   89|  3.54k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  3.54k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1138|  3.54k|            vo_c->sparse_eof_signalled = vo_c->is_sparse;
 1139|  3.54k|        }
 1140|  3.54k|        return;
 1141|  3.54k|    }
 1142|       |
 1143|  72.3k|    if (mpctx->video_status > STATUS_PLAYING)
  ------------------
  |  Branch (1143:9): [True: 0, False: 72.3k]
  ------------------
 1144|      0|        mpctx->video_status = STATUS_PLAYING;
 1145|       |
 1146|  72.3k|    if (r != VD_NEW_FRAME) {
  ------------------
  |  Branch (1146:9): [True: 0, False: 72.3k]
  ------------------
 1147|      0|        mp_wakeup_core(mpctx); // Decode more in next iteration.
 1148|      0|        return;
 1149|      0|    }
 1150|       |
 1151|  72.3k|    if (logical_eof && !mpctx->num_past_frames && mpctx->num_next_frames == 1 &&
  ------------------
  |  Branch (1151:9): [True: 0, False: 72.3k]
  |  Branch (1151:24): [True: 0, False: 0]
  |  Branch (1151:51): [True: 0, False: 0]
  ------------------
 1152|  72.3k|        use_video_lookahead(mpctx) && !vo_c->is_sparse)
  ------------------
  |  Branch (1152:9): [True: 0, False: 0]
  |  Branch (1152:39): [True: 0, False: 0]
  ------------------
 1153|      0|    {
 1154|       |        // Too much danger to accidentally mark video as sparse when e.g.
 1155|       |        // seeking exactly to the last frame, so as a heuristic, do this only
 1156|       |        // if it looks like the "first" video frame (unreliable, but often
 1157|       |        // works out well). Helps with seeking with single-image video tracks,
 1158|       |        // as well as detecting whether as video track is really an image.
 1159|      0|        if (mpctx->next_frames[0]->pts == 0) {
  ------------------
  |  Branch (1159:13): [True: 0, False: 0]
  ------------------
 1160|      0|            MP_VERBOSE(mpctx, "assuming single-image video stream\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1161|      0|            vo_c->is_sparse = true;
 1162|      0|        }
 1163|      0|    }
 1164|       |
 1165|       |    // Inject vo crop to notify and reconfig if needed
 1166|  72.3k|    apply_video_crop(mpctx, vo);
 1167|       |
 1168|       |    // Filter output is different from VO input?
 1169|  72.3k|    struct mp_image_params *p = &mpctx->next_frames[0]->params;
 1170|  72.3k|    if (!vo->params || !mp_image_params_static_equal(p, vo->params)) {
  ------------------
  |  Branch (1170:9): [True: 558, False: 71.7k]
  |  Branch (1170:24): [True: 8.70k, False: 63.0k]
  ------------------
 1171|       |        // Changing config deletes the current frame; wait until it's finished.
 1172|  9.26k|        if (vo_still_displaying(vo)) {
  ------------------
  |  Branch (1172:13): [True: 0, False: 9.26k]
  ------------------
 1173|      0|            vo_request_wakeup_on_done(vo);
 1174|      0|            return;
 1175|      0|        }
 1176|       |
 1177|  9.26k|        const struct vo_driver *info = mpctx->video_out->driver;
 1178|  9.26k|        char extra[20] = {0};
 1179|  9.26k|        if (p->p_w != p->p_h) {
  ------------------
  |  Branch (1179:13): [True: 0, False: 9.26k]
  ------------------
 1180|      0|            int d_w, d_h;
 1181|      0|            mp_image_params_get_dsize(p, &d_w, &d_h);
 1182|      0|            snprintf(extra, sizeof(extra), " => %dx%d", d_w, d_h);
 1183|      0|        }
 1184|  9.26k|        char sfmt[20] = {0};
 1185|  9.26k|        if (p->hw_subfmt)
  ------------------
  |  Branch (1185:13): [True: 0, False: 9.26k]
  ------------------
 1186|      0|            snprintf(sfmt, sizeof(sfmt), "[%s]", mp_imgfmt_to_name(p->hw_subfmt));
  ------------------
  |  |  331|      0|#define mp_imgfmt_to_name(fmt) mp_imgfmt_to_name_buf((char[16]){0}, 16, (fmt))
  ------------------
 1187|  9.26k|        MP_INFO(mpctx, "VO: [%s] %dx%d%s %s%s\n",
  ------------------
  |  |   87|  9.26k|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.26k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1188|  9.26k|                info->name, p->w, p->h, extra, mp_imgfmt_to_name(p->imgfmt), sfmt);
 1189|  9.26k|        MP_VERBOSE(mpctx, "VO: Description: %s\n", info->description);
  ------------------
  |  |   88|  9.26k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.26k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1190|       |
 1191|  9.26k|        int vo_r = vo_reconfig2(vo, mpctx->next_frames[0]);
 1192|  9.26k|        if (vo_r < 0) {
  ------------------
  |  Branch (1192:13): [True: 0, False: 9.26k]
  ------------------
 1193|      0|            mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
 1194|      0|            goto error;
 1195|      0|        }
 1196|  9.26k|        mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
 1197|  63.0k|    } else {
 1198|       |        // Update parameters that don't require reconfiguring the VO.
 1199|  63.0k|        mp_mutex_lock(&vo->params_mutex);
  ------------------
  |  |  131|  63.0k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1200|  63.0k|        mp_image_params_update_dynamic(vo->params, p, vo->has_peak_detect_values);
 1201|  63.0k|        mp_mutex_unlock(&vo->params_mutex);
  ------------------
  |  |  133|  63.0k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1202|  63.0k|    }
 1203|       |
 1204|  72.3k|    mpctx->time_frame -= get_relative_time(mpctx);
 1205|  72.3k|    update_avsync_before_frame(mpctx);
 1206|       |
 1207|       |    // Enforce timing subtitles to video frames.
 1208|  72.3k|    osd_set_force_video_pts(mpctx->osd, MP_NOPTS_VALUE);
  ------------------
  |  |   38|  72.3k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
 1209|       |
 1210|  72.3k|    if (!update_subtitles(mpctx, mpctx->next_frames[0]->pts)) {
  ------------------
  |  Branch (1210:9): [True: 0, False: 72.3k]
  ------------------
 1211|      0|        MP_VERBOSE(mpctx, "Video frame delayed due to waiting on subtitles.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1212|      0|        return;
 1213|      0|    }
 1214|       |
 1215|  72.3k|    double time_frame = MPMAX(mpctx->time_frame, -1);
  ------------------
  |  |   43|  72.3k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 72.3k, False: 0]
  |  |  ------------------
  ------------------
 1216|  72.3k|    int64_t pts = mp_time_ns() + (int64_t)(time_frame * 1e9);
 1217|       |
 1218|       |    // wait until VO wakes us up to get more frames
 1219|       |    // (NB: in theory, the 1st frame after display sync mode change uses the
 1220|       |    //      wrong waiting mode)
 1221|  72.3k|    if (!vo_is_ready_for_frame(vo, mpctx->display_sync_active ? -1 : pts))
  ------------------
  |  Branch (1221:9): [True: 328, False: 71.9k]
  |  Branch (1221:36): [True: 0, False: 72.3k]
  ------------------
 1222|    328|        return;
 1223|       |
 1224|  71.9k|    mp_assert(mpctx->num_next_frames >= 1);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
 1225|       |
 1226|  71.9k|    if (mpctx->num_past_frames >= MAX_NUM_VO_PTS)
  ------------------
  |  Branch (1226:9): [True: 40.6k, False: 31.2k]
  ------------------
 1227|  40.6k|        mpctx->num_past_frames--;
 1228|  71.9k|    MP_TARRAY_INSERT_AT(mpctx, mpctx->past_frames, mpctx->num_past_frames, 0,
  ------------------
  |  |  115|  71.9k|    do {                                            \
  |  |  116|  71.9k|        size_t at_ = (at);                          \
  |  |  117|  71.9k|        assert(at_ <= (idxvar));                    \
  |  |  118|  71.9k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  71.9k|    do {                                            \
  |  |  |  |   97|  71.9k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  71.9k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  71.9k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  71.9k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 2.41k, False: 69.5k]
  |  |  |  |  ------------------
  |  |  |  |   99|  71.9k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  2.41k|    do {                                                        \
  |  |  |  |  |  |   89|  2.41k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  2.41k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  2.41k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  2.41k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  2.41k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  2.41k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  2.41k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  71.9k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|  71.9k|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|  71.9k|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|  71.9k|        (idxvar)++;                                 \
  |  |  122|  71.9k|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|  71.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1229|  71.9k|                        (struct frame_info){0});
 1230|  71.9k|    mpctx->past_frames[0] = (struct frame_info){
 1231|  71.9k|        .pts = mpctx->next_frames[0]->pts,
 1232|  71.9k|        .num_vsyncs = -1,
 1233|  71.9k|    };
 1234|  71.9k|    calculate_frame_duration(mpctx);
 1235|       |
 1236|  71.9k|    int req = vo_get_num_req_frames(mpctx->video_out);
 1237|  71.9k|    mp_assert(req >= 1 && req <= VO_MAX_REQ_FRAMES);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
 1238|  71.9k|    struct vo_frame dummy = {
 1239|  71.9k|        .pts = pts,
 1240|  71.9k|        .duration = -1,
 1241|  71.9k|        .still = mpctx->step_frames > 0,
 1242|  71.9k|        .can_drop = opts->frame_dropping & 1,
 1243|  71.9k|        .num_frames = MPMIN(mpctx->num_next_frames, req),
  ------------------
  |  |   44|  71.9k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 71.9k]
  |  |  ------------------
  ------------------
 1244|  71.9k|        .num_vsyncs = 1,
 1245|  71.9k|    };
 1246|   143k|    for (int n = 0; n < dummy.num_frames; n++)
  ------------------
  |  Branch (1246:21): [True: 71.9k, False: 71.9k]
  ------------------
 1247|  71.9k|        dummy.frames[n] = mpctx->next_frames[n];
 1248|  71.9k|    struct vo_frame *frame = vo_frame_ref(&dummy);
 1249|       |
 1250|  71.9k|    double diff = mpctx->past_frames[0].approx_duration;
 1251|  71.9k|    if (opts->untimed || (vo->driver->caps & VO_CAP_UNTIMED))
  ------------------
  |  Branch (1251:9): [True: 71.9k, False: 0]
  |  Branch (1251:26): [True: 0, False: 0]
  ------------------
 1252|  71.9k|        diff = -1; // disable frame dropping and aspects of frame timing
 1253|  71.9k|    if (diff >= 0) {
  ------------------
  |  Branch (1253:9): [True: 0, False: 71.9k]
  ------------------
 1254|      0|        diff /= mpctx->video_speed;
 1255|      0|        frame->duration = MP_TIME_S_TO_NS(MPCLAMP(diff, 0, 10));
  ------------------
  |  |   59|      0|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  |  |  ------------------
  |  |  |  Branch (59:30): [True: 0, False: 0]
  |  |  |  Branch (59:30): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1256|      0|    }
 1257|       |
 1258|  71.9k|    mpctx->video_pts = mpctx->next_frames[0]->pts;
 1259|  71.9k|    mpctx->last_frame_duration =
 1260|  71.9k|        mpctx->next_frames[0]->pkt_duration / mpctx->video_speed;
 1261|       |
 1262|  71.9k|    shift_frames(mpctx);
 1263|       |
 1264|  71.9k|    schedule_frame(mpctx, frame);
 1265|       |
 1266|  71.9k|    mpctx->osd_force_update = true;
 1267|  71.9k|    update_osd_msg(mpctx);
 1268|       |
 1269|  71.9k|    vo_queue_frame(vo, frame);
 1270|       |
 1271|  71.9k|    check_framedrop(mpctx, vo_c);
 1272|       |
 1273|       |    // The frames were shifted down; "initialize" the new first entry.
 1274|  71.9k|    if (mpctx->num_next_frames >= 1)
  ------------------
  |  Branch (1274:9): [True: 0, False: 71.9k]
  ------------------
 1275|      0|        handle_new_frame(mpctx);
 1276|       |
 1277|  71.9k|    mpctx->shown_vframes++;
 1278|  71.9k|    if (mpctx->video_status < STATUS_PLAYING) {
  ------------------
  |  Branch (1278:9): [True: 561, False: 71.4k]
  ------------------
 1279|    561|        mpctx->video_status = STATUS_READY;
 1280|       |        // After a seek, make sure to wait until the first frame is visible.
 1281|    561|        if (!opts->video_latency_hacks) {
  ------------------
  |  Branch (1281:13): [True: 561, False: 0]
  ------------------
 1282|    561|            vo_wait_frame(vo);
 1283|    561|            MP_VERBOSE(mpctx, "first video frame after restart shown\n");
  ------------------
  |  |   88|    561|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    561|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1284|    561|        }
 1285|    561|    }
 1286|       |
 1287|  71.9k|    mp_notify(mpctx, MPV_EVENT_TICK, NULL);
 1288|       |
 1289|       |    // hr-seek past EOF -> returns last frame, but terminates playback. The
 1290|       |    // early EOF is needed to trigger the exit before the next seek is executed.
 1291|       |    // Always using early EOF breaks other cases, like images.
 1292|  71.9k|    if (logical_eof && !mpctx->num_next_frames && mpctx->ao_chain)
  ------------------
  |  Branch (1292:9): [True: 0, False: 71.9k]
  |  Branch (1292:24): [True: 0, False: 0]
  |  Branch (1292:51): [True: 0, False: 0]
  ------------------
 1293|      0|        mpctx->video_status = STATUS_EOF;
 1294|       |
 1295|  71.9k|    if (mpctx->video_status != STATUS_EOF) {
  ------------------
  |  Branch (1295:9): [True: 71.9k, False: 0]
  ------------------
 1296|  71.9k|        if (mpctx->step_frames > 0) {
  ------------------
  |  Branch (1296:13): [True: 0, False: 71.9k]
  ------------------
 1297|      0|            mpctx->step_frames--;
 1298|      0|            if (!mpctx->step_frames) {
  ------------------
  |  Branch (1298:17): [True: 0, False: 0]
  ------------------
 1299|      0|                set_pause_state(mpctx, true);
 1300|      0|                step_frame_mute(mpctx, false);
 1301|      0|            }
 1302|      0|        }
 1303|  71.9k|        if (mpctx->max_frames == 0 && !mpctx->stop_play)
  ------------------
  |  Branch (1303:13): [True: 0, False: 71.9k]
  |  Branch (1303:39): [True: 0, False: 0]
  ------------------
 1304|      0|            mpctx->stop_play = AT_END_OF_FILE;
 1305|  71.9k|        if (mpctx->max_frames > 0)
  ------------------
  |  Branch (1305:13): [True: 0, False: 71.9k]
  ------------------
 1306|      0|            mpctx->max_frames--;
 1307|  71.9k|    }
 1308|       |
 1309|  71.9k|    vo_c->underrun_signaled = false;
 1310|       |
 1311|  71.9k|    if (mpctx->video_status == STATUS_EOF || mpctx->stop_play)
  ------------------
  |  Branch (1311:9): [True: 0, False: 71.9k]
  |  Branch (1311:46): [True: 0, False: 71.9k]
  ------------------
 1312|      0|        mp_wakeup_core(mpctx);
 1313|  71.9k|    return;
 1314|       |
 1315|      0|error:
 1316|      0|    MP_FATAL(mpctx, "Could not initialize video chain.\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1317|      0|    uninit_video_chain(mpctx);
 1318|      0|    error_on_track(mpctx, track);
 1319|      0|    handle_force_window(mpctx, true);
 1320|      0|    mp_wakeup_core(mpctx);
 1321|      0|}
video.c:recreate_video_filters:
   66|  2.02k|{
   67|  2.02k|    struct MPOpts *opts = mpctx->opts;
   68|  2.02k|    struct vo_chain *vo_c = mpctx->vo_chain;
   69|  2.02k|    mp_assert(vo_c);
  ------------------
  |  |   41|  2.02k|#define mp_assert assert
  ------------------
   70|       |
   71|  2.02k|    return mp_output_chain_update_filters(vo_c->filter, opts->vf_settings);
   72|  2.02k|}
video.c:vo_chain_reset_state:
   92|  4.95k|{
   93|  4.95k|    vo_seek_reset(vo_c->vo);
   94|  4.95k|    vo_c->underrun = false;
   95|  4.95k|    vo_c->underrun_signaled = false;
   96|  4.95k|}
video.c:vo_chain_uninit:
  139|  2.93k|{
  140|  2.93k|    struct track *track = vo_c->track;
  141|  2.93k|    if (track) {
  ------------------
  |  Branch (141:9): [True: 2.93k, False: 0]
  ------------------
  142|  2.93k|        mp_assert(track->vo_c == vo_c);
  ------------------
  |  |   41|  2.93k|#define mp_assert assert
  ------------------
  143|  2.93k|        track->vo_c = NULL;
  144|  2.93k|        if (vo_c->dec_src)
  ------------------
  |  Branch (144:13): [True: 2.02k, False: 903]
  ------------------
  145|  2.93k|            mp_assert(track->dec->f->pins[0] == vo_c->dec_src);
  ------------------
  |  |   41|  2.93k|#define mp_assert assert
  ------------------
  146|  2.93k|        talloc_free(track->dec->f);
  ------------------
  |  |   47|  2.93k|#define talloc_free                     ta_free
  ------------------
  147|  2.93k|        track->dec = NULL;
  148|  2.93k|    }
  149|       |
  150|  2.93k|    if (vo_c->filter_src)
  ------------------
  |  Branch (150:9): [True: 0, False: 2.93k]
  ------------------
  151|      0|        mp_pin_disconnect(vo_c->filter_src);
  152|       |
  153|  2.93k|    talloc_free(vo_c->filter->f);
  ------------------
  |  |   47|  2.93k|#define talloc_free                     ta_free
  ------------------
  154|  2.93k|    talloc_free(vo_c);
  ------------------
  |  |   47|  2.93k|#define talloc_free                     ta_free
  ------------------
  155|       |    // this does not free the VO
  156|  2.93k|}
video.c:filter_update_subtitles:
  215|  71.9k|{
  216|  71.9k|    struct MPContext *mpctx = ctx;
  217|       |
  218|  71.9k|    if (osd_get_render_subs_in_filter(mpctx->osd))
  ------------------
  |  Branch (218:9): [True: 0, False: 71.9k]
  ------------------
  219|      0|        update_subtitles(mpctx, pts);
  220|  71.9k|}
video.c:video_output_image:
  467|  80.6k|{
  468|  80.6k|    struct vo_chain *vo_c = mpctx->vo_chain;
  469|  80.6k|    bool hrseek = false;
  470|  80.6k|    double hrseek_pts = mpctx->hrseek_pts;
  471|  80.6k|    double tolerance = mpctx->hrseek_backstep ? 0 : .005;
  ------------------
  |  Branch (471:24): [True: 0, False: 80.6k]
  ------------------
  472|  80.6k|    if (mpctx->video_status == STATUS_SYNCING) {
  ------------------
  |  Branch (472:9): [True: 6.07k, False: 74.6k]
  ------------------
  473|  6.07k|        hrseek = mpctx->hrseek_active;
  474|       |        // playback_pts is normally only set when audio and video have started
  475|       |        // playing normally. If video is in syncing mode, then this must mean
  476|       |        // video was just enabled via track switching - skip to current time.
  477|  6.07k|        if (!hrseek && mpctx->playback_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  6.07k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (477:13): [True: 6.07k, False: 0]
  |  Branch (477:24): [True: 0, False: 6.07k]
  ------------------
  478|      0|            hrseek = true;
  479|      0|            hrseek_pts = mpctx->playback_pts;
  480|      0|        }
  481|  6.07k|    }
  482|       |
  483|  80.6k|    if (vo_c->is_coverart) {
  ------------------
  |  Branch (483:9): [True: 0, False: 80.6k]
  ------------------
  484|      0|        *logical_eof = true;
  485|      0|        if (vo_has_frame(mpctx->video_out))
  ------------------
  |  Branch (485:13): [True: 0, False: 0]
  ------------------
  486|      0|            return VD_EOF;
  487|      0|        hrseek = false;
  488|      0|    }
  489|       |
  490|  80.6k|    if (have_new_frame(mpctx, false))
  ------------------
  |  Branch (490:9): [True: 328, False: 80.3k]
  ------------------
  491|    328|        return VD_NEW_FRAME;
  492|       |
  493|       |    // Get a new frame if we need one.
  494|  80.3k|    int r = VD_PROGRESS;
  495|  80.3k|    if (needs_new_frame(mpctx)) {
  ------------------
  |  Branch (495:9): [True: 80.3k, False: 0]
  ------------------
  496|       |        // Filter a new frame.
  497|  80.3k|        struct mp_image *img = NULL;
  498|  80.3k|        struct mp_frame frame = mp_pin_out_read(vo_c->filter->f->pins[1]);
  499|  80.3k|        if (frame.type == MP_FRAME_NONE) {
  ------------------
  |  Branch (499:13): [True: 6.36k, False: 74.0k]
  ------------------
  500|  6.36k|            r = vo_c->filter->got_output_eof ? VD_EOF : VD_WAIT;
  ------------------
  |  Branch (500:17): [True: 1.51k, False: 4.84k]
  ------------------
  501|  74.0k|        } else if (frame.type == MP_FRAME_EOF) {
  ------------------
  |  Branch (501:20): [True: 2.02k, False: 71.9k]
  ------------------
  502|  2.02k|            r = VD_EOF;
  503|  71.9k|        } else if (frame.type == MP_FRAME_VIDEO) {
  ------------------
  |  Branch (503:20): [True: 71.9k, False: 0]
  ------------------
  504|  71.9k|            img = frame.data;
  505|  71.9k|        } else {
  506|      0|            MP_ERR(mpctx, "unexpected frame type %s\n",
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  507|      0|                   mp_frame_type_str(frame.type));
  508|      0|            mp_frame_unref(&frame);
  509|      0|            return VD_ERROR;
  510|      0|        }
  511|  80.3k|        if (img) {
  ------------------
  |  Branch (511:13): [True: 71.9k, False: 8.39k]
  ------------------
  512|  71.9k|            double endpts = get_play_end_pts(mpctx);
  513|  71.9k|            if (endpts != MP_NOPTS_VALUE)
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (513:17): [True: 0, False: 71.9k]
  ------------------
  514|      0|                endpts *= mpctx->play_dir;
  515|  71.9k|            if ((endpts != MP_NOPTS_VALUE && img->pts >= endpts) ||
  ------------------
  |  |   38|   143k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (515:18): [True: 0, False: 71.9k]
  |  Branch (515:46): [True: 0, False: 0]
  ------------------
  516|  71.9k|                mpctx->max_frames == 0)
  ------------------
  |  Branch (516:17): [True: 0, False: 71.9k]
  ------------------
  517|      0|            {
  518|      0|                mp_pin_out_unread(vo_c->filter->f->pins[1], frame);
  519|      0|                img = NULL;
  520|      0|                r = VD_EOF;
  521|  71.9k|            } else if (hrseek && (img->pts < hrseek_pts - tolerance ||
  ------------------
  |  Branch (521:24): [True: 0, False: 71.9k]
  |  Branch (521:35): [True: 0, False: 0]
  ------------------
  522|      0|                                  mpctx->hrseek_lastframe))
  ------------------
  |  Branch (522:35): [True: 0, False: 0]
  ------------------
  523|      0|            {
  524|       |                /* just skip - but save in case it was the last frame */
  525|      0|                mp_image_setrefp(&mpctx->saved_frame, img);
  526|  71.9k|            } else {
  527|  71.9k|                if (hrseek && mpctx->hrseek_backstep) {
  ------------------
  |  Branch (527:21): [True: 0, False: 71.9k]
  |  Branch (527:31): [True: 0, False: 0]
  ------------------
  528|      0|                    if (mpctx->saved_frame) {
  ------------------
  |  Branch (528:25): [True: 0, False: 0]
  ------------------
  529|      0|                        add_new_frame(mpctx, mpctx->saved_frame);
  530|      0|                        mpctx->saved_frame = NULL;
  531|      0|                    } else {
  532|      0|                        MP_WARN(mpctx, "Backstep failed.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  533|      0|                    }
  534|      0|                    mpctx->hrseek_backstep = false;
  535|      0|                }
  536|  71.9k|                mp_image_unrefp(&mpctx->saved_frame);
  537|  71.9k|                add_new_frame(mpctx, img);
  538|  71.9k|                img = NULL;
  539|  71.9k|            }
  540|  71.9k|            talloc_free(img);
  ------------------
  |  |   47|  71.9k|#define talloc_free                     ta_free
  ------------------
  541|  71.9k|        }
  542|  80.3k|    }
  543|       |
  544|  80.3k|    if (!hrseek)
  ------------------
  |  Branch (544:9): [True: 80.3k, False: 0]
  ------------------
  545|  80.3k|        mp_image_unrefp(&mpctx->saved_frame);
  546|       |
  547|  80.3k|    if (r == VD_EOF) {
  ------------------
  |  Branch (547:9): [True: 3.54k, False: 76.8k]
  ------------------
  548|       |        // If hr-seek went past EOF, use the last frame.
  549|  3.54k|        if (mpctx->saved_frame)
  ------------------
  |  Branch (549:13): [True: 0, False: 3.54k]
  ------------------
  550|      0|            add_new_frame(mpctx, mpctx->saved_frame);
  551|  3.54k|        mpctx->saved_frame = NULL;
  552|  3.54k|        *logical_eof = true;
  553|  3.54k|    }
  554|       |
  555|  80.3k|    return have_new_frame(mpctx, r <= 0) ? VD_NEW_FRAME : r;
  ------------------
  |  Branch (555:12): [True: 71.9k, False: 8.39k]
  ------------------
  556|  80.3k|}
video.c:have_new_frame:
  459|   161k|{
  460|   161k|    return mpctx->num_next_frames >= get_req_frames(mpctx, eof);
  461|   161k|}
video.c:get_req_frames:
  418|   241k|{
  419|       |    // On EOF, drain all frames.
  420|   241k|    if (eof)
  ------------------
  |  Branch (420:9): [True: 3.54k, False: 237k]
  ------------------
  421|  3.54k|        return 1;
  422|       |
  423|   237k|    if (!use_video_lookahead(mpctx))
  ------------------
  |  Branch (423:9): [True: 237k, False: 0]
  ------------------
  424|   237k|        return 1;
  425|       |
  426|      0|    if (mpctx->vo_chain && mpctx->vo_chain->is_sparse)
  ------------------
  |  Branch (426:9): [True: 0, False: 0]
  |  Branch (426:28): [True: 0, False: 0]
  ------------------
  427|      0|        return 1;
  428|       |
  429|       |    // Normally require at least 2 frames, so we can compute a frame duration.
  430|      0|    int min = 2;
  431|       |
  432|       |    // On the first frame, output a new frame as quickly as possible.
  433|      0|    if (mpctx->video_pts == MP_NOPTS_VALUE)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (433:9): [True: 0, False: 0]
  ------------------
  434|      0|        return min;
  435|       |
  436|      0|    int req = vo_get_num_req_frames(mpctx->video_out);
  437|      0|    return MPCLAMP(req, min, MP_ARRAY_SIZE(mpctx->next_frames) - 1);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  438|      0|}
video.c:needs_new_frame:
  442|  80.3k|{
  443|  80.3k|    return mpctx->num_next_frames < get_req_frames(mpctx, false);
  444|  80.3k|}
video.c:add_new_frame:
  448|  71.9k|{
  449|  71.9k|    mp_assert(mpctx->num_next_frames < MP_ARRAY_SIZE(mpctx->next_frames));
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  450|  71.9k|    mp_assert(frame);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  451|  71.9k|    mpctx->next_frames[mpctx->num_next_frames++] = frame;
  452|  71.9k|    if (mpctx->num_next_frames == 1)
  ------------------
  |  Branch (452:9): [True: 71.9k, False: 0]
  ------------------
  453|  71.9k|        handle_new_frame(mpctx);
  454|  71.9k|}
video.c:check_for_hwdec_fallback:
  559|  3.54k|{
  560|  3.54k|    struct vo_chain *vo_c = mpctx->vo_chain;
  561|       |
  562|  3.54k|    if (!vo_c->filter->failed_output_conversion || !vo_c->track || !vo_c->track->dec)
  ------------------
  |  Branch (562:9): [True: 3.54k, False: 0]
  |  Branch (562:52): [True: 0, False: 0]
  |  Branch (562:68): [True: 0, False: 0]
  ------------------
  563|  3.54k|        return false;
  564|       |
  565|      0|    if (mp_decoder_wrapper_control(vo_c->track->dec,
  ------------------
  |  Branch (565:9): [True: 0, False: 0]
  ------------------
  566|      0|                            VDCTRL_FORCE_HWDEC_FALLBACK, NULL) != CONTROL_OK)
  ------------------
  |  |   68|      0|#define CONTROL_OK 1
  ------------------
  567|      0|        return false;
  568|       |
  569|      0|    mp_output_chain_reset_harder(vo_c->filter);
  570|      0|    return true;
  571|      0|}
video.c:check_for_forced_eof:
  574|  3.54k|{
  575|  3.54k|    struct vo_chain *vo_c = mpctx->vo_chain;
  576|       |
  577|  3.54k|    if (!vo_c->track || !vo_c->track->dec)
  ------------------
  |  Branch (577:9): [True: 0, False: 3.54k]
  |  Branch (577:25): [True: 0, False: 3.54k]
  ------------------
  578|      0|        return false;
  579|       |
  580|  3.54k|    struct mp_decoder_wrapper *dec = vo_c->track->dec;
  581|  3.54k|    bool forced_eof = false;
  582|       |
  583|  3.54k|    mp_decoder_wrapper_control(dec, VDCTRL_CHECK_FORCED_EOF, &forced_eof);
  584|  3.54k|    return forced_eof;
  585|  3.54k|}
video.c:use_video_lookahead:
  410|   237k|{
  411|   237k|    return mpctx->video_out &&
  ------------------
  |  Branch (411:12): [True: 237k, False: 0]
  ------------------
  412|   237k|           !(mpctx->video_out->driver->caps & VO_CAP_NORETAIN) &&
  ------------------
  |  Branch (412:12): [True: 237k, False: 0]
  ------------------
  413|   237k|           !(mpctx->opts->untimed || (mpctx->video_out->driver->caps & VO_CAP_UNTIMED)) &&
  ------------------
  |  Branch (413:14): [True: 237k, False: 0]
  |  Branch (413:38): [True: 0, False: 0]
  ------------------
  414|   237k|           !mpctx->opts->video_latency_hacks;
  ------------------
  |  Branch (414:12): [True: 0, False: 0]
  ------------------
  415|   237k|}
video.c:apply_video_crop:
 1023|  72.3k|{
 1024|   144k|    for (int n = 0; n < mpctx->num_next_frames; n++) {
  ------------------
  |  Branch (1024:21): [True: 72.3k, False: 72.3k]
  ------------------
 1025|  72.3k|        struct m_geometry *gm = &vo->opts->video_crop;
 1026|  72.3k|        struct mp_image_params p = mpctx->next_frames[n]->params;
 1027|  72.3k|        if (gm->xy_valid || (gm->wh_valid && (gm->w > 0 || gm->h > 0)))
  ------------------
  |  Branch (1027:13): [True: 0, False: 72.3k]
  |  Branch (1027:30): [True: 0, False: 72.3k]
  |  Branch (1027:47): [True: 0, False: 0]
  |  Branch (1027:60): [True: 0, False: 0]
  ------------------
 1028|      0|        {
 1029|      0|            m_rect_apply(&p.crop, p.w, p.h, gm);
 1030|      0|        }
 1031|       |
 1032|  72.3k|        if (p.crop.x1 == 0 && p.crop.y1 == 0)
  ------------------
  |  Branch (1032:13): [True: 0, False: 72.3k]
  |  Branch (1032:31): [True: 0, False: 0]
  ------------------
 1033|      0|            return;
 1034|       |
 1035|  72.3k|        if (!mp_image_crop_valid(&p)) {
  ------------------
  |  Branch (1035:13): [True: 0, False: 72.3k]
  ------------------
 1036|      0|            char *str = m_option_type_rect.print(NULL, gm);
 1037|      0|            MP_WARN(vo, "Ignoring invalid --video-crop=%s for %dx%d image\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1038|      0|                    str, p.w, p.h);
 1039|      0|            talloc_free(str);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1040|      0|            *gm = (struct m_geometry){0};
 1041|      0|            mp_property_do("video-crop", M_PROPERTY_SET, gm, mpctx);
 1042|      0|            return;
 1043|      0|        }
 1044|  72.3k|        mpctx->next_frames[n]->params.crop = p.crop;
 1045|  72.3k|    }
 1046|  72.3k|}
video.c:update_avsync_before_frame:
  591|  72.3k|{
  592|  72.3k|    struct MPOpts *opts = mpctx->opts;
  593|  72.3k|    struct vo *vo = mpctx->video_out;
  594|       |
  595|  72.3k|    if (mpctx->video_status < STATUS_READY) {
  ------------------
  |  Branch (595:9): [True: 561, False: 71.7k]
  ------------------
  596|    561|        mpctx->time_frame = 0;
  597|  71.7k|    } else if (mpctx->display_sync_active || vo->opts->video_sync == VS_NONE) {
  ------------------
  |  Branch (597:16): [True: 0, False: 71.7k]
  |  Branch (597:46): [True: 0, False: 71.7k]
  ------------------
  598|       |        // don't touch the timing
  599|  71.7k|    } else if (mpctx->audio_status == STATUS_PLAYING &&
  ------------------
  |  Branch (599:16): [True: 0, False: 71.7k]
  ------------------
  600|  71.7k|               mpctx->video_status == STATUS_PLAYING &&
  ------------------
  |  Branch (600:16): [True: 0, False: 0]
  ------------------
  601|  71.7k|               !ao_untimed(mpctx->ao))
  ------------------
  |  Branch (601:16): [True: 0, False: 0]
  ------------------
  602|      0|    {
  603|      0|        double buffered_audio = ao_get_delay(mpctx->ao);
  604|       |
  605|      0|        double predicted = mpctx->delay / mpctx->video_speed +
  606|      0|                           mpctx->time_frame;
  607|      0|        double difference = buffered_audio - predicted;
  608|      0|        MP_STATS(mpctx, "value %f audio-diff", difference);
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  609|       |
  610|      0|        if (opts->autosync) {
  ------------------
  |  Branch (610:13): [True: 0, False: 0]
  ------------------
  611|       |            /* Smooth reported playback position from AO by averaging
  612|       |             * it with the value expected based on previous value and
  613|       |             * time elapsed since then. May help smooth video timing
  614|       |             * with audio output that have inaccurate position reporting.
  615|       |             * This is badly implemented; the behavior of the smoothing
  616|       |             * now undesirably depends on how often this code runs
  617|       |             * (mainly depends on video frame rate). */
  618|      0|            buffered_audio = predicted + difference / opts->autosync;
  619|      0|        }
  620|       |
  621|      0|        mpctx->time_frame = buffered_audio - mpctx->delay / mpctx->video_speed;
  622|  71.7k|    } else {
  623|       |        /* If we're more than 200 ms behind the right playback
  624|       |         * position, don't try to speed up display of following
  625|       |         * frames to catch up; continue with default speed from
  626|       |         * the current frame instead.
  627|       |         * If untimed is set always output frames immediately
  628|       |         * without sleeping.
  629|       |         */
  630|  71.7k|        if (mpctx->time_frame < -0.2 || opts->untimed ||
  ------------------
  |  Branch (630:13): [True: 0, False: 71.7k]
  |  Branch (630:41): [True: 71.7k, False: 0]
  ------------------
  631|  71.7k|            (vo->driver->caps & VO_CAP_UNTIMED))
  ------------------
  |  Branch (631:13): [True: 0, False: 0]
  ------------------
  632|  71.7k|            mpctx->time_frame = 0;
  633|  71.7k|    }
  634|  72.3k|}
video.c:calculate_frame_duration:
  969|  71.9k|{
  970|  71.9k|    struct vo_chain *vo_c = mpctx->vo_chain;
  971|  71.9k|    mp_assert(mpctx->num_past_frames >= 1 && mpctx->num_next_frames >= 1);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  972|       |
  973|  71.9k|    double demux_duration = vo_c->filter->container_fps > 0
  ------------------
  |  Branch (973:29): [True: 71.9k, False: 7]
  ------------------
  974|  71.9k|                            ? 1.0 / vo_c->filter->container_fps : -1;
  975|  71.9k|    double duration = demux_duration;
  976|       |
  977|  71.9k|    if (mpctx->num_next_frames >= 2) {
  ------------------
  |  Branch (977:9): [True: 0, False: 71.9k]
  ------------------
  978|      0|        double pts0 = mpctx->next_frames[0]->pts;
  979|      0|        double pts1 = mpctx->next_frames[1]->pts;
  980|      0|        if (pts0 != MP_NOPTS_VALUE && pts1 != MP_NOPTS_VALUE && pts1 >= pts0)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                      if (pts0 != MP_NOPTS_VALUE && pts1 != MP_NOPTS_VALUE && pts1 >= pts0)
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (980:13): [True: 0, False: 0]
  |  Branch (980:39): [True: 0, False: 0]
  |  Branch (980:65): [True: 0, False: 0]
  ------------------
  981|      0|            duration = pts1 - pts0;
  982|      0|    }
  983|       |
  984|       |    // The following code tries to compensate for rounded Matroska timestamps
  985|       |    // by "unrounding" frame durations, or if not possible, approximating them.
  986|       |    // These formats usually round on 1ms. Some muxers do this incorrectly,
  987|       |    // and might go off by 1ms more, and compensate for it later by an equal
  988|       |    // rounding error into the opposite direction.
  989|  71.9k|    double tolerance = 0.001 * 3 + 0.0001;
  990|       |
  991|  71.9k|    double total = 0;
  992|  71.9k|    int num_dur = 0;
  993|  5.49M|    for (int n = 1; n < mpctx->num_past_frames; n++) {
  ------------------
  |  Branch (993:21): [True: 5.41M, False: 71.9k]
  ------------------
  994|       |        // Eliminate likely outliers using a really dumb heuristic.
  995|  5.41M|        double dur = mpctx->past_frames[n].duration;
  996|  5.41M|        if (dur <= 0 || fabs(dur - duration) >= tolerance)
  ------------------
  |  Branch (996:13): [True: 0, False: 5.41M]
  |  Branch (996:25): [True: 0, False: 5.41M]
  ------------------
  997|      0|            break;
  998|  5.41M|        total += dur;
  999|  5.41M|        num_dur += 1;
 1000|  5.41M|    }
 1001|  71.9k|    double approx_duration = num_dur > 0 ? total / num_dur : duration;
  ------------------
  |  Branch (1001:30): [True: 71.4k, False: 561]
  ------------------
 1002|       |
 1003|       |    // Try if the demuxer frame rate fits - if so, just take it.
 1004|  71.9k|    if (demux_duration > 0) {
  ------------------
  |  Branch (1004:9): [True: 71.9k, False: 7]
  ------------------
 1005|       |        // Note that even if each timestamp is within rounding tolerance, it
 1006|       |        // could literally not add up (e.g. if demuxer FPS is rounded itself).
 1007|  71.9k|        if (fabs(duration - demux_duration) < tolerance &&
  ------------------
  |  Branch (1007:13): [True: 71.9k, False: 0]
  ------------------
 1008|  71.9k|            fabs(total - demux_duration * num_dur) < tolerance &&
  ------------------
  |  Branch (1008:13): [True: 71.9k, False: 0]
  ------------------
 1009|  71.9k|            (num_dur >= 16 || num_dur >= mpctx->num_past_frames - 4))
  ------------------
  |  Branch (1009:14): [True: 65.2k, False: 6.73k]
  |  Branch (1009:31): [True: 6.73k, False: 0]
  ------------------
 1010|  71.9k|        {
 1011|  71.9k|            approx_duration = demux_duration;
 1012|  71.9k|        }
 1013|  71.9k|    }
 1014|       |
 1015|  71.9k|    mpctx->past_frames[0].duration = duration;
 1016|  71.9k|    mpctx->past_frames[0].approx_duration = approx_duration;
 1017|       |
 1018|  71.9k|    MP_STATS(mpctx, "value %f frame-duration", MPMAX(0, duration));
  ------------------
  |  |   95|  71.9k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   143k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 7, False: 71.9k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1019|  71.9k|    MP_STATS(mpctx, "value %f frame-duration-approx", MPMAX(0, approx_duration));
  ------------------
  |  |   95|  71.9k|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   143k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 7, False: 71.9k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1020|  71.9k|}
video.c:shift_frames:
  400|  71.9k|{
  401|  71.9k|    if (mpctx->num_next_frames < 1)
  ------------------
  |  Branch (401:9): [True: 0, False: 71.9k]
  ------------------
  402|      0|        return;
  403|  71.9k|    talloc_free(mpctx->next_frames[0]);
  ------------------
  |  |   47|  71.9k|#define talloc_free                     ta_free
  ------------------
  404|  71.9k|    for (int n = 0; n < mpctx->num_next_frames - 1; n++)
  ------------------
  |  Branch (404:21): [True: 0, False: 71.9k]
  ------------------
  405|      0|        mpctx->next_frames[n] = mpctx->next_frames[n + 1];
  406|  71.9k|    mpctx->num_next_frames -= 1;
  407|  71.9k|}
video.c:schedule_frame:
  947|  71.9k|{
  948|  71.9k|    handle_display_sync_frame(mpctx, frame);
  949|       |
  950|  71.9k|    if (mpctx->num_past_frames > 1 &&
  ------------------
  |  Branch (950:9): [True: 71.4k, False: 561]
  ------------------
  951|  71.9k|        ((mpctx->past_frames[1].num_vsyncs >= 0) != mpctx->display_sync_active))
  ------------------
  |  Branch (951:9): [True: 0, False: 71.4k]
  ------------------
  952|      0|    {
  953|      0|        MP_VERBOSE(mpctx, "Video sync mode %s.\n",
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  954|      0|                   mpctx->display_sync_active ? "enabled" : "disabled");
  955|      0|    }
  956|       |
  957|  71.9k|    if (!mpctx->display_sync_active) {
  ------------------
  |  Branch (957:9): [True: 71.9k, False: 0]
  ------------------
  958|  71.9k|        mpctx->speed_factor_a = 1.0;
  959|  71.9k|        mpctx->speed_factor_v = 1.0;
  960|  71.9k|        update_playback_speed(mpctx);
  961|       |
  962|  71.9k|        update_av_diff(mpctx, mpctx->time_frame > 0 ?
  ------------------
  |  Branch (962:31): [True: 0, False: 71.9k]
  ------------------
  963|  71.9k|            mpctx->time_frame * mpctx->video_speed : 0);
  964|  71.9k|    }
  965|  71.9k|}
video.c:handle_display_sync_frame:
  812|  71.9k|{
  813|  71.9k|    struct MPOpts *opts = mpctx->opts;
  814|  71.9k|    struct vo *vo = mpctx->video_out;
  815|  71.9k|    int mode = vo->opts->video_sync;
  816|       |
  817|  71.9k|    if (!mpctx->display_sync_active) {
  ------------------
  |  Branch (817:9): [True: 71.9k, False: 0]
  ------------------
  818|  71.9k|        mpctx->display_sync_error = 0.0;
  819|  71.9k|        mpctx->display_sync_drift_dir = 0;
  820|  71.9k|    }
  821|       |
  822|  71.9k|    mpctx->display_sync_active = false;
  823|       |
  824|  71.9k|    if (!VS_IS_DISP(mode) || !vo_is_visible(vo))
  ------------------
  |  |  102|   143k|#define VS_IS_DISP(x) ((x) == VS_DISP_RESAMPLE ||       \
  |  |  ------------------
  |  |  |  Branch (102:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  103|  71.9k|                       (x) == VS_DISP_RESAMPLE_VDROP || \
  |  |  ------------------
  |  |  |  Branch (103:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  104|  71.9k|                       (x) == VS_DISP_RESAMPLE_NONE ||  \
  |  |  ------------------
  |  |  |  Branch (104:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  105|  71.9k|                       (x) == VS_DISP_TEMPO ||          \
  |  |  ------------------
  |  |  |  Branch (105:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  106|  71.9k|                       (x) == VS_DISP_ADROP ||          \
  |  |  ------------------
  |  |  |  Branch (106:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  107|  71.9k|                       (x) == VS_DISP_VDROP ||          \
  |  |  ------------------
  |  |  |  Branch (107:24): [True: 0, False: 71.9k]
  |  |  ------------------
  |  |  108|   143k|                       (x) == VS_DISP_NONE)
  |  |  ------------------
  |  |  |  Branch (108:24): [True: 0, False: 71.9k]
  |  |  ------------------
  ------------------
  |  Branch (824:30): [True: 0, False: 0]
  ------------------
  825|  71.9k|        return;
  826|       |
  827|      0|    bool resample = mode == VS_DISP_RESAMPLE || mode == VS_DISP_RESAMPLE_VDROP ||
  ------------------
  |  Branch (827:21): [True: 0, False: 0]
  |  Branch (827:49): [True: 0, False: 0]
  ------------------
  828|      0|                    mode == VS_DISP_RESAMPLE_NONE;
  ------------------
  |  Branch (828:21): [True: 0, False: 0]
  ------------------
  829|      0|    bool drop = mode == VS_DISP_VDROP || mode == VS_DISP_RESAMPLE ||
  ------------------
  |  Branch (829:17): [True: 0, False: 0]
  |  Branch (829:42): [True: 0, False: 0]
  ------------------
  830|      0|                mode == VS_DISP_ADROP || mode == VS_DISP_RESAMPLE_VDROP ||
  ------------------
  |  Branch (830:17): [True: 0, False: 0]
  |  Branch (830:42): [True: 0, False: 0]
  ------------------
  831|      0|                mode == VS_DISP_TEMPO;
  ------------------
  |  Branch (831:17): [True: 0, False: 0]
  ------------------
  832|      0|    drop &= frame->can_drop;
  833|       |
  834|      0|    if (resample && using_spdif_passthrough(mpctx))
  ------------------
  |  Branch (834:9): [True: 0, False: 0]
  |  Branch (834:21): [True: 0, False: 0]
  ------------------
  835|      0|        return;
  836|       |
  837|      0|    double vsync = vo_get_vsync_interval(vo) / 1e9;
  838|      0|    if (vsync <= 0)
  ------------------
  |  Branch (838:9): [True: 0, False: 0]
  ------------------
  839|      0|        return;
  840|       |
  841|      0|    double approx_duration = MPMAX(0, mpctx->past_frames[0].approx_duration);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  842|      0|    double adjusted_duration = approx_duration / opts->playback_speed;
  843|      0|    if (adjusted_duration > 0.5)
  ------------------
  |  Branch (843:9): [True: 0, False: 0]
  ------------------
  844|      0|        return;
  845|       |
  846|      0|    mpctx->speed_factor_v = 1.0;
  847|      0|    if (mode != VS_DISP_VDROP)
  ------------------
  |  Branch (847:9): [True: 0, False: 0]
  ------------------
  848|      0|        mpctx->speed_factor_v = find_best_speed(mpctx, vsync);
  849|       |
  850|       |    // Determine for how many vsyncs a frame should be displayed. This can be
  851|       |    // e.g. 2 for 30hz on a 60hz display. It can also be 0 if the video
  852|       |    // framerate is higher than the display framerate.
  853|       |    // We use the speed-adjusted (i.e. real) frame duration for this.
  854|      0|    double frame_duration = adjusted_duration / mpctx->speed_factor_v;
  855|      0|    double ratio = (frame_duration + mpctx->display_sync_error) / vsync;
  856|      0|    int num_vsyncs = MPMAX(lrint(ratio), 0);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  857|      0|    double prev_error = mpctx->display_sync_error;
  858|      0|    mpctx->display_sync_error += frame_duration - num_vsyncs * vsync;
  859|       |
  860|      0|    MP_TRACE(mpctx, "s=%f vsyncs=%d dur=%f ratio=%f err=%.20f (%f/%f)\n",
  ------------------
  |  |   90|      0|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  861|      0|            mpctx->speed_factor_v, num_vsyncs, adjusted_duration, ratio,
  862|      0|            mpctx->display_sync_error, mpctx->display_sync_error / vsync,
  863|      0|            mpctx->display_sync_error / frame_duration);
  864|       |
  865|      0|    double av_diff = mpctx->last_av_difference;
  866|      0|    MP_STATS(mpctx, "value %f avdiff", av_diff);
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  867|       |
  868|       |    // Intended number of additional display frames to drop (<0) or repeat (>0)
  869|      0|    int drop_repeat = 0;
  870|       |
  871|       |    // If we are too far ahead/behind, attempt to drop/repeat frames.
  872|       |    // Tolerate some desync to avoid frame dropping due to jitter.
  873|      0|    if (drop && fabs(av_diff) >= 0.020 && fabs(av_diff) / vsync >= 1)
  ------------------
  |  Branch (873:9): [True: 0, False: 0]
  |  Branch (873:17): [True: 0, False: 0]
  |  Branch (873:43): [True: 0, False: 0]
  ------------------
  874|      0|        drop_repeat = -av_diff / vsync; // round towards 0
  875|       |
  876|       |    // We can only drop all frames at most. We can repeat much more frames,
  877|       |    // but we still limit it to 10 times the original frames to avoid that
  878|       |    // corner cases or exceptional situations cause too much havoc.
  879|      0|    drop_repeat = MPCLAMP(drop_repeat, -num_vsyncs, num_vsyncs * 10);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  880|      0|    num_vsyncs += drop_repeat;
  881|       |
  882|       |    // Always show the first frame.
  883|      0|    if (mpctx->num_past_frames <= 1 && num_vsyncs < 1)
  ------------------
  |  Branch (883:9): [True: 0, False: 0]
  |  Branch (883:40): [True: 0, False: 0]
  ------------------
  884|      0|        num_vsyncs = 1;
  885|       |
  886|       |    // Estimate the video position, so we can calculate a good A/V difference
  887|       |    // value below. This is used to estimate A/V drift.
  888|      0|    double time_left = vo_get_delay(vo);
  889|       |
  890|       |    // We also know that the timing is (necessarily) off, because we have to
  891|       |    // align frame timings on the vsync boundaries. This is unavoidable, and
  892|       |    // for the sake of the A/V sync calculations we pretend it's perfect.
  893|      0|    time_left += prev_error;
  894|       |    // Likewise, we know sync is off, but is going to be compensated.
  895|      0|    time_left += drop_repeat * vsync;
  896|       |
  897|       |    // If syncing took too long, disregard timing of the first frame.
  898|      0|    if (mpctx->num_past_frames == 2 && time_left < 0) {
  ------------------
  |  Branch (898:9): [True: 0, False: 0]
  |  Branch (898:40): [True: 0, False: 0]
  ------------------
  899|      0|        vo_discard_timing_info(vo);
  900|      0|        time_left = 0;
  901|      0|    }
  902|       |
  903|      0|    if (drop_repeat) {
  ------------------
  |  Branch (903:9): [True: 0, False: 0]
  ------------------
  904|      0|        mpctx->mistimed_frames_total += 1;
  905|      0|        MP_STATS(mpctx, "mistimed");
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  906|      0|    }
  907|       |
  908|      0|    mpctx->total_avsync_change = 0;
  909|      0|    update_av_diff(mpctx, time_left * opts->playback_speed);
  910|       |
  911|      0|    mpctx->past_frames[0].num_vsyncs = num_vsyncs;
  912|      0|    mpctx->past_frames[0].av_diff = mpctx->last_av_difference;
  913|       |
  914|      0|    if (resample || mode == VS_DISP_ADROP || mode == VS_DISP_TEMPO) {
  ------------------
  |  Branch (914:9): [True: 0, False: 0]
  |  Branch (914:21): [True: 0, False: 0]
  |  Branch (914:46): [True: 0, False: 0]
  ------------------
  915|      0|        adjust_audio_drift_compensation(mpctx, vsync);
  916|      0|    } else {
  917|      0|        mpctx->speed_factor_a = 1.0;
  918|      0|    }
  919|       |
  920|       |    // A bad guess, only needed when reverting to audio sync.
  921|      0|    mpctx->time_frame = time_left;
  922|       |
  923|      0|    frame->vsync_interval = vsync;
  924|      0|    frame->vsync_offset = -prev_error;
  925|      0|    frame->ideal_frame_duration = frame_duration;
  926|      0|    frame->ideal_frame_vsync = (-prev_error / frame_duration) * approx_duration;
  927|      0|    frame->ideal_frame_vsync_duration = (vsync / frame_duration) * approx_duration;
  928|      0|    frame->num_vsyncs = num_vsyncs;
  929|      0|    frame->display_synced = true;
  930|      0|    frame->approx_duration = approx_duration;
  931|       |
  932|       |    // Adjust frame virtual vsyncs by the repeat count
  933|      0|    if (drop_repeat > 0)
  ------------------
  |  Branch (933:9): [True: 0, False: 0]
  ------------------
  934|      0|        frame->ideal_frame_vsync_duration /= drop_repeat;
  935|       |
  936|      0|    mpctx->display_sync_active = true;
  937|       |    // Try to avoid audio underruns that may occur if we update
  938|       |    // the playback speed while in the STATUS_SYNCING state.
  939|      0|    if (mpctx->video_status != STATUS_SYNCING)
  ------------------
  |  Branch (939:9): [True: 0, False: 0]
  ------------------
  940|      0|        update_playback_speed(mpctx);
  941|       |
  942|      0|    MP_STATS(mpctx, "value %f aspeed", mpctx->speed_factor_a - 1);
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  943|      0|    MP_STATS(mpctx, "value %f vspeed", mpctx->speed_factor_v - 1);
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  944|      0|}
video.c:update_av_diff:
  638|  71.9k|{
  639|  71.9k|    struct MPOpts *opts = mpctx->opts;
  640|       |
  641|  71.9k|    mpctx->last_av_difference = 0;
  642|       |
  643|  71.9k|    if (mpctx->audio_status != STATUS_PLAYING ||
  ------------------
  |  Branch (643:9): [True: 71.9k, False: 0]
  ------------------
  644|  71.9k|        mpctx->video_status != STATUS_PLAYING)
  ------------------
  |  Branch (644:9): [True: 0, False: 0]
  ------------------
  645|  71.9k|        return;
  646|       |
  647|      0|    if (mpctx->vo_chain && mpctx->vo_chain->is_sparse)
  ------------------
  |  Branch (647:9): [True: 0, False: 0]
  |  Branch (647:28): [True: 0, False: 0]
  ------------------
  648|      0|        return;
  649|       |
  650|      0|    double a_pos = playing_audio_pts(mpctx);
  651|      0|    if (a_pos != MP_NOPTS_VALUE && mpctx->video_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
                  if (a_pos != MP_NOPTS_VALUE && mpctx->video_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|      0|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (651:9): [True: 0, False: 0]
  |  Branch (651:36): [True: 0, False: 0]
  ------------------
  652|      0|        mpctx->last_av_difference = a_pos - mpctx->video_pts
  653|      0|                                  + opts->audio_delay + offset;
  654|      0|    }
  655|       |
  656|      0|    if (fabs(mpctx->last_av_difference) > 0.5 && !mpctx->drop_message_shown) {
  ------------------
  |  Branch (656:9): [True: 0, False: 0]
  |  Branch (656:50): [True: 0, False: 0]
  ------------------
  657|      0|        MP_WARN(mpctx, "%s", av_desync_help_text);
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  658|      0|        mpctx->drop_message_shown = true;
  659|      0|    }
  660|      0|}
video.c:check_framedrop:
  316|  71.9k|{
  317|  71.9k|    struct MPOpts *opts = mpctx->opts;
  318|       |    // check for frame-drop:
  319|  71.9k|    if (mpctx->video_status == STATUS_PLAYING && !mpctx->paused &&
  ------------------
  |  Branch (319:9): [True: 71.4k, False: 561]
  |  Branch (319:50): [True: 71.4k, False: 0]
  ------------------
  320|  71.9k|        mpctx->audio_status == STATUS_PLAYING && !ao_untimed(mpctx->ao) &&
  ------------------
  |  Branch (320:9): [True: 0, False: 71.4k]
  |  Branch (320:50): [True: 0, False: 0]
  ------------------
  321|  71.9k|        vo_c->track && vo_c->track->dec && (opts->frame_dropping & 2))
  ------------------
  |  Branch (321:9): [True: 0, False: 0]
  |  Branch (321:24): [True: 0, False: 0]
  |  Branch (321:44): [True: 0, False: 0]
  ------------------
  322|      0|    {
  323|      0|        float fps = vo_c->filter->container_fps;
  324|       |        // it's a crappy heuristic; avoid getting upset by incorrect fps
  325|      0|        if (fps <= 20 || fps >= 500)
  ------------------
  |  Branch (325:13): [True: 0, False: 0]
  |  Branch (325:26): [True: 0, False: 0]
  ------------------
  326|      0|            return;
  327|      0|        double frame_time =  1.0 / fps;
  328|       |        // try to drop as many frames as we appear to be behind
  329|      0|        mp_decoder_wrapper_set_frame_drops(vo_c->track->dec,
  330|      0|            MPCLAMP((mpctx->last_av_difference - 0.010) / frame_time, 0, 100));
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  331|      0|    }
  332|  71.9k|}
video.c:handle_new_frame:
  372|  71.9k|{
  373|  71.9k|    mp_assert(mpctx->num_next_frames >= 1);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  374|       |
  375|  71.9k|    double frame_time = 0;
  376|  71.9k|    double pts = mpctx->next_frames[0]->pts;
  377|  71.9k|    bool is_sparse = mpctx->vo_chain && mpctx->vo_chain->is_sparse;
  ------------------
  |  Branch (377:22): [True: 71.9k, False: 0]
  |  Branch (377:41): [True: 0, False: 71.9k]
  ------------------
  378|       |
  379|  71.9k|    if (mpctx->video_pts != MP_NOPTS_VALUE) {
  ------------------
  |  |   38|  71.9k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  |  Branch (379:9): [True: 71.4k, False: 561]
  ------------------
  380|  71.4k|        frame_time = pts - mpctx->video_pts;
  381|  71.4k|        double tolerance = mpctx->demuxer->ts_resets_possible &&
  ------------------
  |  Branch (381:28): [True: 0, False: 71.4k]
  ------------------
  382|  71.4k|                           !is_sparse ? 5 : 1e4;
  ------------------
  |  Branch (382:28): [True: 0, False: 0]
  ------------------
  383|  71.4k|        if (frame_time <= 0 || frame_time >= tolerance) {
  ------------------
  |  Branch (383:13): [True: 0, False: 71.4k]
  |  Branch (383:32): [True: 0, False: 71.4k]
  ------------------
  384|       |            // Assume a discontinuity.
  385|      0|            MP_WARN(mpctx, "Invalid video timestamp: %f -> %f\n",
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  386|      0|                    mpctx->video_pts, pts);
  387|      0|            frame_time = 0;
  388|      0|        }
  389|  71.4k|    }
  390|  71.9k|    mpctx->time_frame += frame_time / mpctx->video_speed;
  391|  71.9k|    if (mpctx->ao_chain && !mpctx->ao_chain->delaying_audio_start)
  ------------------
  |  Branch (391:9): [True: 7, False: 71.9k]
  |  Branch (391:28): [True: 7, False: 0]
  ------------------
  392|      7|        mpctx->delay -= frame_time;
  393|  71.9k|    if (mpctx->video_status >= STATUS_PLAYING)
  ------------------
  |  Branch (393:9): [True: 71.4k, False: 561]
  ------------------
  394|  71.4k|        adjust_sync(mpctx, pts, frame_time);
  395|  71.9k|    MP_TRACE(mpctx, "frametime=%5.3f\n", frame_time);
  ------------------
  |  |   90|  71.9k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  71.9k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  396|  71.9k|}
video.c:adjust_sync:
  344|  71.4k|{
  345|  71.4k|    struct MPOpts *opts = mpctx->opts;
  346|       |
  347|  71.4k|    if (mpctx->audio_status != STATUS_PLAYING)
  ------------------
  |  Branch (347:9): [True: 71.4k, False: 0]
  ------------------
  348|  71.4k|        return;
  349|       |
  350|      0|    double a_pts = written_audio_pts(mpctx) + opts->audio_delay - mpctx->delay;
  351|      0|    double av_delay = a_pts - v_pts;
  352|       |
  353|      0|    double change = av_delay * 0.1;
  354|      0|    double factor = fabs(av_delay) < 0.3 ? 0.1 : 0.4;
  ------------------
  |  Branch (354:21): [True: 0, False: 0]
  ------------------
  355|      0|    double max_change = opts->default_max_pts_correction >= 0 ?
  ------------------
  |  Branch (355:25): [True: 0, False: 0]
  ------------------
  356|      0|                        opts->default_max_pts_correction : frame_time * factor;
  357|      0|    if (change < -max_change)
  ------------------
  |  Branch (357:9): [True: 0, False: 0]
  ------------------
  358|      0|        change = -max_change;
  359|      0|    else if (change > max_change)
  ------------------
  |  Branch (359:14): [True: 0, False: 0]
  ------------------
  360|      0|        change = max_change;
  361|      0|    mpctx->delay += change;
  362|      0|    mpctx->total_avsync_change += change;
  363|       |
  364|      0|    if (mpctx->display_sync_active)
  ------------------
  |  Branch (364:9): [True: 0, False: 0]
  ------------------
  365|      0|        mpctx->total_avsync_change = 0;
  366|      0|}

mp_url_unescape_inplace:
  140|   540k|{
  141|  14.8G|    for (int len = strlen(url), i = 0, o = 0; i <= len;) {
  ------------------
  |  Branch (141:47): [True: 14.8G, False: 540k]
  ------------------
  142|  14.8G|        if ((url[i] != '%') || (i > len - 3)) {  // %NN can't start after len-3
  ------------------
  |  Branch (142:13): [True: 14.8G, False: 7.85M]
  |  Branch (142:32): [True: 791, False: 7.85M]
  ------------------
  143|  14.8G|            url[o++] = url[i++];
  144|  14.8G|            continue;
  145|  14.8G|        }
  146|       |
  147|  7.85M|        int msd = hex2dec(url[i + 1]),
  148|  7.85M|            lsd = hex2dec(url[i + 2]);
  149|       |
  150|  7.85M|        if (msd >= 0 && lsd >= 0) {
  ------------------
  |  Branch (150:13): [True: 704k, False: 7.14M]
  |  Branch (150:25): [True: 235k, False: 468k]
  ------------------
  151|   235k|            url[o++] = 16 * msd + lsd;
  152|   235k|            i += 3;
  153|  7.61M|        } else {
  154|  7.61M|            url[o++] = url[i++];
  155|  7.61M|            url[o++] = url[i++];
  156|  7.61M|            url[o++] = url[i++];
  157|  7.61M|        }
  158|  7.85M|    }
  159|   540k|}
stream_create_with_args:
  429|  53.7k|{
  430|  53.7k|    mp_assert(args->url);
  ------------------
  |  |   41|  53.7k|#define mp_assert assert
  ------------------
  431|       |
  432|  53.7k|    int r = STREAM_NO_MATCH;
  ------------------
  |  |   65|  53.7k|#define STREAM_NO_MATCH -2
  ------------------
  433|  53.7k|    *ret = NULL;
  434|       |
  435|       |    // Open stream proper
  436|  53.7k|    if (args->sinfo) {
  ------------------
  |  Branch (436:9): [True: 30.0k, False: 23.6k]
  ------------------
  437|  30.0k|        r = stream_create_instance(args->sinfo, args, ret);
  438|  30.0k|    } else {
  439|  97.6k|        for (int i = 0; i < MP_ARRAY_SIZE(stream_list); i++) {
  ------------------
  |  |   48|  97.6k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (439:25): [True: 97.5k, False: 16]
  ------------------
  440|  97.5k|            r = stream_create_instance(stream_list[i], args, ret);
  441|  97.5k|            if (r == STREAM_OK)
  ------------------
  |  |   68|  97.5k|#define STREAM_OK    1
  ------------------
  |  Branch (441:17): [True: 22.9k, False: 74.6k]
  ------------------
  442|  22.9k|                break;
  443|  74.6k|            if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
  ------------------
  |  |   65|   149k|#define STREAM_NO_MATCH -2
  ------------------
                          if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED)
  ------------------
  |  |   66|    694|#define STREAM_UNSUPPORTED -1
  ------------------
  |  Branch (443:17): [True: 73.9k, False: 694]
  |  Branch (443:41): [True: 17, False: 677]
  ------------------
  444|  73.9k|                continue;
  445|    677|            if (r == STREAM_UNSAFE)
  ------------------
  |  |   64|    677|#define STREAM_UNSAFE -3
  ------------------
  |  Branch (445:17): [True: 0, False: 677]
  ------------------
  446|      0|                continue;
  447|    677|            break;
  448|    677|        }
  449|  23.6k|    }
  450|       |
  451|  53.7k|    if (!*ret && !(args->flags & STREAM_SILENT) && !mp_cancel_test(args->cancel))
  ------------------
  |  |   44|    693|#define STREAM_SILENT             (1 << 1)
  ------------------
  |  Branch (451:9): [True: 693, False: 53.0k]
  |  Branch (451:18): [True: 693, False: 0]
  |  Branch (451:52): [True: 693, False: 0]
  ------------------
  452|    693|    {
  453|    693|        struct mp_log *log = mp_log_new(NULL, args->global->log, "!stream");
  454|       |
  455|    693|        if (r == STREAM_UNSAFE) {
  ------------------
  |  |   64|    693|#define STREAM_UNSAFE -3
  ------------------
  |  Branch (455:13): [True: 0, False: 693]
  ------------------
  456|      0|            mp_err(log, "\nRefusing to load potentially unsafe URL from a playlist.\n"
  ------------------
  |  |   72|      0|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  457|      0|                   "Use the --load-unsafe-playlists option to load it anyway.\n\n");
  458|    693|        } else if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED) {
  ------------------
  |  |   65|  1.38k|#define STREAM_NO_MATCH -2
  ------------------
                      } else if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED) {
  ------------------
  |  |   66|    677|#define STREAM_UNSUPPORTED -1
  ------------------
  |  Branch (458:20): [True: 16, False: 677]
  |  Branch (458:44): [True: 0, False: 677]
  ------------------
  459|     16|            mp_err(log, "No protocol handler found to open URL %s\n", args->url);
  ------------------
  |  |   72|     16|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  460|     16|            mp_err(log, "The protocol is either unsupported, or was disabled "
  ------------------
  |  |   72|     16|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  461|     16|                        "at compile-time.\n");
  462|    677|        } else {
  463|    677|            mp_err(log, "Failed to open %s.\n", args->url);
  ------------------
  |  |   72|    677|#define mp_err(log, ...)        mp_msg(log, MSGL_ERR, __VA_ARGS__)
  ------------------
  464|    677|        }
  465|       |
  466|    693|        talloc_free(log);
  ------------------
  |  |   47|    693|#define talloc_free                     ta_free
  ------------------
  467|    693|    }
  468|       |
  469|  53.7k|    return r;
  470|  53.7k|}
stream_create:
  474|  23.6k|{
  475|  23.6k|    struct stream_open_args args = {
  476|  23.6k|        .global = global,
  477|  23.6k|        .cancel = c,
  478|  23.6k|        .flags = flags,
  479|  23.6k|        .url = url,
  480|  23.6k|    };
  481|  23.6k|    struct stream *s;
  482|  23.6k|    stream_create_with_args(&args, &s);
  483|  23.6k|    return s;
  484|  23.6k|}
stream_read_partial:
  596|   428k|{
  597|   428k|    mp_assert(s->buf_cur <= s->buf_end);
  ------------------
  |  |   41|   428k|#define mp_assert assert
  ------------------
  598|   428k|    mp_assert(buf_size >= 0);
  ------------------
  |  |   41|   428k|#define mp_assert assert
  ------------------
  599|   428k|    if (s->buf_cur == s->buf_end && buf_size > 0) {
  ------------------
  |  Branch (599:9): [True: 393k, False: 34.4k]
  |  Branch (599:37): [True: 393k, False: 0]
  ------------------
  600|   393k|        if (buf_size > (s->buffer_mask + 1) / 2) {
  ------------------
  |  Branch (600:13): [True: 4.37k, False: 389k]
  ------------------
  601|       |            // Direct read if the buffer is too small anyway.
  602|  4.37k|            stream_drop_buffers(s);
  603|  4.37k|            return stream_read_unbuffered(s, buf, buf_size);
  604|  4.37k|        }
  605|   389k|        stream_read_more(s, 1);
  606|   389k|    }
  607|   423k|    int res = ring_copy(s, buf, buf_size, s->buf_cur);
  608|   423k|    s->buf_cur += res;
  609|   423k|    return res;
  610|   428k|}
stream_read_char_fallback:
  614|    436|{
  615|    436|    uint8_t c;
  616|    436|    return stream_read_partial(s, &c, 1) ? c : STREAM_EOF;
  ------------------
  |  |   71|    436|#define STREAM_EOF (-256)
  ------------------
  |  Branch (616:12): [True: 0, False: 436]
  ------------------
  617|    436|}
stream_read:
  620|  1.39k|{
  621|  1.39k|    int len = total;
  622|  2.81k|    while (len > 0) {
  ------------------
  |  Branch (622:12): [True: 2.74k, False: 63]
  ------------------
  623|  2.74k|        int read = stream_read_partial(s, mem, len);
  624|  2.74k|        if (read <= 0)
  ------------------
  |  Branch (624:13): [True: 1.32k, False: 1.41k]
  ------------------
  625|  1.32k|            break; // EOF
  626|  1.41k|        mem = (char *)mem + read;
  627|  1.41k|        len -= read;
  628|  1.41k|    }
  629|  1.39k|    total -= len;
  630|  1.39k|    return total;
  631|  1.39k|}
stream_peek:
  636|  1.46M|{
  637|  1.51M|    while (stream_read_more(s, forward_size)) {}
  ------------------
  |  Branch (637:12): [True: 52.9k, False: 1.46M]
  ------------------
  638|  1.46M|    return s->buf_end - s->buf_cur;
  639|  1.46M|}
stream_read_peek:
  644|  1.46M|{
  645|  1.46M|    stream_peek(s, buf_size);
  646|  1.46M|    return ring_copy(s, buf, buf_size, s->buf_cur);
  647|  1.46M|}
stream_drop_buffers:
  688|  27.7k|{
  689|  27.7k|    s->pos = stream_tell(s);
  690|  27.7k|    s->buf_start = s->buf_cur = s->buf_end = 0;
  691|  27.7k|    s->eof = 0;
  692|  27.7k|    stream_resize_buffer(s, 0, 0);
  693|  27.7k|}
stream_seek:
  725|   945k|{
  726|   945k|    MP_TRACE(s, "seek request from %" PRId64 " to %" PRId64 "\n",
  ------------------
  |  |   90|   945k|#define MP_TRACE(obj, ...)      MP_MSG(obj, MSGL_TRACE, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   945k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  727|   945k|             stream_tell(s), pos);
  728|       |
  729|   945k|    s->eof = 0; // eof should be set only on read; seeking always clears it
  730|       |
  731|   945k|    if (pos < 0) {
  ------------------
  |  Branch (731:9): [True: 0, False: 945k]
  ------------------
  732|      0|        MP_ERR(s, "Invalid seek to negative position %lld!\n", (long long)pos);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  733|      0|        pos = 0;
  734|      0|    }
  735|       |
  736|   945k|    if (pos <= s->pos) {
  ------------------
  |  Branch (736:9): [True: 929k, False: 16.0k]
  ------------------
  737|   929k|        int64_t x = pos - (s->pos - (int)s->buf_end);
  738|   929k|        if (x >= (int)s->buf_start) {
  ------------------
  |  Branch (738:13): [True: 922k, False: 7.35k]
  ------------------
  739|   922k|            s->buf_cur = x;
  740|   922k|            mp_assert(s->buf_cur >= s->buf_start);
  ------------------
  |  |   41|   922k|#define mp_assert assert
  ------------------
  741|   922k|            mp_assert(s->buf_cur <= s->buf_end);
  ------------------
  |  |   41|   922k|#define mp_assert assert
  ------------------
  742|   922k|            return true;
  743|   922k|        }
  744|   929k|    }
  745|       |
  746|  23.4k|    if (s->mode == STREAM_WRITE)
  ------------------
  |  |   42|  23.4k|#define STREAM_WRITE              (1 << 0)
  ------------------
  |  Branch (746:9): [True: 0, False: 23.4k]
  ------------------
  747|      0|        return s->seekable && s->seek(s, pos);
  ------------------
  |  Branch (747:16): [True: 0, False: 0]
  |  Branch (747:31): [True: 0, False: 0]
  ------------------
  748|       |
  749|       |    // Skip data instead of performing a seek in some cases.
  750|  23.4k|    if (pos >= s->pos &&
  ------------------
  |  Branch (750:9): [True: 16.0k, False: 7.35k]
  ------------------
  751|  23.4k|        ((!s->seekable && s->fast_skip) ||
  ------------------
  |  Branch (751:11): [True: 0, False: 16.0k]
  |  Branch (751:27): [True: 0, False: 0]
  ------------------
  752|  16.0k|         pos - s->pos <= s->requested_buffer_size))
  ------------------
  |  Branch (752:10): [True: 68, False: 16.0k]
  ------------------
  753|     68|    {
  754|     68|        return stream_skip_read(s, pos - stream_tell(s));
  755|     68|    }
  756|       |
  757|  23.3k|    return stream_seek_unbuffered(s, pos);
  758|  23.4k|}
stream_seek_skip:
  763|   664k|{
  764|   664k|    uint64_t cur_pos = stream_tell(s);
  765|       |
  766|   664k|    if (cur_pos == pos)
  ------------------
  |  Branch (766:9): [True: 9.08k, False: 655k]
  ------------------
  767|  9.08k|        return true;
  768|       |
  769|   655k|    return !s->seekable && pos > cur_pos
  ------------------
  |  Branch (769:12): [True: 0, False: 655k]
  |  Branch (769:28): [True: 0, False: 0]
  ------------------
  770|   655k|        ? stream_skip_read(s, pos - cur_pos)
  771|   655k|        : stream_seek(s, pos);
  772|   664k|}
stream_control:
  775|  1.60M|{
  776|  1.60M|    return s->control ? s->control(s, cmd, arg) : STREAM_UNSUPPORTED;
  ------------------
  |  |   66|  1.60M|#define STREAM_UNSUPPORTED -1
  ------------------
  |  Branch (776:12): [True: 0, False: 1.60M]
  ------------------
  777|  1.60M|}
stream_get_size:
  781|   124k|{
  782|   124k|    return s->get_size ? s->get_size(s) : -1;
  ------------------
  |  Branch (782:12): [True: 124k, False: 80]
  ------------------
  783|   124k|}
free_stream:
  786|   248k|{
  787|   248k|    if (!s)
  ------------------
  |  Branch (787:9): [True: 195k, False: 53.0k]
  ------------------
  788|   195k|        return;
  789|       |
  790|  53.0k|    if (s->close)
  ------------------
  |  Branch (790:9): [True: 0, False: 53.0k]
  ------------------
  791|      0|        s->close(s);
  792|  53.0k|    talloc_free(s);
  ------------------
  |  |   47|  53.0k|#define talloc_free                     ta_free
  ------------------
  793|  53.0k|}
stream_skip_bom:
  799|  30.1k|{
  800|  30.1k|    char buf[4];
  801|  30.1k|    int len = stream_read_peek(s, buf, sizeof(buf));
  802|  30.1k|    bstr data = {buf, len};
  803|   120k|    for (int n = 0; n < 3; n++) {
  ------------------
  |  Branch (803:21): [True: 90.3k, False: 29.9k]
  ------------------
  804|  90.3k|        if (bstr_startswith0(data, bom[n])) {
  ------------------
  |  Branch (804:13): [True: 276, False: 90.1k]
  ------------------
  805|    276|            stream_seek_skip(s, stream_tell(s) + strlen(bom[n]));
  806|    276|            return n;
  807|    276|        }
  808|  90.3k|    }
  809|  29.9k|    return -1; // default to 8 bit codepages
  810|  30.1k|}
stream_read_complete:
  825|  1.30k|{
  826|  1.30k|    if (max_size < 0 || max_size > STREAM_MAX_READ_SIZE)
  ------------------
  |  |   36|  1.30k|#define STREAM_MAX_READ_SIZE (INT_MAX - 1)
  ------------------
  |  Branch (826:9): [True: 0, False: 1.30k]
  |  Branch (826:25): [True: 0, False: 1.30k]
  ------------------
  827|      0|        abort();
  828|  1.30k|    if (s->is_directory)
  ------------------
  |  Branch (828:9): [True: 0, False: 1.30k]
  ------------------
  829|      0|        return (struct bstr){NULL, 0};
  830|       |
  831|  1.30k|    int bufsize;
  832|  1.30k|    int total_read = 0;
  833|  1.30k|    int padding = 1;
  834|  1.30k|    char *buf = NULL;
  835|  1.30k|    int64_t size = stream_get_size(s) - stream_tell(s);
  836|  1.30k|    if (size > max_size && !s->allow_partial_read)
  ------------------
  |  Branch (836:9): [True: 0, False: 1.30k]
  |  Branch (836:28): [True: 0, False: 0]
  ------------------
  837|      0|        return (struct bstr){NULL, 0};
  838|  1.30k|    if (size > 0)
  ------------------
  |  Branch (838:9): [True: 1.30k, False: 0]
  ------------------
  839|  1.30k|        bufsize = size + padding;
  840|      0|    else
  841|      0|        bufsize = 1000;
  842|  1.30k|    if (s->allow_partial_read)
  ------------------
  |  Branch (842:9): [True: 0, False: 1.30k]
  ------------------
  843|      0|        bufsize = MPMIN(bufsize, max_size + padding);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  844|  1.30k|    while (1) {
  ------------------
  |  Branch (844:12): [Folded - Ignored]
  ------------------
  845|  1.30k|        buf = talloc_realloc_size(talloc_ctx, buf, bufsize);
  ------------------
  |  |   39|  1.30k|#define talloc_realloc_size             ta_xrealloc_size
  |  |  ------------------
  |  |  |  |  158|  1.30k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  1.30k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  1.30k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  1.30k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  846|  1.30k|        int readsize = stream_read(s, buf + total_read, bufsize - total_read);
  847|  1.30k|        total_read += readsize;
  848|  1.30k|        if (total_read >= max_size && s->allow_partial_read) {
  ------------------
  |  Branch (848:13): [True: 0, False: 1.30k]
  |  Branch (848:39): [True: 0, False: 0]
  ------------------
  849|      0|            total_read = max_size;
  850|      0|            break;
  851|      0|        }
  852|  1.30k|        if (total_read < bufsize)
  ------------------
  |  Branch (852:13): [True: 1.30k, False: 0]
  ------------------
  853|  1.30k|            break;
  854|      0|        if (bufsize > max_size) {
  ------------------
  |  Branch (854:13): [True: 0, False: 0]
  ------------------
  855|      0|            talloc_free(buf);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  856|      0|            return (struct bstr){NULL, 0};
  857|      0|        }
  858|      0|        bufsize = MPMIN(bufsize + (bufsize >> 1), max_size + padding);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  859|      0|    }
  860|  1.30k|    buf = talloc_realloc_size(talloc_ctx, buf, total_read + padding);
  ------------------
  |  |   39|  1.30k|#define talloc_realloc_size             ta_xrealloc_size
  |  |  ------------------
  |  |  |  |  158|  1.30k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  1.30k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  1.30k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  1.30k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  861|  1.30k|    memset(&buf[total_read], 0, padding);
  862|  1.30k|    return (struct bstr){buf, total_read};
  863|  1.30k|}
stream.c:hex2dec:
  128|  15.7M|{
  129|  15.7M|    if (c >= '0' && c <= '9')
  ------------------
  |  Branch (129:9): [True: 2.99M, False: 12.7M]
  |  Branch (129:21): [True: 151k, False: 2.83M]
  ------------------
  130|   151k|        return c - '0';
  131|  15.5M|    if (c >= 'A' && c <= 'F')
  ------------------
  |  Branch (131:9): [True: 2.83M, False: 12.7M]
  |  Branch (131:21): [True: 365k, False: 2.46M]
  ------------------
  132|   365k|        return 10 + c - 'A';
  133|  15.1M|    if (c >= 'a' && c <= 'f')
  ------------------
  |  Branch (133:9): [True: 1.68M, False: 13.4M]
  |  Branch (133:21): [True: 491k, False: 1.19M]
  ------------------
  134|   491k|        return 10 + c - 'a';
  135|  14.6M|    return -1;
  136|  15.1M|}
stream.c:stream_create_instance:
  325|   127k|{
  326|   127k|    const char *url = args->url;
  327|   127k|    int flags = args->flags;
  328|       |
  329|   127k|    *ret = NULL;
  330|       |
  331|   127k|    const char *path = url;
  332|       |
  333|   127k|    if (flags & STREAM_LOCAL_FS_ONLY) {
  ------------------
  |  |   54|   127k|#define STREAM_LOCAL_FS_ONLY      (1 << 5) // stream_file only, no URLs
  ------------------
  |  Branch (333:9): [True: 0, False: 127k]
  ------------------
  334|      0|        if (!sinfo->local_fs)
  ------------------
  |  Branch (334:13): [True: 0, False: 0]
  ------------------
  335|      0|            return STREAM_NO_MATCH;
  ------------------
  |  |   65|      0|#define STREAM_NO_MATCH -2
  ------------------
  336|   127k|    } else {
  337|   127k|        char **get_protocols = sinfo->get_protocols ? sinfo->get_protocols() : NULL;
  ------------------
  |  Branch (337:32): [True: 34, False: 127k]
  ------------------
  338|   127k|        char **protocols = get_protocols ? get_protocols : (char **)sinfo->protocols;
  ------------------
  |  Branch (338:28): [True: 34, False: 127k]
  ------------------
  339|       |
  340|   226k|        for (int n = 0; protocols && protocols[n]; n++) {
  ------------------
  |  Branch (340:25): [True: 226k, False: 17]
  |  Branch (340:38): [True: 153k, False: 73.9k]
  ------------------
  341|   153k|            path = match_proto(url, protocols[n]);
  342|   153k|            if (path)
  ------------------
  |  Branch (342:17): [True: 53.7k, False: 99.2k]
  ------------------
  343|  53.7k|                break;
  344|   153k|        }
  345|       |
  346|   127k|        talloc_free(get_protocols);
  ------------------
  |  |   47|   127k|#define talloc_free                     ta_free
  ------------------
  347|       |
  348|   127k|        if (!path)
  ------------------
  |  Branch (348:13): [True: 73.9k, False: 53.7k]
  ------------------
  349|  73.9k|            return STREAM_NO_MATCH;
  ------------------
  |  |   65|  73.9k|#define STREAM_NO_MATCH -2
  ------------------
  350|   127k|    }
  351|       |
  352|  53.7k|    stream_t *s = talloc_zero(NULL, stream_t);
  ------------------
  |  |   27|  53.7k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  53.7k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  53.7k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  353|  53.7k|    s->global = args->global;
  354|  53.7k|    struct stream_opts *opts = mp_get_config_group(s, s->global, &stream_conf);
  355|  53.7k|    if (flags & STREAM_SILENT) {
  ------------------
  |  |   44|  53.7k|#define STREAM_SILENT             (1 << 1)
  ------------------
  |  Branch (355:9): [True: 30.0k, False: 23.6k]
  ------------------
  356|  30.0k|        s->log = mp_null_log;
  357|  30.0k|    } else {
  358|  23.6k|        s->log = mp_log_new(s, s->global->log, sinfo->name);
  359|  23.6k|    }
  360|  53.7k|    s->info = sinfo;
  361|  53.7k|    s->cancel = args->cancel;
  362|  53.7k|    s->url = talloc_strdup(s, url);
  ------------------
  |  |   50|  53.7k|#define talloc_strdup                   ta_xstrdup
  ------------------
  363|  53.7k|    s->path = talloc_strdup(s, path);
  ------------------
  |  |   50|  53.7k|#define talloc_strdup                   ta_xstrdup
  ------------------
  364|  53.7k|    s->mode = flags & (STREAM_READ | STREAM_WRITE);
  ------------------
  |  |   41|  53.7k|#define STREAM_READ               0
  ------------------
                  s->mode = flags & (STREAM_READ | STREAM_WRITE);
  ------------------
  |  |   42|  53.7k|#define STREAM_WRITE              (1 << 0)
  ------------------
  365|  53.7k|    s->requested_buffer_size = opts->buffer_size;
  366|  53.7k|    s->allow_partial_read = flags & STREAM_ALLOW_PARTIAL_READ;
  ------------------
  |  |   56|  53.7k|#define STREAM_ALLOW_PARTIAL_READ (1 << 7) // allows partial read with stream_read_file()
  ------------------
  367|       |
  368|  53.7k|    if (flags & STREAM_LESS_NOISE)
  ------------------
  |  |   55|  53.7k|#define STREAM_LESS_NOISE         (1 << 6) // try to log errors only
  ------------------
  |  Branch (368:9): [True: 0, False: 53.7k]
  ------------------
  369|      0|        mp_msg_set_max_level(s->log, MSGL_WARN);
  370|       |
  371|  53.7k|    struct demux_opts *demux_opts = mp_get_config_group(s, s->global, &demux_conf);
  372|  53.7k|    s->access_references = demux_opts->access_references;
  373|  53.7k|    talloc_free(demux_opts);
  ------------------
  |  |   47|  53.7k|#define talloc_free                     ta_free
  ------------------
  374|       |
  375|  53.7k|    MP_VERBOSE(s, "Opening %s\n", url);
  ------------------
  |  |   88|  53.7k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  53.7k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  376|       |
  377|  53.7k|    if (strlen(url) > INT_MAX / 8) {
  ------------------
  |  Branch (377:9): [True: 0, False: 53.7k]
  ------------------
  378|      0|        MP_ERR(s, "URL too large.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  379|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  380|      0|        return STREAM_ERROR;
  ------------------
  |  |   67|      0|#define STREAM_ERROR 0
  ------------------
  381|      0|    }
  382|       |
  383|  53.7k|    if ((s->mode & STREAM_WRITE) && !sinfo->can_write) {
  ------------------
  |  |   42|  53.7k|#define STREAM_WRITE              (1 << 0)
  ------------------
  |  Branch (383:9): [True: 0, False: 53.7k]
  |  Branch (383:37): [True: 0, False: 0]
  ------------------
  384|      0|        MP_DBG(s, "No write access implemented.\n");
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  385|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  386|      0|        return STREAM_NO_MATCH;
  ------------------
  |  |   65|      0|#define STREAM_NO_MATCH -2
  ------------------
  387|      0|    }
  388|       |
  389|  53.7k|    s->stream_origin = flags & STREAM_ORIGIN_MASK; // pass through by default
  ------------------
  |  |   52|  53.7k|#define STREAM_ORIGIN_MASK        (7 << 2) // for extracting origin value from flags
  ------------------
  390|  53.7k|    if (opts->load_unsafe_playlists) {
  ------------------
  |  Branch (390:9): [True: 0, False: 53.7k]
  ------------------
  391|      0|        s->stream_origin = STREAM_ORIGIN_DIRECT;
  ------------------
  |  |   47|      0|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  ------------------
  392|  53.7k|    } else if (sinfo->stream_origin) {
  ------------------
  |  Branch (392:16): [True: 691, False: 53.0k]
  ------------------
  393|    691|        s->stream_origin = check_origin(s->stream_origin, sinfo->stream_origin);
  394|    691|    }
  395|       |
  396|  53.7k|    if (!s->stream_origin) {
  ------------------
  |  Branch (396:9): [True: 0, False: 53.7k]
  ------------------
  397|      0|        talloc_free(s);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  398|      0|        return STREAM_UNSAFE;
  ------------------
  |  |   64|      0|#define STREAM_UNSAFE -3
  ------------------
  399|      0|    }
  400|       |
  401|  53.7k|    int r = STREAM_UNSUPPORTED;
  ------------------
  |  |   66|  53.7k|#define STREAM_UNSUPPORTED -1
  ------------------
  402|  53.7k|    if (sinfo->open2) {
  ------------------
  |  Branch (402:9): [True: 53.6k, False: 99]
  ------------------
  403|  53.6k|        r = sinfo->open2(s, args);
  404|  53.6k|    } else if (!args->special_arg) {
  ------------------
  |  Branch (404:16): [True: 99, False: 0]
  ------------------
  405|     99|        r = (sinfo->open)(s);
  406|     99|    }
  407|  53.7k|    if (r != STREAM_OK) {
  ------------------
  |  |   68|  53.7k|#define STREAM_OK    1
  ------------------
  |  Branch (407:9): [True: 694, False: 53.0k]
  ------------------
  408|    694|        talloc_free(s);
  ------------------
  |  |   47|    694|#define talloc_free                     ta_free
  ------------------
  409|    694|        return r;
  410|    694|    }
  411|       |
  412|  53.0k|    if (!stream_resize_buffer(s, 0, 0)) {
  ------------------
  |  Branch (412:9): [True: 0, False: 53.0k]
  ------------------
  413|      0|        free_stream(s);
  414|      0|        return STREAM_ERROR;
  ------------------
  |  |   67|      0|#define STREAM_ERROR 0
  ------------------
  415|      0|    }
  416|       |
  417|  53.0k|    mp_assert(s->seekable == !!s->seek);
  ------------------
  |  |   41|  53.0k|#define mp_assert assert
  ------------------
  418|       |
  419|  53.0k|    if (s->mime_type)
  ------------------
  |  Branch (419:9): [True: 0, False: 53.0k]
  ------------------
  420|  53.0k|        MP_VERBOSE(s, "Mime-type: '%s'\n", s->mime_type);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  421|       |
  422|  53.0k|    MP_DBG(s, "Stream opened successfully.\n");
  ------------------
  |  |   89|  53.0k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  53.0k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  423|       |
  424|  53.0k|    *ret = s;
  425|  53.0k|    return STREAM_OK;
  ------------------
  |  |   68|  53.0k|#define STREAM_OK    1
  ------------------
  426|  53.0k|}
stream.c:match_proto:
  207|   153k|{
  208|   153k|    int l = strlen(proto);
  209|   153k|    if (l > 0) {
  ------------------
  |  Branch (209:9): [True: 152k, False: 690]
  ------------------
  210|   152k|        if (strncasecmp(url, proto, l) == 0 && strncmp("://", url + l, 3) == 0)
  ------------------
  |  Branch (210:13): [True: 53.1k, False: 99.1k]
  |  Branch (210:48): [True: 53.0k, False: 80]
  ------------------
  211|  53.0k|            return url + l + 3;
  212|   152k|    } else if (!mp_is_url(bstr0(url))) {
  ------------------
  |  Branch (212:16): [True: 665, False: 25]
  ------------------
  213|    665|        return url; // pure filenames
  214|    665|    }
  215|  99.2k|    return NULL;
  216|   153k|}
stream.c:check_origin:
  222|    691|{
  223|    691|    switch (src) {
  ------------------
  |  Branch (223:13): [True: 0, False: 691]
  ------------------
  224|    691|    case STREAM_ORIGIN_DIRECT:
  ------------------
  |  |   47|    691|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  ------------------
  |  Branch (224:5): [True: 691, False: 0]
  ------------------
  225|    691|    case STREAM_ORIGIN_UNSAFE:
  ------------------
  |  |   50|    691|#define STREAM_ORIGIN_UNSAFE      (4 << 2) // from a grotesque source
  ------------------
  |  Branch (225:5): [True: 0, False: 691]
  ------------------
  226|       |        // Allow anything, but constrain it to the new origin.
  227|    691|        return new;
  228|      0|    case STREAM_ORIGIN_FS:
  ------------------
  |  |   48|      0|#define STREAM_ORIGIN_FS          (2 << 2) // referenced from playlist on unix FS
  ------------------
  |  Branch (228:5): [True: 0, False: 691]
  ------------------
  229|       |        // From unix FS, allow all but unsafe.
  230|      0|        if (new == STREAM_ORIGIN_FS || new == STREAM_ORIGIN_NET)
  ------------------
  |  |   48|      0|#define STREAM_ORIGIN_FS          (2 << 2) // referenced from playlist on unix FS
  ------------------
                      if (new == STREAM_ORIGIN_FS || new == STREAM_ORIGIN_NET)
  ------------------
  |  |   49|      0|#define STREAM_ORIGIN_NET         (3 << 2) // referenced from playlist on network
  ------------------
  |  Branch (230:13): [True: 0, False: 0]
  |  Branch (230:40): [True: 0, False: 0]
  ------------------
  231|      0|            return new;
  232|      0|        break;
  233|      0|    case STREAM_ORIGIN_NET:
  ------------------
  |  |   49|      0|#define STREAM_ORIGIN_NET         (3 << 2) // referenced from playlist on network
  ------------------
  |  Branch (233:5): [True: 0, False: 691]
  ------------------
  234|       |        // Allow only other network links.
  235|      0|        if (new == STREAM_ORIGIN_NET)
  ------------------
  |  |   49|      0|#define STREAM_ORIGIN_NET         (3 << 2) // referenced from playlist on network
  ------------------
  |  Branch (235:13): [True: 0, False: 0]
  ------------------
  236|      0|            return new;
  237|      0|        break;
  238|    691|    }
  239|      0|    return 0;
  240|    691|}
stream.c:stream_read_unbuffered:
  502|   583k|{
  503|   583k|    mp_assert(len >= 0);
  ------------------
  |  |   41|   583k|#define mp_assert assert
  ------------------
  504|   583k|    if (len <= 0)
  ------------------
  |  Branch (504:9): [True: 0, False: 583k]
  ------------------
  505|      0|        return 0;
  506|       |
  507|   583k|    int res = 0;
  508|       |    // we will retry even if we already reached EOF previously.
  509|   583k|    if (s->fill_buffer && !mp_cancel_test(s->cancel))
  ------------------
  |  Branch (509:9): [True: 582k, False: 493]
  |  Branch (509:27): [True: 582k, False: 0]
  ------------------
  510|   582k|        res = s->fill_buffer(s, buf, len);
  511|   583k|    if (res <= 0) {
  ------------------
  |  Branch (511:9): [True: 520k, False: 62.9k]
  ------------------
  512|   520k|        s->eof = 1;
  513|   520k|        return 0;
  514|   520k|    }
  515|  62.9k|    mp_assert(res <= len);
  ------------------
  |  |   41|  62.9k|#define mp_assert assert
  ------------------
  516|       |    // When reading succeeded we are obviously not at eof.
  517|  62.9k|    s->eof = 0;
  518|  62.9k|    s->pos += res;
  519|  62.9k|    s->total_unbuffered_read_bytes += res;
  520|  62.9k|    return res;
  521|  62.9k|}
stream.c:stream_read_more:
  528|  1.90M|{
  529|  1.90M|    mp_assert(forward >= 0);
  ------------------
  |  |   41|  1.90M|#define mp_assert assert
  ------------------
  530|       |
  531|  1.90M|    int forward_avail = s->buf_end - s->buf_cur;
  532|  1.90M|    if (forward_avail >= forward)
  ------------------
  |  Branch (532:9): [True: 1.32M, False: 579k]
  ------------------
  533|  1.32M|        return false;
  534|       |
  535|       |    // Avoid that many small reads will lead to many low-level read calls.
  536|   579k|    forward = MPMAX(forward, s->requested_buffer_size / 2);
  ------------------
  |  |   43|   579k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 1.24k, False: 577k]
  |  |  ------------------
  ------------------
  537|   579k|    mp_assert(forward_avail < forward);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  538|       |
  539|       |    // Keep guaranteed seek-back.
  540|   579k|    int buf_old = MPMIN(s->buf_cur - s->buf_start, s->requested_buffer_size / 2);
  ------------------
  |  |   44|   579k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 26.6k, False: 552k]
  |  |  ------------------
  ------------------
  541|       |
  542|   579k|    if (!stream_resize_buffer(s, buf_old + forward_avail, buf_old + forward))
  ------------------
  |  Branch (542:9): [True: 0, False: 579k]
  ------------------
  543|      0|        return false;
  544|       |
  545|   579k|    int buf_alloc = s->buffer_mask + 1;
  546|       |
  547|   579k|    mp_assert(s->buf_start <= s->buf_cur);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  548|   579k|    mp_assert(s->buf_cur <= s->buf_end);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  549|   579k|    mp_assert(s->buf_cur < buf_alloc * 2);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  550|   579k|    mp_assert(s->buf_end < buf_alloc * 2);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  551|   579k|    mp_assert(s->buf_start < buf_alloc);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  552|       |
  553|       |    // Note: read as much as possible, even if forward is much smaller. Do
  554|       |    // this because the stream buffer is supposed to set an approx. minimum
  555|       |    // read size on it.
  556|   579k|    int read = buf_alloc - (buf_old + forward_avail); // free buffer past end
  557|       |
  558|   579k|    int pos = s->buf_end & s->buffer_mask;
  559|   579k|    read = MPMIN(read, buf_alloc - pos);
  ------------------
  |  |   44|   579k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 11.8k, False: 567k]
  |  |  ------------------
  ------------------
  560|       |
  561|       |    // Note: if wrap-around happens, we need to make two calls. This may
  562|       |    // affect latency (e.g. waiting for new data on a socket), so do only
  563|       |    // 1 read call always.
  564|   579k|    read = stream_read_unbuffered(s, &s->buffer[pos], read);
  565|       |
  566|   579k|    s->buf_end += read;
  567|       |
  568|       |    // May have overwritten old data.
  569|   579k|    if (s->buf_end - s->buf_start >= buf_alloc) {
  ------------------
  |  Branch (569:9): [True: 22.3k, False: 556k]
  ------------------
  570|  22.3k|        mp_assert(s->buf_end >= buf_alloc);
  ------------------
  |  |   41|  22.3k|#define mp_assert assert
  ------------------
  571|       |
  572|  22.3k|        s->buf_start = s->buf_end - buf_alloc;
  573|       |
  574|  22.3k|        mp_assert(s->buf_start <= s->buf_cur);
  ------------------
  |  |   41|  22.3k|#define mp_assert assert
  ------------------
  575|  22.3k|        mp_assert(s->buf_cur <= s->buf_end);
  ------------------
  |  |   41|  22.3k|#define mp_assert assert
  ------------------
  576|       |
  577|  22.3k|        if (s->buf_start >= buf_alloc) {
  ------------------
  |  Branch (577:13): [True: 799, False: 21.5k]
  ------------------
  578|    799|            s->buf_start -= buf_alloc;
  579|    799|            s->buf_cur -= buf_alloc;
  580|    799|            s->buf_end -= buf_alloc;
  581|    799|        }
  582|  22.3k|    }
  583|       |
  584|       |    // Must not have overwritten guaranteed old data.
  585|   579k|    mp_assert(s->buf_cur - s->buf_start >= buf_old);
  ------------------
  |  |   41|   579k|#define mp_assert assert
  ------------------
  586|       |
  587|   579k|    if (s->buf_cur < s->buf_end)
  ------------------
  |  Branch (587:9): [True: 180k, False: 398k]
  ------------------
  588|   180k|        s->eof = 0;
  589|       |
  590|   579k|    return !!read;
  591|   579k|}
stream.c:ring_copy:
  248|  1.88M|{
  249|  1.88M|    mp_assert(len >= 0);
  ------------------
  |  |   41|  1.88M|#define mp_assert assert
  ------------------
  250|       |
  251|  1.88M|    if (pos < s->buf_start || pos > s->buf_end)
  ------------------
  |  Branch (251:9): [True: 0, False: 1.88M]
  |  Branch (251:31): [True: 0, False: 1.88M]
  ------------------
  252|      0|        return 0;
  253|       |
  254|  1.88M|    int copied = 0;
  255|  1.88M|    len = MPMIN(len, s->buf_end - pos);
  ------------------
  |  |   44|  1.88M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 548k, False: 1.33M]
  |  |  ------------------
  ------------------
  256|       |
  257|  1.88M|    if (len && pos <= s->buffer_mask) {
  ------------------
  |  Branch (257:9): [True: 1.48M, False: 398k]
  |  Branch (257:16): [True: 1.39M, False: 93.4k]
  ------------------
  258|  1.39M|        int copy = MPMIN(len, s->buffer_mask + 1 - pos);
  ------------------
  |  |   44|  1.39M|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 1.24k, False: 1.39M]
  |  |  ------------------
  ------------------
  259|  1.39M|        memcpy(dst, &s->buffer[pos], copy);
  260|  1.39M|        copied += copy;
  261|  1.39M|        len -= copy;
  262|  1.39M|        pos += copy;
  263|  1.39M|    }
  264|       |
  265|  1.88M|    if (len) {
  ------------------
  |  Branch (265:9): [True: 94.7k, False: 1.79M]
  ------------------
  266|  94.7k|        memcpy((char *)dst + copied, &s->buffer[pos & s->buffer_mask], len);
  267|  94.7k|        copied += len;
  268|  94.7k|    }
  269|       |
  270|  1.88M|    return copied;
  271|  1.88M|}
stream.c:stream_resize_buffer:
  281|   659k|{
  282|   659k|    mp_assert(keep >= s->buf_end - s->buf_cur);
  ------------------
  |  |   41|   659k|#define mp_assert assert
  ------------------
  283|   659k|    mp_assert(keep <= new);
  ------------------
  |  |   41|   659k|#define mp_assert assert
  ------------------
  284|       |
  285|   659k|    new = MPMAX(new, s->requested_buffer_size);
  ------------------
  |  |   43|   659k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 777, False: 659k]
  |  |  ------------------
  ------------------
  286|   659k|    new = MPMIN(new, STREAM_MAX_BUFFER_SIZE);
  ------------------
  |  |   44|   659k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 659k]
  |  |  ------------------
  ------------------
  287|   659k|    new = mp_round_next_power_of_2(new);
  288|       |
  289|   659k|    mp_assert(keep <= new); // can't fail (if old buffer size was valid)
  ------------------
  |  |   41|   659k|#define mp_assert assert
  ------------------
  290|       |
  291|   659k|    if (new == s->buffer_mask + 1)
  ------------------
  |  Branch (291:9): [True: 605k, False: 54.0k]
  ------------------
  292|   605k|        return true;
  293|       |
  294|  54.0k|    int old_pos = s->buf_cur - s->buf_start;
  295|  54.0k|    int old_used_len = s->buf_end - s->buf_start;
  296|  54.0k|    int skip = old_used_len > new ? old_used_len - new : 0;
  ------------------
  |  Branch (296:16): [True: 40, False: 53.9k]
  ------------------
  297|       |
  298|  54.0k|    MP_DBG(s, "resize stream to %d bytes, drop %d bytes\n", new, skip);
  ------------------
  |  |   89|  54.0k|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  54.0k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  299|       |
  300|  54.0k|    void *nbuf = ta_alloc_size(s, new);
  ------------------
  |  |  153|  54.0k|#define ta_alloc_size(...)      ta_dbg_set_loc(ta_alloc_size(__VA_ARGS__), TA_LOC)
  |  |  ------------------
  |  |  |  |   43|  54.0k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  54.0k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   37|  54.0k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  301|  54.0k|    if (!nbuf)
  ------------------
  |  Branch (301:9): [True: 0, False: 54.0k]
  ------------------
  302|      0|        return false; // oom; tolerate it, caller needs to check if required
  303|       |
  304|  54.0k|    int new_len = 0;
  305|  54.0k|    if (s->buffer)
  ------------------
  |  Branch (305:9): [True: 940, False: 53.0k]
  ------------------
  306|    940|        new_len = ring_copy(s, nbuf, new, s->buf_start + skip);
  307|  54.0k|    mp_assert(new_len == old_used_len - skip);
  ------------------
  |  |   41|  54.0k|#define mp_assert assert
  ------------------
  308|  54.0k|    mp_assert(old_pos >= skip); // "keep" too low
  ------------------
  |  |   41|  54.0k|#define mp_assert assert
  ------------------
  309|  54.0k|    mp_assert(old_pos - skip <= new_len);
  ------------------
  |  |   41|  54.0k|#define mp_assert assert
  ------------------
  310|  54.0k|    s->buf_start = 0;
  311|  54.0k|    s->buf_cur = old_pos - skip;
  312|  54.0k|    s->buf_end = new_len;
  313|       |
  314|  54.0k|    ta_free(s->buffer);
  315|       |
  316|  54.0k|    s->buffer = nbuf;
  317|  54.0k|    s->buffer_mask = new - 1;
  318|       |
  319|  54.0k|    return true;
  320|  54.0k|}
stream.c:stream_skip_read:
  669|     68|{
  670|    146|    while (len > 0) {
  ------------------
  |  Branch (670:12): [True: 136, False: 10]
  ------------------
  671|    136|        unsigned int left = s->buf_end - s->buf_cur;
  672|    136|        if (!left) {
  ------------------
  |  Branch (672:13): [True: 72, False: 64]
  ------------------
  673|     72|            if (!stream_read_more(s, 1))
  ------------------
  |  Branch (673:17): [True: 58, False: 14]
  ------------------
  674|     58|                return false;
  675|     14|            continue;
  676|     72|        }
  677|     64|        unsigned skip = MPMIN(len, left);
  ------------------
  |  |   44|     64|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 54, False: 10]
  |  |  ------------------
  ------------------
  678|     64|        s->buf_cur += skip;
  679|     64|        len -= skip;
  680|     64|    }
  681|     10|    return true;
  682|     68|}
stream.c:stream_seek_unbuffered:
  697|  23.3k|{
  698|  23.3k|    if (newpos != s->pos) {
  ------------------
  |  Branch (698:9): [True: 23.3k, False: 0]
  ------------------
  699|  23.3k|        MP_VERBOSE(s, "stream level seek from %" PRId64 " to %" PRId64 "\n",
  ------------------
  |  |   88|  23.3k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  23.3k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  700|  23.3k|                   s->pos, newpos);
  701|       |
  702|  23.3k|        s->total_stream_seeks++;
  703|       |
  704|  23.3k|        if (newpos > s->pos && !s->seekable) {
  ------------------
  |  Branch (704:13): [True: 16.0k, False: 7.35k]
  |  Branch (704:32): [True: 0, False: 16.0k]
  ------------------
  705|      0|            MP_ERR(s, "Cannot seek forward in this stream\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  706|      0|            return false;
  707|      0|        }
  708|  23.3k|        if (newpos < s->pos && !s->seekable) {
  ------------------
  |  Branch (708:13): [True: 7.35k, False: 16.0k]
  |  Branch (708:32): [True: 0, False: 7.35k]
  ------------------
  709|      0|            MP_ERR(s, "Cannot seek backward in linear streams!\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  710|      0|            return false;
  711|      0|        }
  712|  23.3k|        if (s->seek(s, newpos) <= 0) {
  ------------------
  |  Branch (712:13): [True: 0, False: 23.3k]
  ------------------
  713|      0|            int level = mp_cancel_test(s->cancel) ? MSGL_V : MSGL_ERR;
  ------------------
  |  Branch (713:25): [True: 0, False: 0]
  ------------------
  714|      0|            MP_MSG(s, level, "Seek failed (to %lld, size %lld)\n",
  ------------------
  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  ------------------
  715|      0|                   (long long)newpos, (long long)stream_get_size(s));
  716|      0|            return false;
  717|      0|        }
  718|  23.3k|        stream_drop_buffers(s);
  719|  23.3k|        s->pos = newpos;
  720|  23.3k|    }
  721|  23.3k|    return true;
  722|  23.3k|}

stream.c:stream_tell:
  222|  1.64M|{
  223|  1.64M|    return s->pos + s->buf_cur - s->buf_end;
  224|  1.64M|}
demux_lavf.c:stream_tell:
  222|   473k|{
  223|   473k|    return s->pos + s->buf_cur - s->buf_end;
  224|   473k|}
demux_playlist.c:stream_read_char:
  213|   570k|{
  214|   570k|    return s->buf_cur < s->buf_end
  ------------------
  |  Branch (214:12): [True: 569k, False: 436]
  ------------------
  215|   570k|        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
  216|   570k|        : stream_read_char_fallback(s);
  217|   570k|}
demux_playlist.c:stream_tell:
  222|   694k|{
  223|   694k|    return s->pos + s->buf_cur - s->buf_end;
  224|   694k|}
ebml.c:stream_read_char:
  213|  49.7k|{
  214|  49.7k|    return s->buf_cur < s->buf_end
  ------------------
  |  Branch (214:12): [True: 49.7k, False: 0]
  ------------------
  215|  49.7k|        ? s->buffer[(s->buf_cur++) & s->buffer_mask]
  216|  49.7k|        : stream_read_char_fallback(s);
  217|  49.7k|}

stream_cb.c:open_cb:
   55|     17|{
   56|     17|    struct priv *p = talloc_ptrtype(stream, p);
  ------------------
  |  |   34|     17|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|     17|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|     17|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   57|     17|    stream->priv = p;
   58|       |
   59|     17|    bstr bproto = mp_split_proto(bstr0(stream->url), NULL);
   60|     17|    char *proto = bstrto0(stream, bproto);
   61|       |
   62|     17|    void *user_data;
   63|     17|    mpv_stream_cb_open_ro_fn open_fn;
   64|       |
   65|     17|    if (!mp_streamcb_lookup(stream->global, proto, &user_data, &open_fn))
  ------------------
  |  Branch (65:9): [True: 17, False: 0]
  ------------------
   66|     17|        return STREAM_UNSUPPORTED;
  ------------------
  |  |   66|     17|#define STREAM_UNSUPPORTED -1
  ------------------
   67|       |
   68|      0|    mpv_stream_cb_info info = {0};
   69|       |
   70|      0|    int r = open_fn(user_data, stream->url, &info);
   71|      0|    if (r < 0) {
  ------------------
  |  Branch (71:9): [True: 0, False: 0]
  ------------------
   72|      0|        if (r != MPV_ERROR_LOADING_FAILED)
  ------------------
  |  Branch (72:13): [True: 0, False: 0]
  ------------------
   73|      0|            MP_WARN(stream, "unknown error from user callback\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   74|      0|        return STREAM_ERROR;
  ------------------
  |  |   67|      0|#define STREAM_ERROR 0
  ------------------
   75|      0|    }
   76|       |
   77|      0|    if (!info.read_fn || !info.close_fn) {
  ------------------
  |  Branch (77:9): [True: 0, False: 0]
  |  Branch (77:26): [True: 0, False: 0]
  ------------------
   78|      0|        MP_FATAL(stream, "required read_fn or close_fn callbacks not set.\n");
  ------------------
  |  |   84|      0|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   79|      0|        return STREAM_ERROR;
  ------------------
  |  |   67|      0|#define STREAM_ERROR 0
  ------------------
   80|      0|    }
   81|       |
   82|      0|    p->info = info;
   83|       |
   84|      0|    if (p->info.seek_fn && p->info.seek_fn(p->info.cookie, 0) >= 0) {
  ------------------
  |  Branch (84:9): [True: 0, False: 0]
  |  Branch (84:28): [True: 0, False: 0]
  ------------------
   85|      0|        stream->seek = seek;
   86|      0|        stream->seekable = true;
   87|      0|    }
   88|      0|    stream->fast_skip = true;
   89|      0|    stream->fill_buffer = fill_buffer;
   90|      0|    stream->get_size = get_size;
   91|      0|    stream->close = s_close;
   92|       |
   93|      0|    if (p->info.cancel_fn && stream->cancel) {
  ------------------
  |  Branch (93:9): [True: 0, False: 0]
  |  Branch (93:30): [True: 0, False: 0]
  ------------------
   94|      0|        p->cancel = mp_cancel_new(p);
   95|      0|        mp_cancel_set_parent(p->cancel, stream->cancel);
   96|      0|        mp_cancel_set_cb(p->cancel, p->info.cancel_fn, p->info.cookie);
   97|      0|    }
   98|       |
   99|      0|    return STREAM_OK;
  ------------------
  |  |   68|      0|#define STREAM_OK    1
  ------------------
  100|      0|}

mp_file_url_to_filename:
  176|  95.4k|{
  177|  95.4k|    bstr proto = mp_split_proto(url, &url);
  178|  95.4k|    if (bstrcasecmp0(proto, "file") != 0)
  ------------------
  |  Branch (178:9): [True: 95.4k, False: 0]
  ------------------
  179|  95.4k|        return NULL;
  180|      0|    char *filename = bstrto0(talloc_ctx, url);
  181|      0|    mp_url_unescape_inplace(filename);
  182|       |#if HAVE_DOS_PATHS
  183|       |    // extract '/' from '/x:/path'
  184|       |    if (filename[0] == '/' && filename[1] && filename[2] == ':')
  185|       |        memmove(filename, filename + 1, strlen(filename)); // including \0
  186|       |#endif
  187|      0|    return filename;
  188|  95.4k|}
stream_file.c:open_f:
  277|    673|{
  278|    673|    struct priv *p = talloc_ptrtype(stream, p);
  ------------------
  |  |   34|    673|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|    673|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|    673|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  279|    673|    *p = (struct priv) {
  280|    673|        .fd = -1,
  281|    673|    };
  282|    673|    stream->priv = p;
  283|    673|    stream->is_local_fs = true;
  284|       |
  285|    673|    bool strict_fs = args->flags & STREAM_LOCAL_FS_ONLY;
  ------------------
  |  |   54|    673|#define STREAM_LOCAL_FS_ONLY      (1 << 5) // stream_file only, no URLs
  ------------------
  286|    673|    bool write = stream->mode == STREAM_WRITE;
  ------------------
  |  |   42|    673|#define STREAM_WRITE              (1 << 0)
  ------------------
  287|    673|    int m = O_CLOEXEC | (write ? O_RDWR | O_CREAT | O_TRUNC : O_RDONLY);
  ------------------
  |  Branch (287:26): [True: 0, False: 673]
  ------------------
  288|       |
  289|    673|    char *filename = stream->path;
  290|    673|    char *url = "";
  291|    673|    if (!strict_fs) {
  ------------------
  |  Branch (291:9): [True: 673, False: 0]
  ------------------
  292|    673|        char *fn = mp_file_url_to_filename(stream, bstr0(stream->url));
  293|    673|        if (fn)
  ------------------
  |  Branch (293:13): [True: 0, False: 673]
  ------------------
  294|      0|            filename = stream->path = fn;
  295|    673|        url = stream->url;
  296|    673|    }
  297|       |
  298|    673|    bool is_fdclose = strncmp(url, "fdclose://", 10) == 0;
  299|    673|    if (strncmp(url, "fd://", 5) == 0 || is_fdclose) {
  ------------------
  |  Branch (299:9): [True: 8, False: 665]
  |  Branch (299:42): [True: 0, False: 665]
  ------------------
  300|      8|        stream->is_local_fs = false;
  301|      8|        char *begin = strstr(stream->url, "://") + 3, *end = NULL;
  302|      8|        p->fd = strtol(begin, &end, 0);
  303|      8|        if (!end || end == begin || end[0] || p->fd < 0) {
  ------------------
  |  Branch (303:13): [True: 0, False: 8]
  |  Branch (303:21): [True: 8, False: 0]
  |  Branch (303:37): [True: 0, False: 0]
  |  Branch (303:47): [True: 0, False: 0]
  ------------------
  304|      8|            MP_ERR(stream, "Invalid FD number: %s\n", stream->url);
  ------------------
  |  |   85|      8|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      8|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  305|      8|            return STREAM_ERROR;
  ------------------
  |  |   67|      8|#define STREAM_ERROR 0
  ------------------
  306|      8|        }
  307|      0|#ifdef F_SETFD
  308|      0|        if (fcntl(p->fd, F_GETFD) == -1) {
  ------------------
  |  Branch (308:13): [True: 0, False: 0]
  ------------------
  309|      0|            MP_ERR(stream, "Invalid FD: %d\n", p->fd);
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  310|      0|            return STREAM_ERROR;
  ------------------
  |  |   67|      0|#define STREAM_ERROR 0
  ------------------
  311|      0|        }
  312|      0|#endif
  313|      0|        if (is_fdclose)
  ------------------
  |  Branch (313:13): [True: 0, False: 0]
  ------------------
  314|      0|            p->close = true;
  315|    665|    } else if (!strict_fs && !strcmp(filename, "-")) {
  ------------------
  |  Branch (315:16): [True: 665, False: 0]
  |  Branch (315:30): [True: 0, False: 665]
  ------------------
  316|      0|        stream->is_local_fs = false;
  317|      0|        if (!write) {
  ------------------
  |  Branch (317:13): [True: 0, False: 0]
  ------------------
  318|      0|            MP_INFO(stream, "Reading from stdin...\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  319|      0|            p->fd = 0;
  320|      0|        } else {
  321|      0|            MP_INFO(stream, "Writing to stdout...\n");
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  322|      0|            p->fd = 1;
  323|      0|        }
  324|    665|    } else {
  325|    665|        if (bstr_startswith0(bstr0(stream->url), "appending://"))
  ------------------
  |  Branch (325:13): [True: 0, False: 665]
  ------------------
  326|      0|            p->appending = true;
  327|       |
  328|    665|        mode_t openmode = S_IRUSR | S_IWUSR;
  329|    665|#ifndef __MINGW32__
  330|    665|        openmode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  331|    665|        if (!write)
  ------------------
  |  Branch (331:13): [True: 665, False: 0]
  ------------------
  332|    665|            m |= O_NONBLOCK;
  333|    665|#endif
  334|    665|        p->fd = open(filename, m | O_BINARY, openmode);
  ------------------
  |  |   66|    665|#define O_BINARY 0
  ------------------
  335|    665|        if (p->fd < 0) {
  ------------------
  |  Branch (335:13): [True: 663, False: 2]
  ------------------
  336|    663|            MP_ERR(stream, "Cannot open file '%s': %s\n",
  ------------------
  |  |   85|    663|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    663|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  337|    663|                   filename, mp_strerror(errno));
  338|    663|            return STREAM_ERROR;
  ------------------
  |  |   67|    663|#define STREAM_ERROR 0
  ------------------
  339|    663|        }
  340|      2|        p->close = true;
  341|      2|    }
  342|       |
  343|      2|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  344|      2|    if (p->fd != 42) {
  ------------------
  |  Branch (344:9): [True: 2, False: 0]
  ------------------
  345|      2|        s_close(stream);
  346|      2|        return STREAM_ERROR;
  ------------------
  |  |   67|      2|#define STREAM_ERROR 0
  ------------------
  347|      2|    }
  348|      0|#endif
  349|       |
  350|      0|    struct stat st;
  351|      0|    bool is_sock_or_fifo = false;
  352|      0|    if (fstat(p->fd, &st) == 0) {
  ------------------
  |  Branch (352:9): [True: 0, False: 0]
  ------------------
  353|      0|        if (S_ISDIR(st.st_mode)) {
  354|      0|            stream->is_directory = true;
  355|      0|        } else if (S_ISREG(st.st_mode)) {
  356|      0|            p->regular_file = true;
  357|      0|#ifndef _WIN32
  358|       |            // O_NONBLOCK has weird semantics on file locks; remove it.
  359|      0|            int val = fcntl(p->fd, F_GETFL) & ~(unsigned)O_NONBLOCK;
  360|      0|            fcntl(p->fd, F_SETFL, val);
  361|      0|#endif
  362|      0|        } else {
  363|      0|#ifndef __MINGW32__
  364|      0|            is_sock_or_fifo = S_ISSOCK(st.st_mode) || S_ISFIFO(st.st_mode);
  365|      0|#endif
  366|      0|            p->use_poll = true;
  367|      0|        }
  368|      0|    }
  369|       |
  370|       |#ifdef _WIN32
  371|       |    setmode(p->fd, O_BINARY);
  372|       |#endif
  373|       |
  374|      0|    off_t len = lseek(p->fd, 0, SEEK_END);
  375|      0|    lseek(p->fd, 0, SEEK_SET);
  376|      0|    if (len != (off_t)-1) {
  ------------------
  |  Branch (376:9): [True: 0, False: 0]
  ------------------
  377|      0|        stream->seek = seek;
  378|      0|        stream->seekable = true;
  379|      0|    }
  380|       |
  381|      0|    stream->fast_skip = true;
  382|      0|    stream->fill_buffer = fill_buffer;
  383|      0|    stream->write_buffer = write_buffer;
  384|      0|    stream->get_size = get_size;
  385|      0|    stream->close = s_close;
  386|       |
  387|      0|    if (is_sock_or_fifo || check_stream_network(p->fd)) {
  ------------------
  |  Branch (387:9): [True: 0, False: 0]
  |  Branch (387:28): [True: 0, False: 0]
  ------------------
  388|      0|        stream->streaming = true;
  389|       |#if HAVE_COCOA
  390|       |        if (fcntl(p->fd, F_RDAHEAD, 0) < 0) {
  391|       |            MP_VERBOSE(stream, "Cannot disable read ahead on file '%s': %s\n",
  392|       |                       filename, mp_strerror(errno));
  393|       |        }
  394|       |#endif
  395|      0|    }
  396|       |
  397|      0|    p->orig_size = get_size(stream);
  398|       |
  399|      0|    p->cancel = mp_cancel_new(p);
  400|      0|    if (stream->cancel)
  ------------------
  |  Branch (400:9): [True: 0, False: 0]
  ------------------
  401|      0|        mp_cancel_set_parent(p->cancel, stream->cancel);
  402|       |
  403|      0|    return STREAM_OK;
  ------------------
  |  |   68|      0|#define STREAM_OK    1
  ------------------
  404|      2|}
stream_file.c:s_close:
  168|      2|{
  169|      2|    struct priv *p = s->priv;
  170|      2|    if (p->close)
  ------------------
  |  Branch (170:9): [True: 2, False: 0]
  ------------------
  171|      2|        close(p->fd);
  172|      2|}

mp_setup_av_network_options:
  185|      1|{
  186|      1|    void *temp = talloc_new(NULL);
  ------------------
  |  |   40|      1|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      1|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  187|      1|    struct stream_lavf_params *opts =
  188|      1|        mp_get_config_group(temp, global, &stream_lavf_conf);
  189|       |
  190|       |    // HTTP specific options (other protocols ignore them)
  191|      1|    if (opts->useragent)
  ------------------
  |  Branch (191:9): [True: 1, False: 0]
  ------------------
  192|      1|        av_dict_set(dict, "user_agent", opts->useragent, 0);
  193|      1|    if (opts->cookies_enabled) {
  ------------------
  |  Branch (193:9): [True: 0, False: 1]
  ------------------
  194|      0|        char *file = opts->cookies_file;
  195|      0|        if (file && file[0])
  ------------------
  |  Branch (195:13): [True: 0, False: 0]
  |  Branch (195:21): [True: 0, False: 0]
  ------------------
  196|      0|            file = mp_get_user_path(temp, global, file);
  197|      0|        char *cookies = cookies_lavf(temp, global, log, file);
  198|      0|        if (cookies && cookies[0])
  ------------------
  |  Branch (198:13): [True: 0, False: 0]
  |  Branch (198:24): [True: 0, False: 0]
  ------------------
  199|      0|            av_dict_set(dict, "cookies", cookies, 0);
  200|      0|    }
  201|      1|    av_dict_set(dict, "tls_verify", opts->tls_verify ? "1" : "0", 0);
  ------------------
  |  Branch (201:37): [True: 0, False: 1]
  ------------------
  202|      1|    if (opts->tls_ca_file) {
  ------------------
  |  Branch (202:9): [True: 0, False: 1]
  ------------------
  203|      0|        char *file = mp_get_user_path(temp, global, opts->tls_ca_file);
  204|      0|        av_dict_set(dict, "ca_file", file, 0);
  205|      0|    }
  206|      1|    if (opts->tls_cert_file) {
  ------------------
  |  Branch (206:9): [True: 0, False: 1]
  ------------------
  207|      0|        char *file = mp_get_user_path(temp, global, opts->tls_cert_file);
  208|      0|        av_dict_set(dict, "cert_file", file, 0);
  209|      0|    }
  210|      1|    if (opts->tls_key_file) {
  ------------------
  |  Branch (210:9): [True: 0, False: 1]
  ------------------
  211|      0|        char *file = mp_get_user_path(temp, global, opts->tls_key_file);
  212|      0|        av_dict_set(dict, "key_file", file, 0);
  213|      0|    }
  214|      1|    char *cust_headers = talloc_strdup(temp, "");
  ------------------
  |  |   50|      1|#define talloc_strdup                   ta_xstrdup
  ------------------
  215|      1|    if (opts->referrer) {
  ------------------
  |  Branch (215:9): [True: 0, False: 1]
  ------------------
  216|      0|        cust_headers = talloc_asprintf_append(cust_headers, "Referer: %s\r\n",
  ------------------
  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  ------------------
  217|      0|                                              opts->referrer);
  218|      0|    }
  219|      1|    if (opts->http_header_fields) {
  ------------------
  |  Branch (219:9): [True: 0, False: 1]
  ------------------
  220|      0|        for (int n = 0; opts->http_header_fields[n]; n++) {
  ------------------
  |  Branch (220:25): [True: 0, False: 0]
  ------------------
  221|      0|            cust_headers = talloc_asprintf_append(cust_headers, "%s\r\n",
  ------------------
  |  |   63|      0|#define talloc_asprintf_append          ta_talloc_asprintf_append
  ------------------
  222|      0|                                                  opts->http_header_fields[n]);
  223|      0|        }
  224|      0|    }
  225|      1|    if (strlen(cust_headers))
  ------------------
  |  Branch (225:9): [True: 0, False: 1]
  ------------------
  226|      0|        av_dict_set(dict, "headers", cust_headers, 0);
  227|      1|    av_dict_set(dict, "icy", "1", 0);
  228|       |    // So far, every known protocol uses microseconds for this
  229|       |    // Except rtsp.
  230|      1|    if (opts->timeout > 0) {
  ------------------
  |  Branch (230:9): [True: 1, False: 0]
  ------------------
  231|      1|        if (target_fmt && strcmp(target_fmt, "rtsp") == 0) {
  ------------------
  |  Branch (231:13): [True: 0, False: 1]
  |  Branch (231:27): [True: 0, False: 0]
  ------------------
  232|      0|            mp_verbose(log, "Broken FFmpeg RTSP API => not setting timeout.\n");
  ------------------
  |  |   75|      0|#define mp_verbose(log, ...)    mp_msg(log, MSGL_V, __VA_ARGS__)
  ------------------
  233|      1|        } else {
  234|      1|            char buf[80];
  235|      1|            snprintf(buf, sizeof(buf), "%lld", (long long)(opts->timeout * 1e6));
  236|      1|            av_dict_set(dict, "timeout", buf, 0);
  237|      1|        }
  238|      1|    }
  239|      1|    if (opts->http_proxy && opts->http_proxy[0])
  ------------------
  |  Branch (239:9): [True: 0, False: 1]
  |  Branch (239:29): [True: 0, False: 0]
  ------------------
  240|      0|        av_dict_set(dict, "http_proxy", opts->http_proxy, 0);
  241|       |
  242|      1|    mp_set_avdict(dict, opts->avopts);
  243|       |
  244|      1|    talloc_free(temp);
  ------------------
  |  |   47|      1|#define talloc_free                     ta_free
  ------------------
  245|      1|}
stream_lavf.c:open_f:
  357|      1|{
  358|      1|    AVIOContext *avio = NULL;
  359|      1|    int res = STREAM_ERROR;
  ------------------
  |  |   67|      1|#define STREAM_ERROR 0
  ------------------
  360|      1|    AVDictionary *dict = NULL;
  361|      1|    void *temp = talloc_new(NULL);
  ------------------
  |  |   40|      1|#define talloc_new                      ta_xnew_context
  |  |  ------------------
  |  |  |  |  122|      1|#define ta_xnew_context(...)            ta_oom_p(ta_new_context(__VA_ARGS__))
  |  |  ------------------
  ------------------
  362|       |
  363|      1|    stream->seek = NULL;
  364|      1|    stream->seekable = false;
  365|       |
  366|      1|    int flags = stream->mode == STREAM_WRITE ? AVIO_FLAG_WRITE : AVIO_FLAG_READ;
  ------------------
  |  |   42|      1|#define STREAM_WRITE              (1 << 0)
  ------------------
  |  Branch (366:17): [True: 0, False: 1]
  ------------------
  367|       |
  368|      1|    const char *filename = stream->url;
  369|      1|    if (!filename) {
  ------------------
  |  Branch (369:9): [True: 0, False: 1]
  ------------------
  370|      0|        MP_ERR(stream, "No URL\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  371|      0|        goto out;
  372|      0|    }
  373|      3|    for (int i = 0; i < MP_ARRAY_SIZE(prefix); i++)
  ------------------
  |  |   48|      3|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (373:21): [True: 2, False: 1]
  ------------------
  374|      2|        if (!strncmp(filename, prefix[i], strlen(prefix[i])))
  ------------------
  |  Branch (374:13): [True: 1, False: 1]
  ------------------
  375|      1|            filename += strlen(prefix[i]);
  376|      1|    if (!strncmp(filename, "rtsp:", 5) || !strncmp(filename, "rtsps:", 6)) {
  ------------------
  |  Branch (376:9): [True: 0, False: 1]
  |  Branch (376:43): [True: 0, False: 1]
  ------------------
  377|       |        /* This is handled as a special demuxer, without a separate
  378|       |         * stream layer. demux_lavf will do all the real work. Note
  379|       |         * that libavformat doesn't even provide a protocol entry for
  380|       |         * this (the rtsp demuxer's probe function checks for a "rtsp:"
  381|       |         * filename prefix), so it has to be handled specially here.
  382|       |         */
  383|      0|        stream->demuxer = "lavf";
  384|      0|        stream->lavf_type = "rtsp";
  385|      0|        talloc_free(temp);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  386|      0|        return STREAM_OK;
  ------------------
  |  |   68|      0|#define STREAM_OK    1
  ------------------
  387|      0|    }
  388|       |
  389|       |    // Replace "mms://" with "mmsh://", so that most mms:// URLs just work.
  390|       |    // Replace "dav://" or "webdav://" with "http://" and "davs://" or "webdavs://" with "https://"
  391|      1|    bstr b_filename = bstr0(filename);
  392|      1|    if (bstr_eatstart0(&b_filename, "mms://") ||
  ------------------
  |  Branch (392:9): [True: 0, False: 1]
  ------------------
  393|      1|        bstr_eatstart0(&b_filename, "mmshttp://"))
  ------------------
  |  Branch (393:9): [True: 0, False: 1]
  ------------------
  394|      0|    {
  395|      0|        filename = talloc_asprintf(temp, "mmsh://%.*s", BSTR_P(b_filename));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  396|      1|    } else if (bstr_eatstart0(&b_filename, "dav://") || bstr_eatstart0(&b_filename, "webdav://"))
  ------------------
  |  Branch (396:16): [True: 0, False: 1]
  |  Branch (396:57): [True: 0, False: 1]
  ------------------
  397|      0|    {
  398|      0|        filename = talloc_asprintf(temp, "http://%.*s", BSTR_P(b_filename));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  399|      1|    } else if (bstr_eatstart0(&b_filename, "davs://") || bstr_eatstart0(&b_filename, "webdavs://"))
  ------------------
  |  Branch (399:16): [True: 0, False: 1]
  |  Branch (399:58): [True: 0, False: 1]
  ------------------
  400|      0|    {
  401|      0|        filename = talloc_asprintf(temp, "https://%.*s", BSTR_P(b_filename));
  ------------------
  |  |   52|      0|#define talloc_asprintf                 ta_xasprintf
  |  |  ------------------
  |  |  |  |  127|      0|#define ta_xasprintf(...)               ta_oom_s(ta_asprintf(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (127:62): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  402|      0|    }
  403|       |
  404|      1|    av_dict_set(&dict, "reconnect", "1", 0);
  405|      1|    av_dict_set(&dict, "reconnect_delay_max", "7", 0);
  406|       |
  407|      1|    mp_setup_av_network_options(&dict, NULL, stream->global, stream->log);
  408|       |
  409|      1|    AVIOInterruptCB cb = {
  410|      1|        .callback = interrupt_cb,
  411|      1|        .opaque = stream,
  412|      1|    };
  413|       |
  414|      1|    filename = normalize_url(stream, filename);
  415|       |
  416|      1|    if (strncmp(filename, "rtmp", 4) == 0) {
  ------------------
  |  Branch (416:9): [True: 1, False: 0]
  ------------------
  417|      1|        stream->demuxer = "lavf";
  418|      1|        stream->lavf_type = "flv";
  419|       |        // Setting timeout enables listen mode - force it to disabled.
  420|      1|        av_dict_set(&dict, "timeout", "0", 0);
  421|      1|    }
  422|       |
  423|      1|    int err = avio_open2(&avio, filename, flags, &cb, &dict);
  424|      1|    if (err < 0) {
  ------------------
  |  Branch (424:9): [True: 1, False: 0]
  ------------------
  425|      1|        if (err == AVERROR_PROTOCOL_NOT_FOUND)
  ------------------
  |  Branch (425:13): [True: 1, False: 0]
  ------------------
  426|      1|            MP_ERR(stream, "Protocol not found. Make sure"
  ------------------
  |  |   85|      1|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      1|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  427|      1|                   " FFmpeg is compiled with networking support.\n");
  428|      1|        goto out;
  429|      1|    }
  430|       |
  431|      0|    mp_avdict_print_unset(stream->log, MSGL_V, dict);
  432|       |
  433|      0|    if (avio->av_class) {
  ------------------
  |  Branch (433:9): [True: 0, False: 0]
  ------------------
  434|      0|        uint8_t *mt = NULL;
  435|      0|        if (av_opt_get(avio, "mime_type", AV_OPT_SEARCH_CHILDREN, &mt) >= 0) {
  ------------------
  |  Branch (435:13): [True: 0, False: 0]
  ------------------
  436|      0|            stream->mime_type = talloc_strdup(stream, mt);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  437|      0|            av_free(mt);
  438|      0|        }
  439|      0|    }
  440|       |
  441|      0|    stream->priv = avio;
  442|      0|    stream->seekable = avio->seekable & AVIO_SEEKABLE_NORMAL;
  443|      0|    stream->seek = stream->seekable ? seek : NULL;
  ------------------
  |  Branch (443:20): [True: 0, False: 0]
  ------------------
  444|      0|    stream->fill_buffer = fill_buffer;
  445|      0|    stream->write_buffer = write_buffer;
  446|      0|    stream->get_size = get_size;
  447|      0|    stream->control = control;
  448|      0|    stream->close = close_f;
  449|       |    // enable cache (should be avoided for files, but no way to detect this)
  450|      0|    stream->streaming = true;
  451|      0|    if (stream->info->stream_origin == STREAM_ORIGIN_NET)
  ------------------
  |  |   49|      0|#define STREAM_ORIGIN_NET         (3 << 2) // referenced from playlist on network
  ------------------
  |  Branch (451:9): [True: 0, False: 0]
  ------------------
  452|      0|        stream->is_network = true;
  453|      0|    res = STREAM_OK;
  ------------------
  |  |   68|      0|#define STREAM_OK    1
  ------------------
  454|       |
  455|      1|out:
  456|      1|    av_dict_free(&dict);
  457|      1|    talloc_free(temp);
  ------------------
  |  |   47|      1|#define talloc_free                     ta_free
  ------------------
  458|      1|    return res;
  459|      0|}
stream_lavf.c:normalize_url:
  345|      1|{
  346|      1|    bstr proto = mp_split_proto(bstr0(filename), NULL);
  347|      6|    for (int n = 0; http_like[n]; n++) {
  ------------------
  |  Branch (347:21): [True: 5, False: 1]
  ------------------
  348|      5|        if (bstr_equals0(proto, http_like[n]))
  ------------------
  |  Branch (348:13): [True: 0, False: 5]
  ------------------
  349|       |            // Escape everything but reserved characters.
  350|       |            // Also don't double-scape, so include '%'.
  351|      0|            return mp_url_escape(ta_parent, filename, ":/?#[]@!$&'()*+,;=%");
  352|      5|    }
  353|      1|    return (char *)filename;
  354|      1|}
stream_lavf.c:get_safe_protocols:
  275|     34|{
  276|     34|    int num = 0;
  277|     34|    char **protocols = NULL;
  278|     34|    char **ffmpeg_demuxers = mp_get_lavf_demuxers();
  279|     34|    char **ffmpeg_protos = mp_get_lavf_protocols();
  280|       |
  281|    408|    for (int i = 0; ffmpeg_protos[i]; i++) {
  ------------------
  |  Branch (281:21): [True: 374, False: 34]
  ------------------
  282|  7.17k|        for (int j = 0; safe_protos[j]; j++) {
  ------------------
  |  Branch (282:25): [True: 6.83k, False: 340]
  ------------------
  283|  6.83k|            if (strcmp(ffmpeg_protos[i], safe_protos[j][0]) != 0)
  ------------------
  |  Branch (283:17): [True: 6.80k, False: 34]
  ------------------
  284|  6.80k|                continue;
  285|     68|            for (int k = 0; safe_protos[j][k]; k++)
  ------------------
  |  Branch (285:29): [True: 34, False: 34]
  ------------------
  286|     34|                MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, safe_protos[j][k]));
  ------------------
  |  |  105|     68|    do {                                            \
  |  |  106|     34|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     34|    do {                                            \
  |  |  |  |   97|     34|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     34|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     34|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     34|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 34, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|     34|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|     34|    do {                                                        \
  |  |  |  |  |  |   89|     34|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|     34|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|     34|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|     34|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|     34|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|     34|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|     34|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     34|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     34|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     34|        (idxvar)++;                                 \
  |  |  109|     34|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  287|     34|            break;
  288|  6.83k|        }
  289|    374|    }
  290|       |
  291|       |    // rtsp is a demuxer not protocol in ffmpeg so it is handled separately
  292|  12.1k|    for (int i = 0; ffmpeg_demuxers[i]; i++) {
  ------------------
  |  Branch (292:21): [True: 12.0k, False: 34]
  ------------------
  293|  12.0k|        if (strcmp("rtsp", ffmpeg_demuxers[i]) == 0) {
  ------------------
  |  Branch (293:13): [True: 0, False: 12.0k]
  ------------------
  294|      0|            MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "rtsp"));
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  295|      0|            MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "rtsps"));
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  296|      0|            break;
  297|      0|        }
  298|  12.0k|    }
  299|       |
  300|     34|    MP_TARRAY_APPEND(NULL, protocols, num, NULL);
  ------------------
  |  |  105|     34|    do {                                            \
  |  |  106|     34|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     34|    do {                                            \
  |  |  |  |   97|     34|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     34|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     34|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     34|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 34]
  |  |  |  |  ------------------
  |  |  |  |   99|     34|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     34|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     34|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     34|        (idxvar)++;                                 \
  |  |  109|     34|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  301|       |
  302|     34|    talloc_free(ffmpeg_demuxers);
  ------------------
  |  |   47|     34|#define talloc_free                     ta_free
  ------------------
  303|     34|    talloc_free(ffmpeg_protos);
  ------------------
  |  |   47|     34|#define talloc_free                     ta_free
  ------------------
  304|       |
  305|     34|    return protocols;
  306|     34|}
stream_lavf.c:get_unsafe_protocols:
  309|     17|{
  310|     17|    int num = 0;
  311|     17|    char **protocols = NULL;
  312|     17|    char **safe_protocols = get_safe_protocols();
  313|     17|    char **ffmpeg_protos = mp_get_lavf_protocols();
  314|       |
  315|    204|    for (int i = 0; ffmpeg_protos[i]; i++) {
  ------------------
  |  Branch (315:21): [True: 187, False: 17]
  ------------------
  316|    187|        bool safe_protocol = false;
  317|    357|        for (int j = 0; safe_protocols[j]; j++) {
  ------------------
  |  Branch (317:25): [True: 187, False: 170]
  ------------------
  318|    187|            if (strcmp(ffmpeg_protos[i], safe_protocols[j]) == 0) {
  ------------------
  |  Branch (318:17): [True: 17, False: 170]
  ------------------
  319|     17|                safe_protocol = true;
  320|     17|                break;
  321|     17|            }
  322|    187|        }
  323|       |        // Skip to avoid name conflict with builtin mpv protocol.
  324|    187|        if (strcmp(ffmpeg_protos[i], "bluray") == 0 || strcmp(ffmpeg_protos[i], "dvd") == 0)
  ------------------
  |  Branch (324:13): [True: 0, False: 187]
  |  Branch (324:56): [True: 0, False: 187]
  ------------------
  325|      0|            continue;
  326|       |
  327|    187|        if (!safe_protocol)
  ------------------
  |  Branch (327:13): [True: 170, False: 17]
  ------------------
  328|    170|            MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, ffmpeg_protos[i]));
  ------------------
  |  |  105|    170|    do {                                            \
  |  |  106|    170|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|    170|    do {                                            \
  |  |  |  |   97|    170|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|    170|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|    170|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|    170|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 51, False: 119]
  |  |  |  |  ------------------
  |  |  |  |   99|    170|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|     51|    do {                                                        \
  |  |  |  |  |  |   89|     51|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|     51|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|     51|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|     51|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|     51|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|     51|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|     51|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|    170|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|    170|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|    170|        (idxvar)++;                                 \
  |  |  109|    170|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  329|    187|    }
  330|       |
  331|     17|    MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "ffmpeg"));
  ------------------
  |  |  105|     17|    do {                                            \
  |  |  106|     17|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     17|    do {                                            \
  |  |  |  |   97|     17|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     17|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     17|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     17|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 17]
  |  |  |  |  ------------------
  |  |  |  |   99|     17|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     17|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     17|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     17|        (idxvar)++;                                 \
  |  |  109|     17|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  332|     17|    MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "lavf"));
  ------------------
  |  |  105|     17|    do {                                            \
  |  |  106|     17|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     17|    do {                                            \
  |  |  |  |   97|     17|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     17|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     17|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     17|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 17]
  |  |  |  |  ------------------
  |  |  |  |   99|     17|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     17|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     17|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     17|        (idxvar)++;                                 \
  |  |  109|     17|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  333|       |
  334|     17|    MP_TARRAY_APPEND(NULL, protocols, num, NULL);
  ------------------
  |  |  105|     17|    do {                                            \
  |  |  106|     17|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|     17|    do {                                            \
  |  |  |  |   97|     17|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|     17|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|     17|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|     17|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 17]
  |  |  |  |  ------------------
  |  |  |  |   99|     17|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|     17|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|     17|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|     17|        (idxvar)++;                                 \
  |  |  109|     17|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  335|       |
  336|     17|    talloc_free(ffmpeg_protos);
  ------------------
  |  |   47|     17|#define talloc_free                     ta_free
  ------------------
  337|     17|    talloc_free(safe_protocols);
  ------------------
  |  |   47|     17|#define talloc_free                     ta_free
  ------------------
  338|     17|    return protocols;
  339|     17|}

stream_memory_open:
   85|  30.0k|{
   86|  30.0k|    mp_assert(len >= 0);
  ------------------
  |  |   41|  30.0k|#define mp_assert assert
  ------------------
   87|       |
   88|  30.0k|    struct stream_open_args sargs = {
   89|  30.0k|        .global = global,
   90|  30.0k|        .url = "memory://",
   91|  30.0k|        .flags = STREAM_READ | STREAM_SILENT | STREAM_ORIGIN_DIRECT,
  ------------------
  |  |   41|  30.0k|#define STREAM_READ               0
  ------------------
                      .flags = STREAM_READ | STREAM_SILENT | STREAM_ORIGIN_DIRECT,
  ------------------
  |  |   44|  30.0k|#define STREAM_SILENT             (1 << 1)
  ------------------
                      .flags = STREAM_READ | STREAM_SILENT | STREAM_ORIGIN_DIRECT,
  ------------------
  |  |   47|  30.0k|#define STREAM_ORIGIN_DIRECT      (1 << 2) // passed from cmdline or loadfile
  ------------------
   92|  30.0k|        .sinfo = &stream_info_memory,
   93|  30.0k|        .special_arg = &(bstr){data, len},
   94|  30.0k|    };
   95|       |
   96|  30.0k|    struct stream *s = NULL;
   97|  30.0k|    stream_create_with_args(&sargs, &s);
   98|  30.0k|    MP_HANDLE_OOM(s);
  ------------------
  |  |  176|  30.0k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|  30.0k|        void *oom_p_ = (x);     \
  |  |  178|  30.0k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 30.0k]
  |  |  ------------------
  |  |  179|  30.0k|            abort();            \
  |  |  180|  30.0k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   99|  30.0k|    return s;
  100|  30.0k|}
stream_memory.c:open2:
   48|  52.9k|{
   49|  52.9k|    stream->fill_buffer = fill_buffer;
   50|  52.9k|    stream->seek = seek;
   51|  52.9k|    stream->seekable = true;
   52|  52.9k|    stream->get_size = get_size;
   53|       |
   54|  52.9k|    struct priv *p = talloc_zero(stream, struct priv);
  ------------------
  |  |   27|  52.9k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  52.9k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  52.9k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   55|  52.9k|    stream->priv = p;
   56|       |
   57|       |    // Initial data
   58|  52.9k|    bstr data = bstr0(stream->url);
   59|  52.9k|    bool use_hex = bstr_eatstart0(&data, "hex://");
   60|  52.9k|    if (!use_hex)
  ------------------
  |  Branch (60:9): [True: 52.9k, False: 4]
  ------------------
   61|  52.9k|        bstr_eatstart0(&data, "memory://");
   62|       |
   63|  52.9k|    if (args->special_arg)
  ------------------
  |  Branch (63:9): [True: 30.0k, False: 22.8k]
  ------------------
   64|  30.0k|        data = *(bstr *)args->special_arg;
   65|       |
   66|  52.9k|    p->data = bstrdup(stream, data);
   67|       |
   68|  52.9k|    if (use_hex && !bstr_decode_hex(stream, p->data, &p->data)) {
  ------------------
  |  Branch (68:9): [True: 4, False: 52.9k]
  |  Branch (68:20): [True: 3, False: 1]
  ------------------
   69|      3|        MP_FATAL(stream, "Invalid data.\n");
  ------------------
  |  |   84|      3|#define MP_FATAL(obj, ...)      MP_MSG(obj, MSGL_FATAL, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      3|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
   70|      3|        return STREAM_ERROR;
  ------------------
  |  |   67|      3|#define STREAM_ERROR 0
  ------------------
   71|      3|    }
   72|       |
   73|  52.9k|    return STREAM_OK;
  ------------------
  |  |   68|  52.9k|#define STREAM_OK    1
  ------------------
   74|  52.9k|}
stream_memory.c:fill_buffer:
   26|   582k|{
   27|   582k|    struct priv *p = s->priv;
   28|   582k|    bstr data = p->data;
   29|   582k|    if (s->pos < 0 || s->pos > data.len)
  ------------------
  |  Branch (29:9): [True: 0, False: 582k]
  |  Branch (29:23): [True: 244k, False: 338k]
  ------------------
   30|   244k|        return 0;
   31|   338k|    len = MPMIN(len, data.len - s->pos);
  ------------------
  |  |   44|   338k|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 335k, False: 2.93k]
  |  |  ------------------
  ------------------
   32|   338k|    memcpy(buffer, data.start + s->pos, len);
   33|   338k|    return len;
   34|   582k|}
stream_memory.c:seek:
   37|  23.3k|{
   38|  23.3k|    return 1;
   39|  23.3k|}
stream_memory.c:get_size:
   42|   124k|{
   43|   124k|    struct priv *p = s->priv;
   44|   124k|    return p->data.len;
   45|   124k|}

stream_null.c:open_s:
   26|     81|{
   27|     81|    return 1;
   28|     81|}

osd_create:
  158|  5.81k|{
  159|  5.81k|    static_assert(MAX_OSD_PARTS >= OSDTYPE_COUNT, "");
  160|       |
  161|  5.81k|    struct osd_state *osd = talloc_zero(NULL, struct osd_state);
  ------------------
  |  |   27|  5.81k|#define talloc_zero                     ta_xznew
  |  |  ------------------
  |  |  |  |  134|  5.81k|#define ta_xznew(...)                   ta_oom_g(ta_znew(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  5.81k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  162|  5.81k|    *osd = (struct osd_state) {
  163|  5.81k|        .opts_cache = m_config_cache_alloc(osd, global, &mp_osd_render_sub_opts),
  164|  5.81k|        .global = global,
  165|  5.81k|        .log = mp_log_new(osd, global->log, "osd"),
  166|  5.81k|        .force_video_pts = MP_NOPTS_VALUE,
  ------------------
  |  |   38|  5.81k|#define MP_NOPTS_VALUE (-0x1p+63)
  ------------------
  167|  5.81k|        .stats = stats_ctx_create(osd, global, "osd"),
  168|  5.81k|    };
  169|  5.81k|    mp_mutex_init(&osd->lock);
  170|  5.81k|    osd->opts = osd->opts_cache->opts;
  171|       |
  172|  34.8k|    for (int n = 0; n < MAX_OSD_PARTS; n++) {
  ------------------
  |  |  109|  34.8k|#define MAX_OSD_PARTS 5
  ------------------
  |  Branch (172:21): [True: 29.0k, False: 5.81k]
  ------------------
  173|  29.0k|        struct osd_object *obj = talloc(osd, struct osd_object);
  ------------------
  |  |   26|  29.0k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  29.0k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  29.0k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  174|  29.0k|        *obj = (struct osd_object) {
  175|  29.0k|            .type = n,
  176|  29.0k|            .text = talloc_strdup(obj, ""),
  ------------------
  |  |   50|  29.0k|#define talloc_strdup                   ta_xstrdup
  ------------------
  177|  29.0k|            .progbar_state = {.type = -1},
  178|  29.0k|            .vo_change_id = 1,
  179|  29.0k|        };
  180|  29.0k|        osd->objs[n] = obj;
  181|  29.0k|    }
  182|       |
  183|  5.81k|    osd->objs[OSDTYPE_SUB]->is_sub = true;
  184|  5.81k|    osd->objs[OSDTYPE_SUB2]->is_sub = true;
  185|       |
  186|  5.81k|    return osd;
  187|  5.81k|}
osd_free:
  190|  5.81k|{
  191|  5.81k|    if (!osd)
  ------------------
  |  Branch (191:9): [True: 0, False: 5.81k]
  ------------------
  192|      0|        return;
  193|  5.81k|    osd_destroy_backend(osd);
  194|  5.81k|    talloc_free(osd->objs[OSDTYPE_EXTERNAL2]->external2);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  195|  5.81k|    mp_mutex_destroy(&osd->lock);
  ------------------
  |  |  130|  5.81k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  196|  5.81k|    talloc_free(osd);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  197|  5.81k|}
osd_set_text:
  200|    398|{
  201|    398|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|    398|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  202|    398|    struct osd_object *osd_obj = osd->objs[OSDTYPE_OSD];
  203|    398|    if (!text)
  ------------------
  |  Branch (203:9): [True: 398, False: 0]
  ------------------
  204|    398|        text = "";
  205|    398|    if (strcmp(osd_obj->text, text) != 0) {
  ------------------
  |  Branch (205:9): [True: 0, False: 398]
  ------------------
  206|      0|        talloc_free(osd_obj->text);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  207|      0|        osd_obj->text = talloc_strdup(osd_obj, text);
  ------------------
  |  |   50|      0|#define talloc_strdup                   ta_xstrdup
  ------------------
  208|      0|        osd_obj->osd_changed = true;
  209|      0|        osd->want_redraw_notification = true;
  210|      0|    }
  211|    398|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|    398|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  212|    398|}
osd_get_render_subs_in_filter:
  227|  71.9k|{
  228|  71.9k|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|  71.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  229|  71.9k|    bool r = osd->render_subs_in_filter;
  230|  71.9k|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|  71.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  231|  71.9k|    return r;
  232|  71.9k|}
osd_set_force_video_pts:
  250|  72.3k|{
  251|  72.3k|    atomic_store(&osd->force_video_pts, video_pts);
  252|  72.3k|}
osd_set_external2:
  277|  5.81k|{
  278|  5.81k|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  279|  5.81k|    struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL2];
  280|  5.81k|    talloc_free(obj->external2);
  ------------------
  |  |   47|  5.81k|#define talloc_free                     ta_free
  ------------------
  281|  5.81k|    obj->external2 = sub_bitmaps_copy(NULL, imgs);
  282|  5.81k|    obj->vo_change_id += 1;
  283|  5.81k|    osd->want_redraw_notification = true;
  284|  5.81k|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  285|  5.81k|}
osd_changed:
  504|  5.81k|{
  505|  5.81k|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  506|  5.81k|    osd->objs[OSDTYPE_OSD]->osd_changed = true;
  507|  5.81k|    osd->want_redraw_notification = true;
  508|       |    // Done here for a lack of a better place.
  509|  5.81k|    m_config_cache_update(osd->opts_cache);
  510|  5.81k|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  511|  5.81k|}
osd_query_and_reset_want_redraw:
  514|    988|{
  515|    988|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|    988|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  516|    988|    bool r = osd->want_redraw_notification;
  517|    988|    osd->want_redraw_notification = false;
  518|    988|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|    988|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  519|    988|    return r;
  520|    988|}
sub_bitmaps_copy:
  581|  5.81k|{
  582|  5.81k|    if (!in || !in->num_parts)
  ------------------
  |  Branch (582:9): [True: 5.81k, False: 0]
  |  Branch (582:16): [True: 0, False: 0]
  ------------------
  583|  5.81k|        return NULL;
  584|       |
  585|      0|    struct sub_bitmaps *res = talloc(NULL, struct sub_bitmaps);
  ------------------
  |  |   26|      0|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|      0|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|      0|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  586|      0|    *res = *in;
  587|       |
  588|       |    // Note: the p_cache thing is a lie and unused.
  589|       |
  590|       |    // The bitmaps being refcounted is essential for performance, and for
  591|       |    // not invalidating in->parts[*].bitmap pointers.
  592|      0|    mp_assert(in->packed && in->packed->bufs[0]);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  593|       |
  594|      0|    res->packed = mp_image_new_ref(res->packed);
  595|      0|    talloc_steal(res, res->packed);
  ------------------
  |  |   38|      0|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|      0|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  596|       |
  597|      0|    res->parts = NULL;
  598|      0|    MP_RESIZE_ARRAY(res, res->parts, res->num_parts);
  ------------------
  |  |   88|      0|    do {                                                        \
  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  ------------------
  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |   91|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  599|      0|    memcpy(res->parts, in->parts, sizeof(res->parts[0]) * res->num_parts);
  600|       |
  601|      0|    return res;
  602|      0|}

osd_destroy_backend:
   85|  5.81k|{
   86|  34.8k|    for (int n = 0; n < MAX_OSD_PARTS; n++) {
  ------------------
  |  |  109|  34.8k|#define MAX_OSD_PARTS 5
  ------------------
  |  Branch (86:21): [True: 29.0k, False: 5.81k]
  ------------------
   87|  29.0k|        struct osd_object *obj = osd->objs[n];
   88|  29.0k|        destroy_ass_renderer(&obj->ass);
   89|  29.0k|        for (int i = 0; i < obj->num_externals; i++)
  ------------------
  |  Branch (89:25): [True: 0, False: 29.0k]
  ------------------
   90|      0|            destroy_external(obj->externals[i]);
   91|  29.0k|        obj->num_externals = 0;
   92|  29.0k|    }
   93|  5.81k|}
osd_set_external_remove_owner:
  646|  5.81k|{
  647|  5.81k|    mp_mutex_lock(&osd->lock);
  ------------------
  |  |  131|  5.81k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  648|  5.81k|    struct osd_object *obj = osd->objs[OSDTYPE_EXTERNAL];
  649|  5.81k|    for (int n = obj->num_externals - 1; n >= 0; n--) {
  ------------------
  |  Branch (649:42): [True: 0, False: 5.81k]
  ------------------
  650|      0|        struct osd_external *e = obj->externals[n];
  651|      0|        if (e->ov.owner == owner) {
  ------------------
  |  Branch (651:13): [True: 0, False: 0]
  ------------------
  652|      0|            destroy_external(e);
  653|      0|            MP_TARRAY_REMOVE_AT(obj->externals, obj->num_externals, n);
  ------------------
  |  |  143|      0|    do {                                            \
  |  |  144|      0|        size_t at_ = (at);                          \
  |  |  145|      0|        assert(at_ <= (idxvar));                    \
  |  |  146|      0|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|      0|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|      0|        (idxvar)--;                                 \
  |  |  149|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  654|      0|            obj->changed = true;
  655|      0|            osd->want_redraw_notification = true;
  656|      0|        }
  657|      0|    }
  658|  5.81k|    mp_mutex_unlock(&osd->lock);
  ------------------
  |  |  133|  5.81k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  659|  5.81k|}
osd_libass.c:destroy_ass_renderer:
   64|  29.0k|{
   65|  29.0k|    if (ass->track)
  ------------------
  |  Branch (65:9): [True: 0, False: 29.0k]
  ------------------
   66|      0|        ass_free_track(ass->track);
   67|  29.0k|    ass->track = NULL;
   68|  29.0k|    if (ass->render)
  ------------------
  |  Branch (68:9): [True: 0, False: 29.0k]
  ------------------
   69|      0|        ass_renderer_done(ass->render);
   70|  29.0k|    ass->render = NULL;
   71|  29.0k|    if (ass->library)
  ------------------
  |  Branch (71:9): [True: 0, False: 29.0k]
  ------------------
   72|      0|        ass_library_done(ass->library);
   73|  29.0k|    ass->library = NULL;
   74|  29.0k|    talloc_free(ass->log);
  ------------------
  |  |   47|  29.0k|#define talloc_free                     ta_free
  ------------------
   75|  29.0k|    ass->log = NULL;
   76|  29.0k|}

ta_set_parent:
   88|   189M|{
   89|   189M|    struct ta_header *ch = get_header(ptr);
   90|   189M|    if (!ch)
  ------------------
  |  Branch (90:9): [True: 145k, False: 189M]
  ------------------
   91|   145k|        return;
   92|   189M|    struct ta_header *new_parent = get_header(ta_parent);
   93|       |    // Unlink from previous parent
   94|   189M|    if (ch->prev)
  ------------------
  |  Branch (94:9): [True: 237k, False: 189M]
  ------------------
   95|   237k|        ch->prev->next = ch->next;
   96|   189M|    if (ch->next)
  ------------------
  |  Branch (96:9): [True: 29.2M, False: 160M]
  ------------------
   97|  29.2M|        ch->next->prev = ch->prev;
   98|       |    // If ch was the first child, change child link of old parent
   99|   189M|    if (ch->parent) {
  ------------------
  |  Branch (99:9): [True: 41.4M, False: 148M]
  ------------------
  100|  41.4M|        assert(ch->parent->child == ch);
  101|  41.4M|        ch->parent->child = ch->next;
  102|  41.4M|        if (ch->parent->child) {
  ------------------
  |  Branch (102:13): [True: 29.0M, False: 12.3M]
  ------------------
  103|  29.0M|            assert(!ch->parent->child->parent);
  104|  29.0M|            ch->parent->child->parent = ch->parent;
  105|  29.0M|        }
  106|  41.4M|    }
  107|   189M|    ch->next = ch->prev = ch->parent = NULL;
  108|       |    // Link to new parent - insert at start of list (LIFO destructor order)
  109|   189M|    if (new_parent) {
  ------------------
  |  Branch (109:9): [True: 41.6M, False: 148M]
  ------------------
  110|  41.6M|        ch->next = new_parent->child;
  111|  41.6M|        if (ch->next) {
  ------------------
  |  Branch (111:13): [True: 29.2M, False: 12.3M]
  ------------------
  112|  29.2M|            ch->next->prev = ch;
  113|  29.2M|            ch->next->parent = NULL;
  114|  29.2M|        }
  115|  41.6M|        new_parent->child = ch;
  116|  41.6M|        ch->parent = new_parent;
  117|  41.6M|    }
  118|   189M|}
ta_alloc_size:
  136|  61.6M|{
  137|  61.6M|    if (size >= MAX_ALLOC)
  ------------------
  |  |   66|  61.6M|#define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header))
  ------------------
  |  Branch (137:9): [True: 0, False: 61.6M]
  ------------------
  138|      0|        return NULL;
  139|  61.6M|    struct ta_header *h = malloc(sizeof(union aligned_header) + size);
  140|  61.6M|    if (!h)
  ------------------
  |  Branch (140:9): [True: 0, False: 61.6M]
  ------------------
  141|      0|        return NULL;
  142|  61.6M|    *h = (struct ta_header) {.size = size};
  143|  61.6M|    ta_dbg_add(h);
  144|  61.6M|    void *ptr = PTR_FROM_HEADER(h);
  ------------------
  |  |   64|  61.6M|#define PTR_FROM_HEADER(h) ((void *)((union aligned_header *)(h) + 1))
  ------------------
  145|  61.6M|    ta_set_parent(ptr, ta_parent);
  146|  61.6M|    return ptr;
  147|  61.6M|}
ta_zalloc_size:
  153|  10.3M|{
  154|  10.3M|    if (size >= MAX_ALLOC)
  ------------------
  |  |   66|  10.3M|#define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header))
  ------------------
  |  Branch (154:9): [True: 0, False: 10.3M]
  ------------------
  155|      0|        return NULL;
  156|  10.3M|    struct ta_header *h = calloc(1, sizeof(union aligned_header) + size);
  157|  10.3M|    if (!h)
  ------------------
  |  Branch (157:9): [True: 0, False: 10.3M]
  ------------------
  158|      0|        return NULL;
  159|  10.3M|    *h = (struct ta_header) {.size = size};
  160|  10.3M|    ta_dbg_add(h);
  161|  10.3M|    void *ptr = PTR_FROM_HEADER(h);
  ------------------
  |  |   64|  10.3M|#define PTR_FROM_HEADER(h) ((void *)((union aligned_header *)(h) + 1))
  ------------------
  162|  10.3M|    ta_set_parent(ptr, ta_parent);
  163|  10.3M|    return ptr;
  164|  10.3M|}
ta_realloc_size:
  179|  52.4M|{
  180|  52.4M|    if (size >= MAX_ALLOC)
  ------------------
  |  |   66|  52.4M|#define MAX_ALLOC (((size_t)-1) - sizeof(union aligned_header))
  ------------------
  |  Branch (180:9): [True: 0, False: 52.4M]
  ------------------
  181|      0|        return NULL;
  182|  52.4M|    if (!size) {
  ------------------
  |  Branch (182:9): [True: 42.6k, False: 52.3M]
  ------------------
  183|  42.6k|        ta_free(ptr);
  184|  42.6k|        return NULL;
  185|  42.6k|    }
  186|  52.3M|    if (!ptr)
  ------------------
  |  Branch (186:9): [True: 48.1M, False: 4.28M]
  ------------------
  187|  48.1M|        return ta_alloc_size(ta_parent, size);
  188|  4.28M|    struct ta_header *h = get_header(ptr);
  189|  4.28M|    struct ta_header *old_h = h;
  190|  4.28M|    if (h->size == size)
  ------------------
  |  Branch (190:9): [True: 1.30k, False: 4.28M]
  ------------------
  191|  1.30k|        return ptr;
  192|  4.28M|    ta_dbg_remove(h);
  193|  4.28M|    h = realloc(h, sizeof(union aligned_header) + size);
  194|  18.4E|    ta_dbg_add(h ? h : old_h);
  ------------------
  |  Branch (194:16): [True: 4.28M, False: 18.4E]
  ------------------
  195|  4.28M|    if (!h)
  ------------------
  |  Branch (195:9): [True: 0, False: 4.28M]
  ------------------
  196|      0|        return NULL;
  197|  4.28M|    h->size = size;
  198|  4.28M|    if (h != old_h) {
  ------------------
  |  Branch (198:9): [True: 1.83M, False: 2.44M]
  ------------------
  199|       |        // Relink parent
  200|  1.83M|        if (h->parent)
  ------------------
  |  Branch (200:13): [True: 580k, False: 1.25M]
  ------------------
  201|   580k|            h->parent->child = h;
  202|       |        // Relink siblings
  203|  1.83M|        if (h->next)
  ------------------
  |  Branch (203:13): [True: 729k, False: 1.10M]
  ------------------
  204|   729k|            h->next->prev = h;
  205|  1.83M|        if (h->prev)
  ------------------
  |  Branch (205:13): [True: 605k, False: 1.22M]
  ------------------
  206|   605k|            h->prev->next = h;
  207|       |        // Relink children
  208|  1.83M|        if (h->child)
  ------------------
  |  Branch (208:13): [True: 36.2k, False: 1.79M]
  ------------------
  209|  36.2k|            h->child->parent = h;
  210|  1.83M|    }
  211|  4.28M|    return PTR_FROM_HEADER(h);
  ------------------
  |  |   64|  4.28M|#define PTR_FROM_HEADER(h) ((void *)((union aligned_header *)(h) + 1))
  ------------------
  212|  4.28M|}
ta_get_size:
  219|   260M|{
  220|   260M|    struct ta_header *h = get_header(ptr);
  221|   260M|    return h ? h->size : 0;
  ------------------
  |  Branch (221:12): [True: 168M, False: 92.5M]
  ------------------
  222|   260M|}
ta_free_children:
  228|  75.6M|{
  229|  75.6M|    struct ta_header *h = get_header(ptr);
  230|   116M|    while (h && h->child)
  ------------------
  |  Branch (230:12): [True: 116M, False: 1.91k]
  |  Branch (230:17): [True: 41.0M, False: 75.6M]
  ------------------
  231|  41.0M|        ta_free(PTR_FROM_HEADER(h->child));
  ------------------
  |  |   64|  41.0M|#define PTR_FROM_HEADER(h) ((void *)((union aligned_header *)(h) + 1))
  ------------------
  232|  75.6M|}
ta_free:
  237|  85.3M|{
  238|  85.3M|    struct ta_header *h = get_header(ptr);
  239|  85.3M|    if (!h)
  ------------------
  |  Branch (239:9): [True: 13.3M, False: 72.0M]
  ------------------
  240|  13.3M|        return;
  241|  72.0M|    if (h->destructor)
  ------------------
  |  Branch (241:9): [True: 8.43M, False: 63.5M]
  ------------------
  242|  8.43M|        h->destructor(ptr);
  243|  72.0M|    ta_free_children(ptr);
  244|  72.0M|    ta_set_parent(ptr, NULL);
  245|  72.0M|    ta_dbg_remove(h);
  246|  72.0M|    free(h);
  247|  72.0M|}
ta_set_destructor:
  260|  11.1M|{
  261|  11.1M|    struct ta_header *h = get_header(ptr);
  262|  11.1M|    if (h)
  ------------------
  |  Branch (262:9): [True: 11.1M, False: 21]
  ------------------
  263|  11.1M|        h->destructor = destructor;
  264|  11.1M|}
ta_dbg_set_loc:
  379|  75.2M|{
  380|  75.2M|    struct ta_header *h = get_header(ptr);
  381|  75.2M|    if (h)
  ------------------
  |  Branch (381:9): [True: 74.9M, False: 372k]
  ------------------
  382|  74.9M|        h->name = loc;
  383|  75.2M|    return ptr;
  384|  75.2M|}
ta_dbg_mark_as_string:
  389|  46.5M|{
  390|       |    // Specially handled by leak report code.
  391|  46.5M|    return ta_dbg_set_loc(ptr, &allocation_is_string);
  392|  46.5M|}
ta.c:get_header:
   73|   892M|{
   74|   892M|    struct ta_header *h = ptr ? PTR_TO_HEADER(ptr) : NULL;
  ------------------
  |  |   63|   637M|#define PTR_TO_HEADER(ptr) (&((union aligned_header *)(ptr) - 1)->ta)
  ------------------
  |  Branch (74:27): [True: 637M, False: 254M]
  ------------------
   75|   892M|    ta_dbg_check_header(h);
   76|   892M|    return h;
   77|   892M|}
ta.c:ta_dbg_check_header:
  289|   968M|{
  290|   968M|    if (h) {
  ------------------
  |  Branch (290:9): [True: 714M, False: 254M]
  ------------------
  291|   714M|        assert(h->canary == CANARY);
  292|   714M|        if (h->parent) {
  ------------------
  |  Branch (292:13): [True: 201M, False: 512M]
  ------------------
  293|   201M|            assert(!h->prev);
  294|   201M|            assert(h->parent->child == h);
  295|   201M|        }
  296|   714M|    }
  297|   968M|}
ta.c:ta_dbg_add:
  276|  76.3M|{
  277|  76.3M|    h->canary = CANARY;
  ------------------
  |  |   50|  76.3M|#define CANARY 0xD3ADB3EF
  ------------------
  278|  76.3M|    if (enable_leak_check) {
  ------------------
  |  Branch (278:9): [True: 0, False: 76.3M]
  ------------------
  279|      0|        mp_mutex_lock(&ta_dbg_mutex);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  280|      0|        h->leak_next = &leak_node;
  281|      0|        h->leak_prev = leak_node.leak_prev;
  282|      0|        leak_node.leak_prev->leak_next = h;
  283|      0|        leak_node.leak_prev = h;
  284|      0|        mp_mutex_unlock(&ta_dbg_mutex);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  285|      0|    }
  286|  76.3M|}
ta.c:ta_dbg_remove:
  300|  76.3M|{
  301|  76.3M|    ta_dbg_check_header(h);
  302|  76.3M|    if (h->leak_next) { // assume checking for !=NULL invariant ok without lock
  ------------------
  |  Branch (302:9): [True: 0, False: 76.3M]
  ------------------
  303|      0|        mp_mutex_lock(&ta_dbg_mutex);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  304|      0|        h->leak_next->leak_prev = h->leak_prev;
  305|      0|        h->leak_prev->leak_next = h->leak_next;
  306|      0|        mp_mutex_unlock(&ta_dbg_mutex);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  307|      0|        h->leak_next = h->leak_prev = NULL;
  308|      0|    }
  309|  76.3M|    h->canary = 0;
  310|  76.3M|}

client.c:ta_oom_p:
  162|  23.2k|{
  163|  23.2k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 23.2k]
  ------------------
  164|      0|        abort();
  165|  23.2k|    return p;
  166|  23.2k|}
command.c:ta_oom_p:
  162|  29.0k|{
  163|  29.0k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 29.0k]
  ------------------
  164|      0|        abort();
  165|  29.0k|    return p;
  166|  29.0k|}
configfiles.c:ta_oom_p:
  162|   101k|{
  163|   101k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 101k]
  ------------------
  164|      0|        abort();
  165|   101k|    return p;
  166|   101k|}
external_files.c:ta_oom_p:
  162|  9.07k|{
  163|  9.07k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 9.07k]
  ------------------
  164|      0|        abort();
  165|  9.07k|    return p;
  166|  9.07k|}
loadfile.c:ta_oom_p:
  162|  33.1k|{
  163|  33.1k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 33.1k]
  ------------------
  164|      0|        abort();
  165|  33.1k|    return p;
  166|  33.1k|}
main.c:ta_oom_p:
  162|  17.4k|{
  163|  17.4k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 17.4k]
  ------------------
  164|      0|        abort();
  165|  17.4k|    return p;
  166|  17.4k|}
osd.c:ta_oom_b:
  169|  73.5k|{
  170|  73.5k|    if (!b)
  ------------------
  |  Branch (170:9): [True: 0, False: 73.5k]
  ------------------
  171|      0|        abort();
  172|  73.5k|}
osd.c:ta_oom_p:
  162|  34.8k|{
  163|  34.8k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 34.8k]
  ------------------
  164|      0|        abort();
  165|  34.8k|    return p;
  166|  34.8k|}
screenshot.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
scripting.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
video.c:ta_oom_p:
  162|  2.93k|{
  163|  2.93k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 2.93k]
  ------------------
  164|      0|        abort();
  165|  2.93k|    return p;
  166|  2.93k|}
clipboard.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
clipboard-vo.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
stream.c:ta_oom_p:
  162|  53.7k|{
  163|  53.7k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 53.7k]
  ------------------
  164|      0|        abort();
  165|  53.7k|    return p;
  166|  53.7k|}
stream_cb.c:ta_oom_p:
  162|     17|{
  163|     17|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 17]
  ------------------
  164|      0|        abort();
  165|     17|    return p;
  166|     17|}
stream_file.c:ta_oom_p:
  162|    673|{
  163|    673|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 673]
  ------------------
  164|      0|        abort();
  165|    673|    return p;
  166|    673|}
stream_lavf.c:ta_oom_p:
  162|      2|{
  163|      2|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 2]
  ------------------
  164|      0|        abort();
  165|      2|    return p;
  166|      2|}
stream_memory.c:ta_oom_p:
  162|  52.9k|{
  163|  52.9k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 52.9k]
  ------------------
  164|      0|        abort();
  165|  52.9k|    return p;
  166|  52.9k|}
mp_image.c:ta_oom_p:
  162|   216k|{
  163|   216k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 216k]
  ------------------
  164|      0|        abort();
  165|   216k|    return p;
  166|   216k|}
mp_image_pool.c:ta_oom_p:
  162|  15.1k|{
  163|  15.1k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 15.1k]
  ------------------
  164|      0|        abort();
  165|  15.1k|    return p;
  166|  15.1k|}
vo.c:ta_oom_p:
  162|   203k|{
  163|   203k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 203k]
  ------------------
  164|      0|        abort();
  165|   203k|    return p;
  166|   203k|}
ta_talloc.c:ta_oom_b:
  169|  2.37M|{
  170|  2.37M|    if (!b)
  ------------------
  |  Branch (170:9): [True: 0, False: 2.37M]
  ------------------
  171|      0|        abort();
  172|  2.37M|}
ta_utils.c:ta_oom_b:
  169|  54.9M|{
  170|  54.9M|    if (!b)
  ------------------
  |  Branch (170:9): [True: 0, False: 54.9M]
  ------------------
  171|      0|        abort();
  172|  54.9M|}
ipc-unix.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
aframe.c:ta_oom_p:
  162|   413k|{
  163|   413k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 413k]
  ------------------
  164|      0|        abort();
  165|   413k|    return p;
  166|   413k|}
ao.c:ta_oom_p:
  162|  2.70k|{
  163|  2.70k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 2.70k]
  ------------------
  164|      0|        abort();
  165|  2.70k|    return p;
  166|  2.70k|}
buffer.c:ta_oom_p:
  162|  1.35k|{
  163|  1.35k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.35k]
  ------------------
  164|      0|        abort();
  165|  1.35k|    return p;
  166|  1.35k|}
codecs.c:ta_oom_p:
  162|  10.4k|{
  163|  10.4k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 10.4k]
  ------------------
  164|      0|        abort();
  165|  10.4k|    return p;
  166|  10.4k|}
msg.c:ta_oom_p:
  162|  3.06M|{
  163|  3.06M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 3.06M]
  ------------------
  164|      0|        abort();
  165|  3.06M|    return p;
  166|  3.06M|}
msg.c:ta_oom_s:
  175|  54.7k|{
  176|  54.7k|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 54.7k]
  ------------------
  177|      0|        abort();
  178|  54.7k|    return s;
  179|  54.7k|}
playlist.c:ta_oom_p:
  162|  94.7k|{
  163|  94.7k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 94.7k]
  ------------------
  164|      0|        abort();
  165|  94.7k|    return p;
  166|  94.7k|}
stats.c:ta_oom_p:
  162|   245k|{
  163|   245k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 245k]
  ------------------
  164|      0|        abort();
  165|   245k|    return p;
  166|   245k|}
stats.c:ta_oom_s:
  175|  9.92k|{
  176|  9.92k|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 9.92k]
  ------------------
  177|      0|        abort();
  178|  9.92k|    return s;
  179|  9.92k|}
tags.c:ta_oom_p:
  162|  90.8k|{
  163|  90.8k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 90.8k]
  ------------------
  164|      0|        abort();
  165|  90.8k|    return p;
  166|  90.8k|}
demux.c:ta_oom_p:
  162|  1.02M|{
  163|  1.02M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.02M]
  ------------------
  164|      0|        abort();
  165|  1.02M|    return p;
  166|  1.02M|}
demux_cue.c:ta_oom_p:
  162|     55|{
  163|     55|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 55]
  ------------------
  164|      0|        abort();
  165|     55|    return p;
  166|     55|}
demux_disc.c:ta_oom_p:
  162|  25.0k|{
  163|  25.0k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 25.0k]
  ------------------
  164|      0|        abort();
  165|  25.0k|    return p;
  166|  25.0k|}
demux_edl.c:ta_oom_p:
  162|  98.0k|{
  163|  98.0k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 98.0k]
  ------------------
  164|      0|        abort();
  165|  98.0k|    return p;
  166|  98.0k|}
demux_lavf.c:ta_oom_p:
  162|  52.8k|{
  163|  52.8k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 52.8k]
  ------------------
  164|      0|        abort();
  165|  52.8k|    return p;
  166|  52.8k|}
demux_mf.c:ta_oom_p:
  162|  4.80k|{
  163|  4.80k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 4.80k]
  ------------------
  164|      0|        abort();
  165|  4.80k|    return p;
  166|  4.80k|}
demux_mkv.c:ta_oom_p:
  162|  24.4k|{
  163|  24.4k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 24.4k]
  ------------------
  164|      0|        abort();
  165|  24.4k|    return p;
  166|  24.4k|}
demux_playlist.c:ta_oom_p:
  162|  59.2k|{
  163|  59.2k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 59.2k]
  ------------------
  164|      0|        abort();
  165|  59.2k|    return p;
  166|  59.2k|}
demux_timeline.c:ta_oom_p:
  162|  64.3k|{
  163|  64.3k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 64.3k]
  ------------------
  164|      0|        abort();
  165|  64.3k|    return p;
  166|  64.3k|}
demux_timeline.c:ta_oom_s:
  175|    436|{
  176|    436|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 436]
  ------------------
  177|      0|        abort();
  178|    436|    return s;
  179|    436|}
ebml.c:ta_oom_p:
  162|     88|{
  163|     88|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 88]
  ------------------
  164|      0|        abort();
  165|     88|    return p;
  166|     88|}
packet.c:ta_oom_p:
  162|   126k|{
  163|   126k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 126k]
  ------------------
  164|      0|        abort();
  165|   126k|    return p;
  166|   126k|}
packet_pool.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
timeline.c:ta_oom_p:
  162|    573|{
  163|    573|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 573]
  ------------------
  164|      0|        abort();
  165|    573|    return p;
  166|    573|}
f_async_queue.c:ta_oom_p:
  162|  2.69k|{
  163|  2.69k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 2.69k]
  ------------------
  164|      0|        abort();
  165|  2.69k|    return p;
  166|  2.69k|}
f_decoder_wrapper.c:ta_oom_p:
  162|  10.4k|{
  163|  10.4k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 10.4k]
  ------------------
  164|      0|        abort();
  165|  10.4k|    return p;
  166|  10.4k|}
f_output_chain.c:ta_oom_p:
  162|  3.84k|{
  163|  3.84k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 3.84k]
  ------------------
  164|      0|        abort();
  165|  3.84k|    return p;
  166|  3.84k|}
filter.c:ta_oom_p:
  162|   824k|{
  163|   824k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 824k]
  ------------------
  164|      0|        abort();
  165|   824k|    return p;
  166|   824k|}
cmd.c:ta_oom_p:
  162|  2.51M|{
  163|  2.51M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 2.51M]
  ------------------
  164|      0|        abort();
  165|  2.51M|    return p;
  166|  2.51M|}
input.c:ta_oom_s:
  175|  1.26M|{
  176|  1.26M|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 1.26M]
  ------------------
  177|      0|        abort();
  178|  1.26M|    return s;
  179|  1.26M|}
input.c:ta_oom_p:
  162|  34.8k|{
  163|  34.8k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 34.8k]
  ------------------
  164|      0|        abort();
  165|  34.8k|    return p;
  166|  34.8k|}
bstr.c:ta_oom_p:
  162|      4|{
  163|      4|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 4]
  ------------------
  164|      0|        abort();
  165|      4|    return p;
  166|      4|}
charset_conv.c:ta_oom_p:
  162|   213k|{
  163|   213k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 213k]
  ------------------
  164|      0|        abort();
  165|   213k|    return p;
  166|   213k|}
dispatch.c:ta_oom_p:
  162|  59.5k|{
  163|  59.5k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 59.5k]
  ------------------
  164|      0|        abort();
  165|  59.5k|    return p;
  166|  59.5k|}
node.c:ta_oom_p:
  162|  17.4k|{
  163|  17.4k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 17.4k]
  ------------------
  164|      0|        abort();
  165|  17.4k|    return p;
  166|  17.4k|}
path_utils.c:ta_oom_s:
  175|  78.1k|{
  176|  78.1k|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 78.1k]
  ------------------
  177|      0|        abort();
  178|  78.1k|    return s;
  179|  78.1k|}
path_utils.c:ta_oom_p:
  162|  80.1k|{
  163|  80.1k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 80.1k]
  ------------------
  164|      0|        abort();
  165|  80.1k|    return p;
  166|  80.1k|}
thread_pool.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
thread_tools.c:ta_oom_p:
  162|  36.9k|{
  163|  36.9k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 36.9k]
  ------------------
  164|      0|        abort();
  165|  36.9k|    return p;
  166|  36.9k|}
m_config_core.c:ta_oom_p:
  162|  4.08M|{
  163|  4.08M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 4.08M]
  ------------------
  164|      0|        abort();
  165|  4.08M|    return p;
  166|  4.08M|}
m_config_frontend.c:ta_oom_p:
  162|  8.17M|{
  163|  8.17M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 8.17M]
  ------------------
  164|      0|        abort();
  165|  8.17M|    return p;
  166|  8.17M|}
m_option.c:ta_oom_s:
  175|  11.6k|{
  176|  11.6k|    if (!s)
  ------------------
  |  Branch (176:9): [True: 0, False: 11.6k]
  ------------------
  177|      0|        abort();
  178|  11.6k|    return s;
  179|  11.6k|}
m_option.c:ta_oom_p:
  162|  1.02M|{
  163|  1.02M|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.02M]
  ------------------
  164|      0|        abort();
  165|  1.02M|    return p;
  166|  1.02M|}
parse_configfile.c:ta_oom_p:
  162|  5.81k|{
  163|  5.81k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 5.81k]
  ------------------
  164|      0|        abort();
  165|  5.81k|    return p;
  166|  5.81k|}
path.c:ta_oom_p:
  162|   146k|{
  163|   146k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 146k]
  ------------------
  164|      0|        abort();
  165|   146k|    return p;
  166|   146k|}
audio.c:ta_oom_p:
  162|  1.95k|{
  163|  1.95k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.95k]
  ------------------
  164|      0|        abort();
  165|  1.95k|    return p;
  166|  1.95k|}
ad_spdif.c:ta_oom_p:
  162|  1.95k|{
  163|  1.95k|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.95k]
  ------------------
  164|      0|        abort();
  165|  1.95k|    return p;
  166|  1.95k|}
cue.c:ta_oom_p:
  162|    104|{
  163|    104|    if (!p)
  ------------------
  |  Branch (163:9): [True: 0, False: 104]
  ------------------
  164|      0|        abort();
  165|    104|    return p;
  166|    104|}

ta_talloc_strdup_append_buffer:
   30|   340k|{
   31|   340k|    ta_xstrdup_append_buffer(&s, a);
  ------------------
  |  |  124|   340k|#define ta_xstrdup_append_buffer(...)   ta_oom_b(ta_strdup_append_buffer(__VA_ARGS__))
  ------------------
   32|   340k|    return s;
   33|   340k|}
ta_talloc_strndup_append_buffer:
   42|   340k|{
   43|   340k|    ta_xstrndup_append_buffer(&s, a, n);
  ------------------
  |  |  126|   340k|#define ta_xstrndup_append_buffer(...)  ta_oom_b(ta_strndup_append_buffer(__VA_ARGS__))
  ------------------
   44|   340k|    return s;
   45|   340k|}
ta_talloc_vasprintf_append:
   48|  1.62M|{
   49|  1.62M|    ta_xvasprintf_append(&s, fmt, ap);
  ------------------
  |  |  130|  1.62M|#define ta_xvasprintf_append(...)       ta_oom_b(ta_vasprintf_append(__VA_ARGS__))
  ------------------
   50|  1.62M|    return s;
   51|  1.62M|}
ta_talloc_vasprintf_append_buffer:
   54|  68.6k|{
   55|  68.6k|    ta_xvasprintf_append_buffer(&s, fmt, ap);
  ------------------
  |  |  132|  68.6k|#define ta_xvasprintf_append_buffer(...) ta_oom_b(ta_vasprintf_append_buffer(__VA_ARGS__))
  ------------------
   56|  68.6k|    return s;
   57|  68.6k|}
ta_talloc_asprintf_append:
   60|  1.62M|{
   61|  1.62M|    char *res;
   62|  1.62M|    va_list ap;
   63|  1.62M|    va_start(ap, fmt);
   64|  1.62M|    res = talloc_vasprintf_append(s, fmt, ap);
  ------------------
  |  |   61|  1.62M|#define talloc_vasprintf_append         ta_talloc_vasprintf_append
  ------------------
   65|  1.62M|    va_end(ap);
   66|  1.62M|    return res;
   67|  1.62M|}
ta_talloc_asprintf_append_buffer:
   70|  68.6k|{
   71|  68.6k|    char *res;
   72|  68.6k|    va_list ap;
   73|  68.6k|    va_start(ap, fmt);
   74|  68.6k|    res = talloc_vasprintf_append_buffer(s, fmt, ap);
  ------------------
  |  |   62|  68.6k|#define talloc_vasprintf_append_buffer  ta_talloc_vasprintf_append_buffer
  ------------------
   75|  68.6k|    va_end(ap);
   76|  68.6k|    return res;
   77|  68.6k|}

ta_calc_array_size:
   30|  4.89M|{
   31|  4.89M|    if (count > (((size_t)-1) / element_size))
  ------------------
  |  Branch (31:9): [True: 0, False: 4.89M]
  ------------------
   32|      0|        return (size_t)-1;
   33|  4.89M|    return element_size * count;
   34|  4.89M|}
ta_calc_prealloc_elems:
   41|  3.10M|{
   42|  3.10M|    if (nextidx >= ((size_t)-1) / 2 - 1)
  ------------------
  |  Branch (42:9): [True: 0, False: 3.10M]
  ------------------
   43|      0|        return (size_t)-1;
   44|  3.10M|    return (nextidx + 1) * 2;
   45|  3.10M|}
ta_new_context:
   50|  1.49M|{
   51|  1.49M|    return ta_alloc_size(ta_parent, 0);
   52|  1.49M|}
ta_steal_:
   58|  1.10M|{
   59|  1.10M|    ta_set_parent(ptr, ta_parent);
   60|  1.10M|    return ptr;
   61|  1.10M|}
ta_memdup:
   66|   865k|{
   67|   865k|    if (!ptr) {
  ------------------
  |  Branch (67:9): [True: 330k, False: 535k]
  ------------------
   68|   330k|        assert(!size);
   69|   330k|        return NULL;
   70|   330k|    }
   71|   535k|    void *res = ta_alloc_size(ta_parent, size);
   72|   535k|    if (!res)
  ------------------
  |  Branch (72:9): [True: 0, False: 535k]
  ------------------
   73|      0|        return NULL;
   74|   535k|    memcpy(res, ptr, size);
   75|   535k|    return res;
   76|   535k|}
ta_strdup:
  113|  37.4M|{
  114|  37.4M|    return ta_strndup(ta_parent, str, str ? strlen(str) : 0);
  ------------------
  |  Branch (114:39): [True: 32.0M, False: 5.43M]
  ------------------
  115|  37.4M|}
ta_strndup:
  123|  48.2M|{
  124|  48.2M|    if (!str)
  ------------------
  |  Branch (124:9): [True: 5.53M, False: 42.7M]
  ------------------
  125|  5.53M|        return NULL;
  126|  42.7M|    char *new = NULL;
  127|  42.7M|    strndup_append_at(&new, 0, str, n);
  128|  42.7M|    ta_set_parent(new, ta_parent);
  129|  42.7M|    return new;
  130|  48.2M|}
ta_strdup_append:
  137|  73.5k|{
  138|  73.5k|    return strndup_append_at(str, *str ? strlen(*str) : 0, a, (size_t)-1);
  ------------------
  |  Branch (138:35): [True: 73.5k, False: 0]
  ------------------
  139|  73.5k|}
ta_strdup_append_buffer:
  145|   340k|{
  146|   340k|    size_t size = ta_get_size(*str);
  147|   340k|    if (size > 0)
  ------------------
  |  Branch (147:9): [True: 340k, False: 0]
  ------------------
  148|   340k|        size -= 1;
  149|   340k|    return strndup_append_at(str, size, a, (size_t)-1);
  150|   340k|}
ta_strndup_append_buffer:
  164|   340k|{
  165|   340k|    size_t size = ta_get_size(*str);
  166|   340k|    if (size > 0)
  ------------------
  |  Branch (166:9): [True: 340k, False: 0]
  ------------------
  167|   340k|        size -= 1;
  168|   340k|    return strndup_append_at(str, size, a, n);
  169|   340k|}
ta_asprintf:
  204|  1.41M|{
  205|  1.41M|    char *res;
  206|  1.41M|    va_list ap;
  207|  1.41M|    va_start(ap, fmt);
  208|  1.41M|    res = ta_vasprintf(ta_parent, fmt, ap);
  209|  1.41M|    va_end(ap);
  210|  1.41M|    return res;
  211|  1.41M|}
ta_vasprintf:
  214|  1.41M|{
  215|  1.41M|    char *res = NULL;
  216|  1.41M|    ta_vasprintf_append_at(&res, 0, fmt, ap);
  217|  1.41M|    ta_set_parent(res, ta_parent);
  218|  1.41M|    if (!res) {
  ------------------
  |  Branch (218:9): [True: 0, False: 1.41M]
  ------------------
  219|      0|        ta_free(res);
  220|      0|        return NULL;
  221|      0|    }
  222|  1.41M|    return res;
  223|  1.41M|}
ta_vasprintf_append:
  240|  1.62M|{
  241|  1.62M|    return ta_vasprintf_append_at(str, *str ? strlen(*str) : 0, fmt, ap);
  ------------------
  |  Branch (241:40): [True: 1.62M, False: 0]
  ------------------
  242|  1.62M|}
ta_vasprintf_append_buffer:
  262|  68.6k|{
  263|  68.6k|    size_t size = ta_get_size(*str);
  264|  68.6k|    if (size > 0)
  ------------------
  |  Branch (264:9): [True: 68.6k, False: 0]
  ------------------
  265|  68.6k|        size -= 1;
  266|  68.6k|    return ta_vasprintf_append_at(str, size, fmt, ap);
  267|  68.6k|}
ta_xmemdup:
  270|   736k|{
  271|   736k|    void *new = ta_memdup(ta_parent, ptr, size);
  272|   736k|    ta_oom_b(new || !ptr);
  ------------------
  |  Branch (272:14): [True: 406k, False: 330k]
  |  Branch (272:21): [True: 330k, False: 0]
  ------------------
  273|   736k|    return new;
  274|   736k|}
ta_xrealloc_size:
  277|  5.93M|{
  278|  5.93M|    ptr = ta_realloc_size(ta_parent, ptr, size);
  279|  5.93M|    ta_oom_b(ptr || !size);
  ------------------
  |  Branch (279:14): [True: 5.89M, False: 42.6k]
  |  Branch (279:21): [True: 42.6k, False: 0]
  ------------------
  280|  5.93M|    return ptr;
  281|  5.93M|}
ta_xstrdup:
  284|  37.4M|{
  285|  37.4M|    char *res = ta_strdup(ta_parent, str);
  286|  37.4M|    ta_oom_b(res || !str);
  ------------------
  |  Branch (286:14): [True: 32.0M, False: 5.43M]
  |  Branch (286:21): [True: 5.43M, False: 0]
  ------------------
  287|  37.4M|    return res;
  288|  37.4M|}
ta_xstrndup:
  291|  10.7M|{
  292|  10.7M|    char *res = ta_strndup(ta_parent, str, n);
  293|  10.7M|    ta_oom_b(res || !str);
  ------------------
  |  Branch (293:14): [True: 10.6M, False: 97.4k]
  |  Branch (293:21): [True: 97.4k, False: 0]
  ------------------
  294|  10.7M|    return res;
  295|  10.7M|}
ta_utils.c:strndup_append_at:
   82|  43.4M|{
   83|  43.4M|    assert(ta_get_size(*str) >= at);
   84|       |
   85|  43.4M|    if (!*str && !append)
  ------------------
  |  Branch (85:9): [True: 42.7M, False: 754k]
  |  Branch (85:18): [True: 0, False: 42.7M]
  ------------------
   86|      0|        return true; // stays NULL, but not an OOM condition
   87|       |
   88|  18.4E|    size_t real_len = append ? strnlen(append, append_len) : 0;
  ------------------
  |  Branch (88:23): [True: 43.4M, False: 18.4E]
  ------------------
   89|  43.4M|    if (append_len > real_len)
  ------------------
  |  Branch (89:9): [True: 414k, False: 43.0M]
  ------------------
   90|   414k|        append_len = real_len;
   91|       |
   92|  43.4M|    if (ta_get_size(*str) < at + append_len + 1) {
  ------------------
  |  Branch (92:9): [True: 43.3M, False: 73.5k]
  ------------------
   93|  43.3M|        char *t = ta_realloc_size(NULL, *str, at + append_len + 1);
   94|  43.3M|        if (!t)
  ------------------
  |  Branch (94:13): [True: 0, False: 43.3M]
  ------------------
   95|      0|            return false;
   96|  43.3M|        *str = t;
   97|  43.3M|    }
   98|       |
   99|  43.4M|    if (append_len)
  ------------------
  |  Branch (99:9): [True: 42.9M, False: 528k]
  ------------------
  100|  42.9M|        memcpy(*str + at, append, append_len);
  101|       |
  102|  43.4M|    (*str)[at + append_len] = '\0';
  103|       |
  104|  43.4M|    ta_dbg_mark_as_string(*str);
  105|       |
  106|  43.4M|    return true;
  107|  43.4M|}
ta_utils.c:ta_vasprintf_append_at:
  174|  3.10M|{
  175|  3.10M|    assert(ta_get_size(*str) >= at);
  176|       |
  177|  3.10M|    int size;
  178|  3.10M|    va_list copy;
  179|  3.10M|    va_copy(copy, ap);
  180|  3.10M|    char c;
  181|  3.10M|    size = vsnprintf(&c, 1, fmt, copy);
  182|  3.10M|    va_end(copy);
  183|       |
  184|  3.10M|    if (size < 0)
  ------------------
  |  Branch (184:9): [True: 0, False: 3.10M]
  ------------------
  185|      0|        return false;
  186|       |
  187|  3.10M|    if (ta_get_size(*str) < at + size + 1) {
  ------------------
  |  Branch (187:9): [True: 3.10M, False: 0]
  ------------------
  188|  3.10M|        char *t = ta_realloc_size(NULL, *str, at + size + 1);
  189|  3.10M|        if (!t)
  ------------------
  |  Branch (189:13): [True: 0, False: 3.10M]
  ------------------
  190|      0|            return false;
  191|  3.10M|        *str = t;
  192|  3.10M|    }
  193|  3.10M|    vsnprintf(*str + at, size + 1, fmt, ap);
  194|       |
  195|  3.10M|    ta_dbg_mark_as_string(*str);
  196|       |
  197|  3.10M|    return true;
  198|  3.10M|}

mp_csp_guess_colorspace:
  154|  7.13k|{
  155|  7.13k|    return width >= 1280 || height > 576 ? PL_COLOR_SYSTEM_BT_709 : PL_COLOR_SYSTEM_BT_601;
  ------------------
  |  Branch (155:12): [True: 0, False: 7.13k]
  |  Branch (155:29): [True: 0, False: 7.13k]
  ------------------
  156|  7.13k|}
mp_csp_guess_primaries:
  159|  7.13k|{
  160|       |    // HD content
  161|  7.13k|    if (width >= 1280 || height > 576)
  ------------------
  |  Branch (161:9): [True: 0, False: 7.13k]
  |  Branch (161:26): [True: 0, False: 7.13k]
  ------------------
  162|      0|        return PL_COLOR_PRIM_BT_709;
  163|       |
  164|  7.13k|    switch (height) {
  165|      0|    case 576: // Typical PAL content, including anamorphic/squared
  ------------------
  |  Branch (165:5): [True: 0, False: 7.13k]
  ------------------
  166|      0|        return PL_COLOR_PRIM_BT_601_625;
  167|       |
  168|      0|    case 480: // Typical NTSC content, including squared
  ------------------
  |  Branch (168:5): [True: 0, False: 7.13k]
  ------------------
  169|      0|    case 486: // NTSC Pro or anamorphic NTSC
  ------------------
  |  Branch (169:5): [True: 0, False: 7.13k]
  ------------------
  170|      0|        return PL_COLOR_PRIM_BT_601_525;
  171|       |
  172|  7.13k|    default: // No good metric, just pick BT.709 to minimize damage
  ------------------
  |  Branch (172:5): [True: 7.13k, False: 0]
  ------------------
  173|  7.13k|        return PL_COLOR_PRIM_BT_709;
  174|  7.13k|    }
  175|  7.13k|}

vd_lavc.c:add_all_hwdec_methods:
  336|  7.59k|{
  337|  7.59k|    const AVCodec *codec = NULL;
  338|  7.59k|    void *iter = NULL;
  339|  3.69M|    while (1) {
  ------------------
  |  Branch (339:12): [Folded - Ignored]
  ------------------
  340|  3.69M|        codec = av_codec_iterate(&iter);
  341|  3.69M|        if (!codec)
  ------------------
  |  Branch (341:13): [True: 7.59k, False: 3.68M]
  ------------------
  342|  7.59k|            break;
  343|  3.68M|        if (codec->type != AVMEDIA_TYPE_VIDEO || !av_codec_is_decoder(codec))
  ------------------
  |  Branch (343:13): [True: 1.75M, False: 1.93M]
  |  Branch (343:50): [True: 0, False: 1.93M]
  ------------------
  344|  1.75M|            continue;
  345|       |
  346|  1.93M|        struct hwdec_info info_template = {
  347|  1.93M|            .pix_fmt = AV_PIX_FMT_NONE,
  348|  1.93M|            .codec = codec,
  349|  1.93M|        };
  350|       |
  351|  1.93M|        const char *wrapper = NULL;
  352|  1.93M|        if (codec->capabilities & (AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_HYBRID))
  ------------------
  |  Branch (352:13): [True: 68.3k, False: 1.86M]
  ------------------
  353|  68.3k|            wrapper = codec->wrapper_name;
  354|       |
  355|       |        // A decoder can provide multiple methods. In particular, hwaccels
  356|       |        // provide various methods (e.g. native h264 with vaapi & d3d11), but
  357|       |        // even wrapper decoders could provide multiple methods.
  358|  1.93M|        bool found_any = false;
  359|  1.93M|        for (int n = 0; ; n++) {
  360|  1.93M|            const AVCodecHWConfig *cfg = avcodec_get_hw_config(codec, n);
  361|  1.93M|            if (!cfg)
  ------------------
  |  Branch (361:17): [True: 1.93M, False: 0]
  ------------------
  362|  1.93M|                break;
  363|       |
  364|      0|            if ((cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) ||
  ------------------
  |  Branch (364:17): [True: 0, False: 0]
  ------------------
  365|      0|                (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
  ------------------
  |  Branch (365:17): [True: 0, False: 0]
  ------------------
  366|      0|            {
  367|      0|                struct hwdec_info info = info_template;
  368|      0|                info.lavc_device = cfg->device_type;
  369|      0|                info.pix_fmt = cfg->pix_fmt;
  370|       |
  371|      0|                const char *name = av_hwdevice_get_type_name(cfg->device_type);
  372|      0|                mp_assert(name); // API violation by libavcodec
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  373|       |
  374|       |                // nvdec hwaccels and the cuvid full decoder clash with their
  375|       |                // naming, so fix it here; we also prefer nvdec for the hwaccel.
  376|      0|                if (strcmp(name, "cuda") == 0 && !wrapper)
  ------------------
  |  Branch (376:21): [True: 0, False: 0]
  |  Branch (376:50): [True: 0, False: 0]
  ------------------
  377|      0|                    name = "nvdec";
  378|       |
  379|      0|                snprintf(info.method_name, sizeof(info.method_name), "%s", name);
  380|       |
  381|       |                // Usually we want to prefer using hw_frames_ctx for true
  382|       |                // hwaccels only, but we actually don't have any way to detect
  383|       |                // those, so always use hw_frames_ctx if offered.
  384|      0|                if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) {
  ------------------
  |  Branch (384:21): [True: 0, False: 0]
  ------------------
  385|      0|                    info.use_hw_frames = true;
  386|      0|                } else {
  387|      0|                    info.use_hw_device = true;
  388|      0|                }
  389|       |
  390|       |                // Direct variant.
  391|      0|                add_hwdec_item(infos, num_infos, info);
  392|       |
  393|       |                // Copy variant.
  394|      0|                info.copying = true;
  395|      0|                if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) {
  ------------------
  |  Branch (395:21): [True: 0, False: 0]
  ------------------
  396|      0|                    info.use_hw_frames = false;
  397|      0|                    info.use_hw_device = true;
  398|      0|                }
  399|      0|                add_hwdec_item(infos, num_infos, info);
  400|       |
  401|      0|                found_any = true;
  402|      0|            } else if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) {
  ------------------
  |  Branch (402:24): [True: 0, False: 0]
  ------------------
  403|      0|                struct hwdec_info info = info_template;
  404|      0|                info.pix_fmt = cfg->pix_fmt;
  405|       |
  406|      0|                const char *name = wrapper;
  407|      0|                if (!name)
  ------------------
  |  Branch (407:21): [True: 0, False: 0]
  ------------------
  408|      0|                    name = av_get_pix_fmt_name(info.pix_fmt);
  409|      0|                mp_assert(name); // API violation by libavcodec
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  410|       |
  411|      0|                snprintf(info.method_name, sizeof(info.method_name), "%s", name);
  412|       |
  413|       |                // Direct variant.
  414|      0|                add_hwdec_item(infos, num_infos, info);
  415|       |
  416|       |                // Copy variant.
  417|      0|                info.copying = true;
  418|      0|                info.pix_fmt = AV_PIX_FMT_NONE; // trust it can do sw output
  419|      0|                add_hwdec_item(infos, num_infos, info);
  420|       |
  421|      0|                found_any = true;
  422|      0|            }
  423|      0|        }
  424|       |
  425|  1.93M|        if (!found_any && wrapper) {
  ------------------
  |  Branch (425:13): [True: 1.93M, False: 0]
  |  Branch (425:27): [True: 68.3k, False: 1.86M]
  ------------------
  426|       |            // We _know_ there's something supported here, usually outputting
  427|       |            // sw surfaces. E.g. mediacodec (before hw_device_ctx support).
  428|       |
  429|  68.3k|            struct hwdec_info info = info_template;
  430|  68.3k|            info.copying = true; // probably
  431|       |
  432|  68.3k|            snprintf(info.method_name, sizeof(info.method_name), "%s", wrapper);
  433|  68.3k|            add_hwdec_item(infos, num_infos, info);
  434|  68.3k|        }
  435|  1.93M|    }
  436|       |
  437|  7.59k|    qsort(*infos, *num_infos, sizeof(struct hwdec_info), hwdec_compare);
  438|  7.59k|}
vd_lavc.c:add_hwdec_item:
  311|  68.3k|{
  312|  68.3k|    if (info.copying)
  ------------------
  |  Branch (312:9): [True: 68.3k, False: 0]
  ------------------
  313|  68.3k|        mp_snprintf_cat(info.method_name, sizeof(info.method_name), "-copy");
  314|       |
  315|       |    // (Including the codec name in case this is a wrapper looks pretty dumb,
  316|       |    // but better not have them clash with hwaccels and others.)
  317|  68.3k|    snprintf(info.name, sizeof(info.name), "%s-%s",
  318|  68.3k|             info.codec->name, info.method_name);
  319|       |
  320|  68.3k|    info.rank = *num_infos;
  321|  68.3k|    info.auto_pos = INT_MAX;
  322|       |
  323|  1.29M|    for (int x = 0; hwdec_autoprobe_info[x].method_name; x++) {
  ------------------
  |  Branch (323:21): [True: 1.22M, False: 68.3k]
  ------------------
  324|  1.22M|        const struct autoprobe_info *entry = &hwdec_autoprobe_info[x];
  325|  1.22M|        if (strcmp(entry->method_name, info.method_name) == 0) {
  ------------------
  |  Branch (325:13): [True: 0, False: 1.22M]
  ------------------
  326|      0|            info.flags |= entry->flags;
  327|      0|            if (info.flags & HWDEC_FLAG_AUTO)
  ------------------
  |  Branch (327:17): [True: 0, False: 0]
  ------------------
  328|      0|                info.auto_pos = x;
  329|      0|        }
  330|  1.22M|    }
  331|       |
  332|  68.3k|    MP_TARRAY_APPEND(NULL, *infos, *num_infos, info);
  ------------------
  |  |  105|  68.3k|    do {                                            \
  |  |  106|  68.3k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  68.3k|    do {                                            \
  |  |  |  |   97|  68.3k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  68.3k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  68.3k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  68.3k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 22.7k, False: 45.5k]
  |  |  |  |  ------------------
  |  |  |  |   99|  68.3k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|  22.7k|    do {                                                        \
  |  |  |  |  |  |   89|  22.7k|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|  22.7k|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|  22.7k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|  22.7k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|  22.7k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|  22.7k|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|  22.7k|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  68.3k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  68.3k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  68.3k|        (idxvar)++;                                 \
  |  |  109|  68.3k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  333|  68.3k|}
vd_lavc.c:hwdec_compare:
  285|  98.6k|{
  286|  98.6k|    struct hwdec_info *h1 = (void *)p1;
  287|  98.6k|    struct hwdec_info *h2 = (void *)p2;
  288|       |
  289|  98.6k|    if (h1 == h2)
  ------------------
  |  Branch (289:9): [True: 0, False: 98.6k]
  ------------------
  290|      0|        return 0;
  291|       |
  292|       |    // Strictly put non-preferred hwdecs to the end of the list.
  293|  98.6k|    if ((h1->auto_pos == INT_MAX) != (h2->auto_pos == INT_MAX))
  ------------------
  |  Branch (293:9): [True: 0, False: 98.6k]
  ------------------
  294|      0|        return h1->auto_pos == INT_MAX ? 1 : -1;
  ------------------
  |  Branch (294:16): [True: 0, False: 0]
  ------------------
  295|       |    // List non-copying entries first, so --hwdec=auto takes them.
  296|  98.6k|    if (h1->copying != h2->copying)
  ------------------
  |  Branch (296:9): [True: 0, False: 98.6k]
  ------------------
  297|      0|        return h1->copying ? 1 : -1;
  ------------------
  |  Branch (297:16): [True: 0, False: 0]
  ------------------
  298|       |    // Order by autoprobe preference order.
  299|  98.6k|    if (h1->auto_pos != h2->auto_pos)
  ------------------
  |  Branch (299:9): [True: 0, False: 98.6k]
  ------------------
  300|      0|        return h1->auto_pos > h2->auto_pos ? 1 : -1;
  ------------------
  |  Branch (300:16): [True: 0, False: 0]
  ------------------
  301|       |    // Put hwdecs without hw_device_ctx last
  302|  98.6k|    if ((!!h1->lavc_device) != (!!h2->lavc_device))
  ------------------
  |  Branch (302:9): [True: 0, False: 98.6k]
  ------------------
  303|      0|        return h1->lavc_device ? -1 : 1;
  ------------------
  |  Branch (303:16): [True: 0, False: 0]
  ------------------
  304|       |    // Fallback sort order to make sorting stable.
  305|  98.6k|    return h1->rank > h2->rank ? 1 :-1;
  ------------------
  |  Branch (305:12): [True: 0, False: 98.6k]
  ------------------
  306|  98.6k|}
vd_lavc.c:create:
 1425|  7.59k|{
 1426|  7.59k|    struct mp_filter *vd = mp_filter_create(parent, &vd_lavc_filter);
 1427|  7.59k|    if (!vd)
  ------------------
  |  Branch (1427:9): [True: 0, False: 7.59k]
  ------------------
 1428|      0|        return NULL;
 1429|       |
 1430|  7.59k|    mp_filter_add_pin(vd, MP_PIN_IN, "in");
 1431|  7.59k|    mp_filter_add_pin(vd, MP_PIN_OUT, "out");
 1432|       |
 1433|  7.59k|    vd->log = mp_log_new(vd, parent->log, NULL);
 1434|       |
 1435|  7.59k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1436|  7.59k|    ctx->log = vd->log;
 1437|  7.59k|    ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf);
 1438|  7.59k|    ctx->opts = ctx->opts_cache->opts;
 1439|  7.59k|    ctx->hwdec_opts_cache = m_config_cache_alloc(ctx, vd->global, &hwdec_conf);
 1440|  7.59k|    ctx->hwdec_opts = ctx->hwdec_opts_cache->opts;
 1441|  7.59k|    ctx->codec = codec;
 1442|  7.59k|    ctx->decoder = talloc_strdup(ctx, decoder);
  ------------------
  |  |   50|  7.59k|#define talloc_strdup                   ta_xstrdup
  ------------------
 1443|  7.59k|    ctx->hwdec_swpool = mp_image_pool_new(ctx);
 1444|  7.59k|    ctx->dr_pool = mp_image_pool_new(ctx);
 1445|       |
 1446|  7.59k|    ctx->public.f = vd;
 1447|  7.59k|    ctx->public.control = control;
 1448|       |
 1449|  7.59k|    mp_mutex_init(&ctx->dr_lock);
 1450|       |
 1451|       |    // hwdec/DR
 1452|  7.59k|    struct mp_stream_info *info = mp_filter_find_stream_info(vd);
 1453|  7.59k|    if (info) {
  ------------------
  |  Branch (1453:9): [True: 7.59k, False: 0]
  ------------------
 1454|  7.59k|        ctx->hwdec_devs = info->hwdec_devs;
 1455|  7.59k|        ctx->vo = info->dr_vo;
 1456|  7.59k|    }
 1457|       |
 1458|  7.59k|    reinit(vd);
 1459|       |
 1460|  7.59k|    if (!ctx->avctx) {
  ------------------
  |  Branch (1460:9): [True: 25, False: 7.56k]
  ------------------
 1461|     25|        talloc_free(vd);
  ------------------
  |  |   47|     25|#define talloc_free                     ta_free
  ------------------
 1462|     25|        return NULL;
 1463|     25|    }
 1464|       |
 1465|  7.56k|    codec->codec_desc = ctx->avctx->codec_descriptor->long_name;
 1466|       |
 1467|  7.56k|    return &ctx->public;
 1468|  7.59k|}
vd_lavc.c:vd_lavc_destroy:
 1406|  7.59k|{
 1407|  7.59k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1408|       |
 1409|  7.59k|    uninit_avctx(vd);
 1410|       |
 1411|  7.59k|    mp_mutex_destroy(&ctx->dr_lock);
  ------------------
  |  |  130|  7.59k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
 1412|  7.59k|}
vd_lavc.c:uninit_avctx:
  896|  15.2k|{
  897|  15.2k|    vd_ffmpeg_ctx *ctx = vd->priv;
  898|       |
  899|  15.2k|    flush_all(vd);
  900|  15.2k|    av_frame_free(&ctx->pic);
  901|  15.2k|    mp_free_av_packet(&ctx->avpkt);
  902|  15.2k|    av_buffer_unref(&ctx->cached_hw_frames_ctx);
  903|       |
  904|  15.2k|    avcodec_free_context(&ctx->avctx);
  905|       |
  906|  15.2k|    av_buffer_unref(&ctx->hwdec_dev);
  907|       |
  908|  15.2k|    ctx->hwdec_failed = false;
  909|  15.2k|    ctx->hwdec_fail_count = 0;
  910|  15.2k|    ctx->max_delay_queue = 0;
  911|  15.2k|    ctx->hw_probing = false;
  912|  15.2k|    ctx->hwdec = (struct hwdec_info){0};
  913|  15.2k|    ctx->use_hwdec = false;
  914|  15.2k|}
vd_lavc.c:flush_all:
  877|  21.5k|{
  878|  21.5k|    vd_ffmpeg_ctx *ctx = vd->priv;
  879|       |
  880|  21.5k|    for (int n = 0; n < ctx->num_delay_queue; n++)
  ------------------
  |  Branch (880:21): [True: 0, False: 21.5k]
  ------------------
  881|      0|        talloc_free(ctx->delay_queue[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  882|  21.5k|    ctx->num_delay_queue = 0;
  883|       |
  884|  21.5k|    for (int n = 0; n < ctx->num_sent_packets; n++)
  ------------------
  |  Branch (884:21): [True: 0, False: 21.5k]
  ------------------
  885|      0|        talloc_free(ctx->sent_packets[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  886|  21.5k|    ctx->num_sent_packets = 0;
  887|       |
  888|  21.5k|    for (int n = 0; n < ctx->num_requeue_packets; n++)
  ------------------
  |  Branch (888:21): [True: 0, False: 21.5k]
  ------------------
  889|      0|        talloc_free(ctx->requeue_packets[n]);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  890|  21.5k|    ctx->num_requeue_packets = 0;
  891|       |
  892|  21.5k|    reset_avctx(vd);
  893|  21.5k|}
vd_lavc.c:reset_avctx:
  867|  29.4k|{
  868|  29.4k|    vd_ffmpeg_ctx *ctx = vd->priv;
  869|       |
  870|  29.4k|    if (ctx->avctx && avcodec_is_open(ctx->avctx))
  ------------------
  |  Branch (870:9): [True: 21.8k, False: 7.61k]
  |  Branch (870:23): [True: 21.7k, False: 25]
  ------------------
  871|  21.7k|        avcodec_flush_buffers(ctx->avctx);
  872|  29.4k|    ctx->flushing = false;
  873|  29.4k|    ctx->hwdec_request_reinit = false;
  874|  29.4k|}
vd_lavc.c:vd_lavc_process:
 1389|   664k|{
 1390|   664k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1391|       |
 1392|   664k|    lavc_process(vd, &ctx->state, send_packet, receive_frame);
 1393|   664k|}
vd_lavc.c:send_packet:
 1158|   284k|{
 1159|   284k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1160|   284k|    AVCodecContext *avctx = ctx->avctx;
 1161|       |
 1162|   284k|    if (ctx->num_requeue_packets && ctx->requeue_packets[0] != pkt)
  ------------------
  |  Branch (1162:9): [True: 0, False: 284k]
  |  Branch (1162:37): [True: 0, False: 0]
  ------------------
 1163|      0|        return AVERROR(EAGAIN); // cannot consume the packet
 1164|       |
 1165|   284k|    if (ctx->hwdec_failed)
  ------------------
  |  Branch (1165:9): [True: 0, False: 284k]
  ------------------
 1166|      0|        return AVERROR(EAGAIN);
 1167|       |
 1168|   284k|    if (!ctx->avctx)
  ------------------
  |  Branch (1168:9): [True: 0, False: 284k]
  ------------------
 1169|      0|        return AVERROR_EOF;
 1170|       |
 1171|   284k|    prepare_decoding(vd);
 1172|       |
 1173|   284k|    if (avctx->skip_frame == AVDISCARD_ALL)
  ------------------
  |  Branch (1173:9): [True: 0, False: 284k]
  ------------------
 1174|      0|        return 0;
 1175|       |
 1176|   284k|    mp_set_av_packet(ctx->avpkt, pkt, &ctx->codec_timebase);
 1177|       |
 1178|   284k|    int ret = avcodec_send_packet(avctx, pkt ? ctx->avpkt : NULL);
  ------------------
  |  Branch (1178:42): [True: 276k, False: 7.88k]
  ------------------
 1179|   284k|    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  ------------------
  |  Branch (1179:9): [True: 0, False: 284k]
  |  Branch (1179:35): [True: 0, False: 284k]
  ------------------
 1180|      0|        return ret;
 1181|       |
 1182|   284k|    if (ctx->hw_probing && ctx->num_sent_packets < 32 &&
  ------------------
  |  Branch (1182:9): [True: 0, False: 284k]
  |  Branch (1182:28): [True: 0, False: 0]
  ------------------
 1183|   284k|        ctx->hwdec_opts->software_fallback <= 32)
  ------------------
  |  Branch (1183:9): [True: 0, False: 0]
  ------------------
 1184|      0|    {
 1185|      0|        pkt = pkt ? demux_copy_packet(vd->packet_pool, pkt) : NULL;
  ------------------
  |  Branch (1185:15): [True: 0, False: 0]
  ------------------
 1186|      0|        MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1187|      0|    }
 1188|       |
 1189|   284k|    if (ret < 0)
  ------------------
  |  Branch (1189:9): [True: 94.0k, False: 190k]
  ------------------
 1190|  94.0k|        handle_err(vd);
 1191|   284k|    return ret;
 1192|   284k|}
vd_lavc.c:prepare_decoding:
 1118|   941k|{
 1119|   941k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1120|   941k|    AVCodecContext *avctx = ctx->avctx;
 1121|   941k|    struct vd_lavc_params *opts = ctx->opts;
 1122|       |
 1123|   941k|    if (!avctx)
  ------------------
  |  Branch (1123:9): [True: 0, False: 941k]
  ------------------
 1124|      0|        return;
 1125|       |
 1126|   941k|    int drop = ctx->framedrop_flags;
 1127|   941k|    if (drop == 1) {
  ------------------
  |  Branch (1127:9): [True: 0, False: 941k]
  ------------------
 1128|      0|        avctx->skip_frame = opts->framedrop;    // normal framedrop
 1129|   941k|    } else if (drop == 2) {
  ------------------
  |  Branch (1129:16): [True: 0, False: 941k]
  ------------------
 1130|      0|        avctx->skip_frame = AVDISCARD_NONREF;   // hr-seek framedrop
 1131|       |        // Can be much more aggressive for true intra codecs.
 1132|      0|        if (ctx->intra_only)
  ------------------
  |  Branch (1132:13): [True: 0, False: 0]
  ------------------
 1133|      0|            avctx->skip_frame = AVDISCARD_ALL;
 1134|   941k|    } else {
 1135|   941k|        avctx->skip_frame = ctx->skip_frame;    // normal playback
 1136|   941k|    }
 1137|       |
 1138|   941k|    if (ctx->hwdec_request_reinit)
  ------------------
  |  Branch (1138:9): [True: 0, False: 941k]
  ------------------
 1139|      0|        reset_avctx(vd);
 1140|   941k|}
vd_lavc.c:handle_err:
 1143|  99.4k|{
 1144|  99.4k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1145|  99.4k|    struct hwdec_opts *hwdec_opts = ctx->hwdec_opts;
 1146|       |
 1147|  99.4k|    MP_WARN(vd, "Error while decoding frame%s!\n",
  ------------------
  |  |   86|  99.4k|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|   198k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 99.4k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1148|  99.4k|            ctx->use_hwdec ? " (hardware decoding)" : "");
 1149|       |
 1150|  99.4k|    if (ctx->use_hwdec) {
  ------------------
  |  Branch (1150:9): [True: 0, False: 99.4k]
  ------------------
 1151|      0|        ctx->hwdec_fail_count += 1;
 1152|      0|        if (ctx->hwdec_fail_count >= hwdec_opts->software_fallback)
  ------------------
  |  Branch (1152:13): [True: 0, False: 0]
  ------------------
 1153|      0|            ctx->hwdec_failed = true;
 1154|      0|    }
 1155|  99.4k|}
vd_lavc.c:receive_frame:
 1270|   656k|{
 1271|   656k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1272|       |
 1273|   656k|    int ret = decode_frame(vd);
 1274|       |
 1275|   656k|    if (ctx->hwdec_failed) {
  ------------------
  |  Branch (1275:9): [True: 0, False: 656k]
  ------------------
 1276|       |        // Failed hardware decoding? Try the next one, and eventually software.
 1277|      0|        struct demux_packet **pkts = ctx->sent_packets;
 1278|      0|        int num_pkts = ctx->num_sent_packets;
 1279|      0|        ctx->sent_packets = NULL;
 1280|      0|        ctx->num_sent_packets = 0;
 1281|       |
 1282|       |        /*
 1283|       |         * We repeatedly force_fallback until we get an avctx, because there are
 1284|       |         * certain hwdecs that are really full decoders, and so if these fail,
 1285|       |         * they also fail to give us a valid avctx, and the early return path
 1286|       |         * here will simply give up on decoding completely if there is no
 1287|       |         * decoder. We should never hit an infinite loop as the hwdec list is
 1288|       |         * finite and we will eventually exhaust it and fall back to software
 1289|       |         * decoding (and in practice, most hwdecs are hwaccels and so the
 1290|       |         * decoder will successfully init even if the hwaccel fails later.)
 1291|       |         */
 1292|      0|        do {
 1293|      0|            force_fallback(vd);
 1294|      0|        } while (!ctx->avctx);
  ------------------
  |  Branch (1294:18): [True: 0, False: 0]
  ------------------
 1295|       |
 1296|      0|        ctx->requeue_packets = pkts;
 1297|      0|        ctx->num_requeue_packets = num_pkts;
 1298|       |
 1299|      0|        return 0; // force retry
 1300|      0|    }
 1301|       |
 1302|   656k|    if (ret == AVERROR(EAGAIN) && ctx->num_requeue_packets)
  ------------------
  |  Branch (1302:9): [True: 571k, False: 85.2k]
  |  Branch (1302:35): [True: 0, False: 571k]
  ------------------
 1303|      0|        return 0; // force retry, so send_queued_packet() gets called
 1304|       |
 1305|   656k|    if (ctx->num_delay_queue <= ctx->max_delay_queue && ret != AVERROR_EOF)
  ------------------
  |  Branch (1305:9): [True: 584k, False: 71.9k]
  |  Branch (1305:57): [True: 577k, False: 7.88k]
  ------------------
 1306|   577k|        return ret;
 1307|       |
 1308|  79.8k|    if (!ctx->num_delay_queue)
  ------------------
  |  Branch (1308:9): [True: 7.88k, False: 71.9k]
  ------------------
 1309|  7.88k|        return ret;
 1310|       |
 1311|  71.9k|    struct mp_image *res = ctx->delay_queue[0];
 1312|  71.9k|    MP_TARRAY_REMOVE_AT(ctx->delay_queue, ctx->num_delay_queue, 0);
  ------------------
  |  |  143|  71.9k|    do {                                            \
  |  |  144|  71.9k|        size_t at_ = (at);                          \
  |  |  145|  71.9k|        assert(at_ <= (idxvar));                    \
  |  |  146|  71.9k|        memmove((p) + at_, (p) + at_ + 1,           \
  |  |  147|  71.9k|                ((idxvar) - at_ - 1) * sizeof((p)[0])); \
  |  |  148|  71.9k|        (idxvar)--;                                 \
  |  |  149|  71.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (149:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1313|       |
 1314|  71.9k|    res = res ? mp_img_swap_to_native(res) : NULL;
  ------------------
  |  Branch (1314:11): [True: 71.9k, False: 0]
  ------------------
 1315|  71.9k|    if (!res)
  ------------------
  |  Branch (1315:9): [True: 0, False: 71.9k]
  ------------------
 1316|      0|        return AVERROR_UNKNOWN;
 1317|       |
 1318|  71.9k|    if (ctx->use_hwdec && ctx->hwdec.copying && res->hwctx) {
  ------------------
  |  Branch (1318:9): [True: 0, False: 71.9k]
  |  Branch (1318:27): [True: 0, False: 0]
  |  Branch (1318:49): [True: 0, False: 0]
  ------------------
 1319|      0|        struct mp_image *sw = mp_image_hw_download(res, ctx->hwdec_swpool);
 1320|      0|        mp_image_unrefp(&res);
 1321|      0|        res = sw;
 1322|      0|        if (!res) {
  ------------------
  |  Branch (1322:13): [True: 0, False: 0]
  ------------------
 1323|      0|            MP_ERR(vd, "Could not copy back hardware decoded frame.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1324|      0|            ctx->hwdec_fail_count = INT_MAX - 1; // force fallback
 1325|      0|            handle_err(vd);
 1326|      0|            return AVERROR_UNKNOWN;
 1327|      0|        }
 1328|      0|    }
 1329|       |
 1330|  71.9k|    if (!ctx->hwdec_notified) {
  ------------------
  |  Branch (1330:9): [True: 561, False: 71.4k]
  ------------------
 1331|    561|        if (ctx->use_hwdec) {
  ------------------
  |  Branch (1331:13): [True: 0, False: 561]
  ------------------
 1332|      0|            MP_INFO(vd, "Using hardware decoding (%s).\n",
  ------------------
  |  |   87|      0|#define MP_INFO(obj, ...)       MP_MSG(obj, MSGL_INFO, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1333|      0|                    ctx->hwdec.method_name);
 1334|    561|        } else {
 1335|    561|            MP_VERBOSE(vd, "Using software decoding.\n");
  ------------------
  |  |   88|    561|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    561|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1336|    561|        }
 1337|    561|        ctx->hwdec_notified = true;
 1338|    561|    }
 1339|       |
 1340|  71.9k|    if (ctx->hw_probing) {
  ------------------
  |  Branch (1340:9): [True: 0, False: 71.9k]
  ------------------
 1341|      0|        for (int n = 0; n < ctx->num_sent_packets; n++)
  ------------------
  |  Branch (1341:25): [True: 0, False: 0]
  ------------------
 1342|      0|            demux_packet_pool_push(vd->packet_pool, ctx->sent_packets[n]);
 1343|      0|        ctx->num_sent_packets = 0;
 1344|      0|        ctx->hw_probing = false;
 1345|      0|    }
 1346|       |
 1347|  71.9k|    *out_frame = MAKE_FRAME(MP_FRAME_VIDEO, res);
  ------------------
  |  |   57|  71.9k|#define MAKE_FRAME(type, frame) ((struct mp_frame){(type), (frame)})
  ------------------
 1348|  71.9k|    return 0;
 1349|  71.9k|}
vd_lavc.c:decode_frame:
 1208|   656k|{
 1209|   656k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1210|   656k|    AVCodecContext *avctx = ctx->avctx;
 1211|       |
 1212|   656k|    if (!avctx || ctx->force_eof)
  ------------------
  |  Branch (1212:9): [True: 0, False: 656k]
  |  Branch (1212:19): [True: 0, False: 656k]
  ------------------
 1213|      0|        return AVERROR_EOF;
 1214|       |
 1215|   656k|    prepare_decoding(vd);
 1216|       |
 1217|       |    // Re-send old packets (typically after a hwdec fallback during init).
 1218|   656k|    if (ctx->num_requeue_packets)
  ------------------
  |  Branch (1218:9): [True: 0, False: 656k]
  ------------------
 1219|      0|        send_queued_packet(vd);
 1220|       |
 1221|   656k|    int ret = avcodec_receive_frame(avctx, ctx->pic);
 1222|   656k|    if (ret < 0) {
  ------------------
  |  Branch (1222:9): [True: 584k, False: 71.9k]
  ------------------
 1223|   584k|        if (ret == AVERROR_EOF) {
  ------------------
  |  Branch (1223:13): [True: 7.88k, False: 577k]
  ------------------
 1224|       |            // If flushing was initialized earlier and has ended now, make it
 1225|       |            // start over in case we get new packets at some point in the future.
 1226|       |            // This must take the delay queue into account, so avctx returns EOF
 1227|       |            // until the delay queue has been drained.
 1228|  7.88k|            if (!ctx->num_delay_queue)
  ------------------
  |  Branch (1228:17): [True: 7.88k, False: 0]
  ------------------
 1229|  7.88k|                reset_avctx(vd);
 1230|   577k|        } else if (ret == AVERROR(EAGAIN)) {
  ------------------
  |  Branch (1230:20): [True: 571k, False: 5.43k]
  ------------------
 1231|       |            // just retry after caller writes a packet
 1232|   571k|        } else {
 1233|  5.43k|            handle_err(vd);
 1234|  5.43k|        }
 1235|   584k|        return ret;
 1236|   584k|    }
 1237|       |
 1238|  71.9k|    mp_codec_info_from_av(avctx, ctx->codec);
 1239|       |
 1240|       |    // If something was decoded successfully, it must return a frame with valid
 1241|       |    // data.
 1242|  71.9k|    mp_assert(ctx->pic->buf[0]);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
 1243|       |
 1244|  71.9k|    struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
 1245|  71.9k|    if (!mpi) {
  ------------------
  |  Branch (1245:9): [True: 0, False: 71.9k]
  ------------------
 1246|      0|        av_frame_unref(ctx->pic);
 1247|      0|        return ret;
 1248|      0|    }
 1249|       |
 1250|  71.9k|    if (mpi->imgfmt == IMGFMT_CUDA && !mpi->planes[0]) {
  ------------------
  |  Branch (1250:9): [True: 0, False: 71.9k]
  |  Branch (1250:39): [True: 0, False: 0]
  ------------------
 1251|      0|        MP_ERR(vd, "CUDA frame without data. This is a FFmpeg bug.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1252|      0|        talloc_free(mpi);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1253|      0|        handle_err(vd);
 1254|      0|        return AVERROR_BUG;
 1255|      0|    }
 1256|       |
 1257|  71.9k|    ctx->hwdec_fail_count = 0;
 1258|       |
 1259|  71.9k|    mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
 1260|  71.9k|    mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
 1261|  71.9k|    mpi->pkt_duration = mp_pts_from_av(ctx->pic->duration, &ctx->codec_timebase);
 1262|       |
 1263|  71.9k|    av_frame_unref(ctx->pic);
 1264|       |
 1265|  71.9k|    MP_TARRAY_APPEND(ctx, ctx->delay_queue, ctx->num_delay_queue, mpi);
  ------------------
  |  |  105|  71.9k|    do {                                            \
  |  |  106|  71.9k|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|  71.9k|    do {                                            \
  |  |  |  |   97|  71.9k|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|  71.9k|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|  71.9k|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|  71.9k|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 561, False: 71.4k]
  |  |  |  |  ------------------
  |  |  |  |   99|  71.9k|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    561|    do {                                                        \
  |  |  |  |  |  |   89|    561|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|    561|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|    561|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|    561|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|    561|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|    561|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|    561|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|  71.9k|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|  71.9k|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|  71.9k|        (idxvar)++;                                 \
  |  |  109|  71.9k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1266|  71.9k|    return ret;
 1267|  71.9k|}
vd_lavc.c:select_and_set_hwdec:
  494|  7.59k|{
  495|  7.59k|    vd_ffmpeg_ctx *ctx = vd->priv;
  496|  7.59k|    const char *codec = ctx->codec->codec;
  497|       |
  498|  7.59k|    m_config_cache_update(ctx->hwdec_opts_cache);
  499|       |
  500|  7.59k|    struct hwdec_info *hwdecs = NULL;
  501|  7.59k|    int num_hwdecs = 0;
  502|  7.59k|    add_all_hwdec_methods(&hwdecs, &num_hwdecs);
  503|       |
  504|  7.59k|    char **hwdec_api = ctx->hwdec_opts->hwdec_api;
  505|  7.59k|    for (int i = 0; hwdec_api && hwdec_api[i]; i++) {
  ------------------
  |  Branch (505:21): [True: 7.59k, False: 0]
  |  Branch (505:34): [True: 7.59k, False: 0]
  ------------------
  506|  7.59k|        bstr opt = bstr0(hwdec_api[i]);
  507|       |
  508|  7.59k|        bool hwdec_requested = !bstr_equals0(opt, "no");
  509|  7.59k|        bool hwdec_auto_safe = bstr_equals0(opt, "auto") ||
  ------------------
  |  Branch (509:32): [True: 0, False: 7.59k]
  ------------------
  510|  7.59k|                            bstr_equals0(opt, "auto-safe") ||
  ------------------
  |  Branch (510:29): [True: 0, False: 7.59k]
  ------------------
  511|  7.59k|                            bstr_equals0(opt, "auto-copy") ||
  ------------------
  |  Branch (511:29): [True: 0, False: 7.59k]
  ------------------
  512|  7.59k|                            bstr_equals0(opt, "auto-copy-safe") ||
  ------------------
  |  Branch (512:29): [True: 0, False: 7.59k]
  ------------------
  513|  7.59k|                            bstr_equals0(opt, "yes") ||
  ------------------
  |  Branch (513:29): [True: 0, False: 7.59k]
  ------------------
  514|  7.59k|                            bstr_equals0(opt, "");
  ------------------
  |  Branch (514:29): [True: 0, False: 7.59k]
  ------------------
  515|  7.59k|        bool hwdec_auto_unsafe = bstr_equals0(opt, "auto-unsafe");
  516|  7.59k|        bool hwdec_auto_copy = bstr_equals0(opt, "auto-copy") ||
  ------------------
  |  Branch (516:32): [True: 0, False: 7.59k]
  ------------------
  517|  7.59k|                            bstr_equals0(opt, "auto-copy-safe") ||
  ------------------
  |  Branch (517:29): [True: 0, False: 7.59k]
  ------------------
  518|  7.59k|                            bstr_equals0(opt, "auto-copy-unsafe");
  ------------------
  |  Branch (518:29): [True: 0, False: 7.59k]
  ------------------
  519|  7.59k|        bool hwdec_auto = hwdec_auto_unsafe || hwdec_auto_copy || hwdec_auto_safe;
  ------------------
  |  Branch (519:27): [True: 0, False: 7.59k]
  |  Branch (519:48): [True: 0, False: 7.59k]
  |  Branch (519:67): [True: 0, False: 7.59k]
  ------------------
  520|       |
  521|  7.59k|        if (!hwdec_requested) {
  ------------------
  |  Branch (521:13): [True: 7.59k, False: 0]
  ------------------
  522|  7.59k|            MP_VERBOSE(vd, "No hardware decoding requested.\n");
  ------------------
  |  |   88|  7.59k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  7.59k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  523|  7.59k|            break;
  524|  7.59k|        } else if (!hwdec_codec_allowed(vd, codec)) {
  ------------------
  |  Branch (524:20): [True: 0, False: 0]
  ------------------
  525|      0|            MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  526|      0|                    "on whitelist.\n", codec);
  527|      0|            break;
  528|      0|        } else {
  529|      0|            bool hwdec_name_supported = false;  // relevant only if !hwdec_auto
  530|      0|            for (int n = 0; n < num_hwdecs; n++) {
  ------------------
  |  Branch (530:29): [True: 0, False: 0]
  ------------------
  531|      0|                struct hwdec_info *hwdec = &hwdecs[n];
  532|       |
  533|      0|                if (!hwdec_auto && !(bstr_equals0(opt, hwdec->method_name) ||
  ------------------
  |  Branch (533:21): [True: 0, False: 0]
  |  Branch (533:38): [True: 0, False: 0]
  ------------------
  534|      0|                                    bstr_equals0(opt, hwdec->name)))
  ------------------
  |  Branch (534:37): [True: 0, False: 0]
  ------------------
  535|      0|                    continue;
  536|      0|                hwdec_name_supported = true;
  537|       |
  538|      0|                bool already_attempted = false;
  539|      0|                for (int j = 0; j < ctx->num_attempted_hwdecs; j++) {
  ------------------
  |  Branch (539:33): [True: 0, False: 0]
  ------------------
  540|      0|                    if (bstr_equals0(ctx->attempted_hwdecs[j], hwdec->name)) {
  ------------------
  |  Branch (540:25): [True: 0, False: 0]
  ------------------
  541|      0|                        MP_DBG(vd, "Skipping previously attempted hwdec: %s\n",
  ------------------
  |  |   89|      0|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  542|      0|                               hwdec->name);
  543|      0|                        already_attempted = true;
  544|      0|                        break;
  545|      0|                    }
  546|      0|                }
  547|      0|                if (already_attempted)
  ------------------
  |  Branch (547:21): [True: 0, False: 0]
  ------------------
  548|      0|                    continue;
  549|       |
  550|      0|                const char *hw_codec = mp_codec_from_av_codec_id(hwdec->codec->id);
  551|      0|                if (!hw_codec || strcmp(hw_codec, codec) != 0)
  ------------------
  |  Branch (551:21): [True: 0, False: 0]
  |  Branch (551:34): [True: 0, False: 0]
  ------------------
  552|      0|                    continue;
  553|       |
  554|      0|                if (hwdec_auto_safe && !(hwdec->flags & HWDEC_FLAG_WHITELIST))
  ------------------
  |  Branch (554:21): [True: 0, False: 0]
  |  Branch (554:40): [True: 0, False: 0]
  ------------------
  555|      0|                    continue;
  556|       |
  557|      0|                MP_VERBOSE(vd, "Looking at hwdec %s...\n", hwdec->name);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  558|       |
  559|       |                /*
  560|       |                 * Past this point, any kind of failure that results in us
  561|       |                 * looking for a new hwdec should not lead to use trying this
  562|       |                 * hwdec again - so add it to the list, regardless of whether
  563|       |                 * initialisation will succeed or not.
  564|       |                 */
  565|      0|                MP_TARRAY_APPEND(ctx, ctx->attempted_hwdecs,
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  566|      0|                                 ctx->num_attempted_hwdecs,
  567|      0|                                 bstrdup(ctx, bstr0(hwdec->name)));
  568|       |
  569|      0|                if (hwdec_auto_copy && !hwdec->copying) {
  ------------------
  |  Branch (569:21): [True: 0, False: 0]
  |  Branch (569:40): [True: 0, False: 0]
  ------------------
  570|      0|                    MP_VERBOSE(vd, "Not using this for auto-copy.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  571|      0|                    continue;
  572|      0|                }
  573|       |
  574|      0|                if (hwdec->lavc_device) {
  ------------------
  |  Branch (574:21): [True: 0, False: 0]
  ------------------
  575|      0|                    ctx->hwdec_dev = hwdec_create_dev(vd, hwdec, hwdec_auto);
  576|      0|                    if (!ctx->hwdec_dev) {
  ------------------
  |  Branch (576:25): [True: 0, False: 0]
  ------------------
  577|      0|                        MP_VERBOSE(vd, "Could not create device.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  578|      0|                        continue;
  579|      0|                    }
  580|       |
  581|      0|                    const struct hwcontext_fns *fns =
  582|      0|                                hwdec_get_hwcontext_fns(hwdec->lavc_device);
  583|      0|                    if (fns && fns->is_emulated && fns->is_emulated(ctx->hwdec_dev)) {
  ------------------
  |  Branch (583:25): [True: 0, False: 0]
  |  Branch (583:32): [True: 0, False: 0]
  |  Branch (583:52): [True: 0, False: 0]
  ------------------
  584|      0|                        if (hwdec_auto) {
  ------------------
  |  Branch (584:29): [True: 0, False: 0]
  ------------------
  585|      0|                            MP_VERBOSE(vd, "Not using emulated API.\n");
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  586|      0|                            av_buffer_unref(&ctx->hwdec_dev);
  587|      0|                            continue;
  588|      0|                        }
  589|      0|                        MP_WARN(vd, "Using emulated hardware decoding API.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  590|      0|                    }
  591|      0|                } else if (!hwdec->copying) {
  ------------------
  |  Branch (591:28): [True: 0, False: 0]
  ------------------
  592|       |                    // Most likely METHOD_INTERNAL, which often use delay-loaded
  593|       |                    // VO support as well.
  594|      0|                    if (ctx->hwdec_devs) {
  ------------------
  |  Branch (594:25): [True: 0, False: 0]
  ------------------
  595|      0|                        struct hwdec_imgfmt_request params = {
  596|      0|                            .imgfmt = pixfmt2imgfmt(hwdec->pix_fmt),
  597|      0|                            .probing = hwdec_auto,
  598|      0|                        };
  599|      0|                        hwdec_devices_request_for_img_fmt(
  600|      0|                            ctx->hwdec_devs, &params);
  601|      0|                    }
  602|      0|                }
  603|       |
  604|      0|                ctx->use_hwdec = true;
  605|      0|                ctx->hwdec = *hwdec;
  606|      0|                break;
  607|      0|            }
  608|      0|            if (ctx->use_hwdec)
  ------------------
  |  Branch (608:17): [True: 0, False: 0]
  ------------------
  609|      0|                break;
  610|      0|            else if (!hwdec_auto && !hwdec_name_supported)
  ------------------
  |  Branch (610:22): [True: 0, False: 0]
  |  Branch (610:37): [True: 0, False: 0]
  ------------------
  611|      0|                MP_WARN(vd, "Unsupported hwdec: %.*s\n", BSTR_P(opt));
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  612|      0|        }
  613|  7.59k|    }
  614|  7.59k|    talloc_free(hwdecs);
  ------------------
  |  |   47|  7.59k|#define talloc_free                     ta_free
  ------------------
  615|       |
  616|       |
  617|  7.59k|    if (ctx->use_hwdec) {
  ------------------
  |  Branch (617:9): [True: 0, False: 7.59k]
  ------------------
  618|      0|        MP_VERBOSE(vd, "Trying hardware decoding via %s.\n", ctx->hwdec.name);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  619|      0|        if (strcmp(ctx->decoder, ctx->hwdec.codec->name) != 0)
  ------------------
  |  Branch (619:13): [True: 0, False: 0]
  ------------------
  620|      0|            MP_VERBOSE(vd, "Using underlying hw-decoder '%s'\n",
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  621|      0|                       ctx->hwdec.codec->name);
  622|  7.59k|    } else {
  623|       |        // If software fallback is disabled and we get here, all hwdec must
  624|       |        // have failed. Tell the ctx to always force an eof.
  625|  7.59k|        if (ctx->hwdec_opts->software_fallback == INT_MAX) {
  ------------------
  |  Branch (625:13): [True: 0, False: 7.59k]
  ------------------
  626|      0|            MP_WARN(ctx, "Software decoding fallback is disabled.\n");
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  627|      0|            ctx->force_eof = true;
  628|  7.59k|        } else {
  629|  7.59k|            MP_VERBOSE(vd, "Using software decoding.\n");
  ------------------
  |  |   88|  7.59k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  7.59k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  630|  7.59k|        }
  631|  7.59k|    }
  632|  7.59k|}
vd_lavc.c:init_avctx:
  702|  7.59k|{
  703|  7.59k|    vd_ffmpeg_ctx *ctx = vd->priv;
  704|  7.59k|    struct vd_lavc_params *lavc_param = ctx->opts;
  705|  7.59k|    struct mp_codec_params *c = ctx->codec;
  706|       |
  707|  7.59k|    m_config_cache_update(ctx->opts_cache);
  708|       |
  709|  7.59k|    mp_assert(!ctx->avctx);
  ------------------
  |  |   41|  7.59k|#define mp_assert assert
  ------------------
  710|       |
  711|  7.59k|    const AVCodec *lavc_codec = NULL;
  712|       |
  713|  7.59k|    if (ctx->use_hwdec) {
  ------------------
  |  Branch (713:9): [True: 0, False: 7.59k]
  ------------------
  714|      0|        lavc_codec = ctx->hwdec.codec;
  715|  7.59k|    } else {
  716|  7.59k|        lavc_codec = avcodec_find_decoder_by_name(ctx->decoder);
  717|  7.59k|    }
  718|  7.59k|    if (!lavc_codec)
  ------------------
  |  Branch (718:9): [True: 0, False: 7.59k]
  ------------------
  719|      0|        return;
  720|       |
  721|  7.59k|    const AVCodecDescriptor *desc = avcodec_descriptor_get(lavc_codec->id);
  722|  7.59k|    ctx->intra_only = desc && (desc->props & AV_CODEC_PROP_INTRA_ONLY);
  ------------------
  |  Branch (722:23): [True: 7.59k, False: 0]
  |  Branch (722:31): [True: 857, False: 6.73k]
  ------------------
  723|       |
  724|  7.59k|    ctx->codec_timebase = mp_get_codec_timebase(ctx->codec);
  725|       |
  726|  7.59k|    ctx->hwdec_failed = false;
  727|  7.59k|    ctx->hwdec_request_reinit = false;
  728|  7.59k|    ctx->avctx = avcodec_alloc_context3(lavc_codec);
  729|  7.59k|    AVCodecContext *avctx = ctx->avctx;
  730|  7.59k|    if (!ctx->avctx)
  ------------------
  |  Branch (730:9): [True: 0, False: 7.59k]
  ------------------
  731|      0|        goto error;
  732|  7.59k|    avctx->codec_type = AVMEDIA_TYPE_VIDEO;
  733|  7.59k|    avctx->codec_id = lavc_codec->id;
  734|  7.59k|    avctx->pkt_timebase = ctx->codec_timebase;
  735|       |
  736|  7.59k|    ctx->pic = av_frame_alloc();
  737|  7.59k|    if (!ctx->pic)
  ------------------
  |  Branch (737:9): [True: 0, False: 7.59k]
  ------------------
  738|      0|        goto error;
  739|       |
  740|  7.59k|    ctx->avpkt = av_packet_alloc();
  741|  7.59k|    if (!ctx->avpkt)
  ------------------
  |  Branch (741:9): [True: 0, False: 7.59k]
  ------------------
  742|      0|        goto error;
  743|       |
  744|  7.59k|    if (ctx->use_hwdec) {
  ------------------
  |  Branch (744:9): [True: 0, False: 7.59k]
  ------------------
  745|      0|        avctx->opaque = vd;
  746|      0|        avctx->thread_count = 1;
  747|      0|        avctx->hwaccel_flags |= AV_HWACCEL_FLAG_IGNORE_LEVEL;
  748|      0|        if (!lavc_param->check_hw_profile)
  ------------------
  |  Branch (748:13): [True: 0, False: 0]
  ------------------
  749|      0|            avctx->hwaccel_flags |= AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH;
  750|       |
  751|      0|#ifdef AV_HWACCEL_FLAG_UNSAFE_OUTPUT
  752|       |        /*
  753|       |         * This flag primarily exists for nvdec which has a very limited
  754|       |         * output frame pool, which can get exhausted if consumers don't
  755|       |         * release frames quickly. However, as an implementation
  756|       |         * requirement, we have to copy the frames anyway, so we don't
  757|       |         * need this extra implicit copy.
  758|       |         */
  759|      0|        avctx->hwaccel_flags |= AV_HWACCEL_FLAG_UNSAFE_OUTPUT;
  760|      0|#endif
  761|       |
  762|      0|        if (ctx->hwdec.use_hw_device) {
  ------------------
  |  Branch (762:13): [True: 0, False: 0]
  ------------------
  763|      0|            if (ctx->hwdec_dev)
  ------------------
  |  Branch (763:17): [True: 0, False: 0]
  ------------------
  764|      0|                avctx->hw_device_ctx = av_buffer_ref(ctx->hwdec_dev);
  765|      0|            if (!avctx->hw_device_ctx)
  ------------------
  |  Branch (765:17): [True: 0, False: 0]
  ------------------
  766|      0|                goto error;
  767|      0|        }
  768|      0|        if (ctx->hwdec.use_hw_frames) {
  ------------------
  |  Branch (768:13): [True: 0, False: 0]
  ------------------
  769|      0|            if (!ctx->hwdec_dev)
  ------------------
  |  Branch (769:17): [True: 0, False: 0]
  ------------------
  770|      0|                goto error;
  771|      0|        }
  772|       |
  773|      0|        if (ctx->hwdec.pix_fmt != AV_PIX_FMT_NONE)
  ------------------
  |  Branch (773:13): [True: 0, False: 0]
  ------------------
  774|      0|            avctx->get_format = get_format_hwdec;
  775|       |
  776|       |        // Some APIs benefit from this, for others it's additional bloat.
  777|      0|        if (ctx->hwdec.copying)
  ------------------
  |  Branch (777:13): [True: 0, False: 0]
  ------------------
  778|      0|            ctx->max_delay_queue = HWDEC_DELAY_QUEUE_COUNT;
  ------------------
  |  |   68|      0|#define HWDEC_DELAY_QUEUE_COUNT 2
  ------------------
  779|      0|        ctx->hw_probing = true;
  780|  7.59k|    } else {
  781|  7.59k|        mp_set_avcodec_threads(vd->log, avctx, lavc_param->threads);
  782|  7.59k|    }
  783|       |
  784|  7.59k|    if (!ctx->use_hwdec && ctx->vo && lavc_param->dr) {
  ------------------
  |  Branch (784:9): [True: 7.59k, False: 0]
  |  Branch (784:28): [True: 7.59k, False: 0]
  |  Branch (784:39): [True: 7.59k, False: 0]
  ------------------
  785|  7.59k|        avctx->opaque = vd;
  786|  7.59k|        avctx->get_buffer2 = get_buffer2_direct;
  787|  7.59k|    }
  788|       |
  789|  7.59k|    avctx->flags |= lavc_param->bitexact ? AV_CODEC_FLAG_BITEXACT : 0;
  ------------------
  |  Branch (789:21): [True: 0, False: 7.59k]
  ------------------
  790|  7.59k|    avctx->flags2 |= lavc_param->fast ? AV_CODEC_FLAG2_FAST : 0;
  ------------------
  |  Branch (790:22): [True: 0, False: 7.59k]
  ------------------
  791|       |
  792|  7.59k|    if (lavc_param->show_all)
  ------------------
  |  Branch (792:9): [True: 0, False: 7.59k]
  ------------------
  793|      0|        avctx->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
  794|       |
  795|  7.59k|    avctx->skip_loop_filter = lavc_param->skip_loop_filter;
  796|  7.59k|    avctx->skip_idct = lavc_param->skip_idct;
  797|  7.59k|    avctx->skip_frame = lavc_param->skip_frame;
  798|  7.59k|    avctx->apply_cropping = lavc_param->apply_cropping;
  799|       |
  800|  7.59k|    if (lavc_codec->id == AV_CODEC_ID_H264 && lavc_param->old_x264)
  ------------------
  |  Branch (800:9): [True: 4.30k, False: 3.28k]
  |  Branch (800:47): [True: 0, False: 4.30k]
  ------------------
  801|      0|        av_opt_set(avctx, "x264_build", "150", AV_OPT_SEARCH_CHILDREN);
  802|       |
  803|  7.59k|    switch(ctx->opts->film_grain) {
  804|      0|    case 0: /*CPU*/
  ------------------
  |  Branch (804:5): [True: 0, False: 7.59k]
  ------------------
  805|       |        // default lavc flags handle film grain within the decoder.
  806|      0|        break;
  807|      0|    case 1: /*GPU*/
  ------------------
  |  Branch (807:5): [True: 0, False: 7.59k]
  ------------------
  808|      0|        if (!ctx->vo ||
  ------------------
  |  Branch (808:13): [True: 0, False: 0]
  ------------------
  809|      0|            (ctx->vo && !(ctx->vo->driver->caps & VO_CAP_FILM_GRAIN))) {
  ------------------
  |  Branch (809:14): [True: 0, False: 0]
  |  Branch (809:25): [True: 0, False: 0]
  ------------------
  810|      0|            MP_MSG(vd, ctx->vo ? MSGL_WARN : MSGL_V,
  ------------------
  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  |  |  |  Branch (82:52): [True: 0, False: 0]
  |  |  |  Branch (82:57): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  811|      0|                   "GPU film grain requested, but VO %s, expect wrong output.\n",
  812|      0|                   ctx->vo ?
  813|      0|                   "does not support applying film grain" :
  814|      0|                   "is not available at decoder initialization to verify support");
  815|      0|        }
  816|       |
  817|      0|        avctx->export_side_data |= AV_CODEC_EXPORT_DATA_FILM_GRAIN;
  818|      0|        break;
  819|  7.59k|    default:
  ------------------
  |  Branch (819:5): [True: 7.59k, False: 0]
  ------------------
  820|  7.59k|        if (ctx->vo && (ctx->vo->driver->caps & VO_CAP_FILM_GRAIN))
  ------------------
  |  Branch (820:13): [True: 7.59k, False: 0]
  |  Branch (820:24): [True: 0, False: 7.59k]
  ------------------
  821|      0|            avctx->export_side_data |= AV_CODEC_EXPORT_DATA_FILM_GRAIN;
  822|       |
  823|  7.59k|        break;
  824|  7.59k|    }
  825|       |
  826|  7.59k|    mp_set_avopts(vd->log, avctx, lavc_param->avopts);
  827|       |
  828|       |    // Do this after the above avopt handling in case it changes values
  829|  7.59k|    ctx->skip_frame = avctx->skip_frame;
  830|       |
  831|  7.59k|    if (mp_set_avctx_codec_headers(avctx, c) < 0) {
  ------------------
  |  Branch (831:9): [True: 0, False: 7.59k]
  ------------------
  832|      0|        MP_ERR(vd, "Could not set codec parameters.\n");
  ------------------
  |  |   85|      0|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  833|      0|        goto error;
  834|      0|    }
  835|       |
  836|  7.59k|#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  837|  7.59k|    if (avctx->width > 8192 || avctx->height > 8192) {
  ------------------
  |  Branch (837:9): [True: 21, False: 7.56k]
  |  Branch (837:32): [True: 4, False: 7.56k]
  ------------------
  838|     25|        MP_ERR(vd, "Frame size too big %" PRIu32 "x%" PRIu32 ".\n", avctx->width, avctx->height);
  ------------------
  |  |   85|     25|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     25|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  839|     25|        goto error;
  840|     25|    }
  841|  7.56k|#endif
  842|       |
  843|       |    /* open it */
  844|  7.56k|    if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
  ------------------
  |  Branch (844:9): [True: 0, False: 7.56k]
  ------------------
  845|      0|        goto error;
  846|       |
  847|       |    // Sometimes, the first packet contains information required for correct
  848|       |    // decoding of the rest of the stream. The only currently known case is the
  849|       |    // x264 build number (encoded in a SEI element), needed to enable a
  850|       |    // workaround for broken 4:4:4 streams produced by older x264 versions.
  851|  7.56k|    if (lavc_codec->id == AV_CODEC_ID_H264 && c->first_packet) {
  ------------------
  |  Branch (851:9): [True: 4.30k, False: 3.25k]
  |  Branch (851:47): [True: 0, False: 4.30k]
  ------------------
  852|      0|        mp_set_av_packet(ctx->avpkt, c->first_packet, &ctx->codec_timebase);
  853|      0|        avcodec_send_packet(avctx, ctx->avpkt);
  854|      0|        avcodec_receive_frame(avctx, ctx->pic);
  855|      0|        av_frame_unref(ctx->pic);
  856|      0|        avcodec_flush_buffers(ctx->avctx);
  857|      0|    }
  858|       |
  859|  7.56k|    return;
  860|       |
  861|     25|error:
  862|     25|    MP_ERR(vd, "Could not open codec.\n");
  ------------------
  |  |   85|     25|#define MP_ERR(obj, ...)        MP_MSG(obj, MSGL_ERR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|     25|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  863|     25|    uninit_avctx(vd);
  864|     25|}
vd_lavc.c:get_buffer2_direct:
 1028|  88.0k|{
 1029|  88.0k|    struct mp_filter *vd = avctx->opaque;
 1030|  88.0k|    vd_ffmpeg_ctx *p = vd->priv;
 1031|       |
 1032|  88.0k|    mp_mutex_lock(&p->dr_lock);
  ------------------
  |  |  131|  88.0k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1033|       |
 1034|  88.0k|    int w = pic->width;
 1035|  88.0k|    int h = pic->height;
 1036|  88.0k|    int linesize_align[AV_NUM_DATA_POINTERS] = {0};
 1037|  88.0k|    avcodec_align_dimensions2(avctx, &w, &h, linesize_align);
 1038|       |
 1039|       |    // We assume that different alignments are just different power-of-2s.
 1040|       |    // Thus, a higher alignment always satisfies a lower alignment.
 1041|  88.0k|    int stride_align = MP_IMAGE_BYTE_ALIGN;
  ------------------
  |  |   35|  88.0k|#define MP_IMAGE_BYTE_ALIGN 64
  ------------------
 1042|   792k|    for (int n = 0; n < AV_NUM_DATA_POINTERS; n++)
  ------------------
  |  Branch (1042:21): [True: 704k, False: 88.0k]
  ------------------
 1043|   704k|        stride_align = MPMAX(stride_align, linesize_align[n]);
  ------------------
  |  |   43|   704k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 704k, False: 0]
  |  |  ------------------
  ------------------
 1044|       |
 1045|       |    // Note: texel sizes may be NPOT, so use full lcm instead of max
 1046|  88.0k|    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
 1047|  88.0k|    if (!(desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)) {
  ------------------
  |  Branch (1047:9): [True: 86.5k, False: 1.47k]
  ------------------
 1048|   191k|        for (int n = 0; n < desc->nb_components; n++)
  ------------------
  |  Branch (1048:25): [True: 104k, False: 86.5k]
  ------------------
 1049|   104k|            stride_align = mp_lcm(stride_align, desc->comp[n].step);
 1050|  86.5k|    }
 1051|       |
 1052|  88.0k|    int imgfmt = pixfmt2imgfmt(pic->format);
 1053|  88.0k|    if (!imgfmt)
  ------------------
  |  Branch (1053:9): [True: 0, False: 88.0k]
  ------------------
 1054|      0|        goto fallback;
 1055|       |
 1056|  88.0k|    if (p->dr_failed)
  ------------------
  |  Branch (1056:9): [True: 87.2k, False: 805]
  ------------------
 1057|  87.2k|        goto fallback;
 1058|       |
 1059|       |    // (For simplicity, we realloc on any parameter change, instead of trying
 1060|       |    // to be clever.)
 1061|    805|    if (stride_align != p->dr_stride_align || w != p->dr_w || h != p->dr_h ||
  ------------------
  |  Branch (1061:9): [True: 805, False: 0]
  |  Branch (1061:47): [True: 0, False: 0]
  |  Branch (1061:63): [True: 0, False: 0]
  ------------------
 1062|    805|        imgfmt != p->dr_imgfmt)
  ------------------
  |  Branch (1062:9): [True: 0, False: 0]
  ------------------
 1063|    805|    {
 1064|    805|        mp_image_pool_clear(p->dr_pool);
 1065|    805|        p->dr_imgfmt = imgfmt;
 1066|    805|        p->dr_w = w;
 1067|    805|        p->dr_h = h;
 1068|    805|        p->dr_stride_align = stride_align;
 1069|    805|        MP_DBG(p, "DR parameter change to %dx%d %s align=%d\n", w, h,
  ------------------
  |  |   89|    805|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    805|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1070|    805|               mp_imgfmt_to_name(imgfmt), stride_align);
 1071|    805|    }
 1072|       |
 1073|    805|    struct mp_image *img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h);
 1074|    805|    if (!img) {
  ------------------
  |  Branch (1074:9): [True: 805, False: 0]
  ------------------
 1075|    805|        bool host_cached = p->opts->dr == -1; // auto
 1076|    805|        int dr_flags = host_cached ? VO_DR_FLAG_HOST_CACHED : 0;
  ------------------
  |  Branch (1076:24): [True: 805, False: 0]
  ------------------
 1077|    805|        MP_DBG(p, "Allocating new%s DR image...\n", host_cached ? " (host-cached)" : "");
  ------------------
  |  |   89|    805|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  1.61k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (82:57): [True: 805, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1078|    805|        img = vo_get_image(p->vo, imgfmt, w, h, stride_align, dr_flags);
 1079|    805|        if (!img) {
  ------------------
  |  Branch (1079:13): [True: 805, False: 0]
  ------------------
 1080|    805|            MP_DBG(p, "...failed..\n");
  ------------------
  |  |   89|    805|#define MP_DBG(obj, ...)        MP_MSG(obj, MSGL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    805|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1081|    805|            goto fallback;
 1082|    805|        }
 1083|       |
 1084|       |        // Now make the mp_image part of the pool. This requires doing magic to
 1085|       |        // the image, so just add it to the pool and get it back to avoid
 1086|       |        // dealing with magic ourselves. (Normally this never fails.)
 1087|      0|        mp_image_pool_add(p->dr_pool, img);
 1088|      0|        img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h);
 1089|      0|        if (!img)
  ------------------
  |  Branch (1089:13): [True: 0, False: 0]
  ------------------
 1090|      0|            goto fallback;
 1091|      0|    }
 1092|       |
 1093|       |    // get_buffer2 callers seem very unappreciative of overwriting pic with a
 1094|       |    // new reference. The AVCodecContext.get_buffer2 comments tell us exactly
 1095|       |    // what we should do, so follow that.
 1096|      0|    for (int n = 0; n < 4; n++) {
  ------------------
  |  Branch (1096:21): [True: 0, False: 0]
  ------------------
 1097|      0|        pic->data[n] = img->planes[n];
 1098|      0|        pic->linesize[n] = img->stride[n];
 1099|      0|        pic->buf[n] = img->bufs[n];
 1100|      0|        img->bufs[n] = NULL;
 1101|      0|    }
 1102|      0|    talloc_free(img);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1103|       |
 1104|      0|    mp_mutex_unlock(&p->dr_lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1105|       |
 1106|      0|    return 0;
 1107|       |
 1108|  88.0k|fallback:
 1109|  88.0k|    if (!p->dr_failed)
  ------------------
  |  Branch (1109:9): [True: 805, False: 87.2k]
  ------------------
 1110|  88.0k|        MP_VERBOSE(p, "DR failed - disabling.\n");
  ------------------
  |  |   88|    805|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|    805|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1111|  88.0k|    p->dr_failed = true;
 1112|  88.0k|    mp_mutex_unlock(&p->dr_lock);
  ------------------
  |  |  133|  88.0k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1113|       |
 1114|  88.0k|    return avcodec_default_get_buffer2(avctx, pic, flags);
 1115|    805|}
vd_lavc.c:vd_lavc_reset:
 1396|  6.33k|{
 1397|  6.33k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1398|       |
 1399|  6.33k|    flush_all(vd);
 1400|       |
 1401|  6.33k|    ctx->state = (struct lavc_state){0};
 1402|  6.33k|    ctx->framedrop_flags = 0;
 1403|  6.33k|}
vd_lavc.c:control:
 1352|   299k|{
 1353|   299k|    vd_ffmpeg_ctx *ctx = vd->priv;
 1354|   299k|    switch (cmd) {
  ------------------
  |  Branch (1354:13): [True: 0, False: 299k]
  ------------------
 1355|   285k|    case VDCTRL_SET_FRAMEDROP:
  ------------------
  |  Branch (1355:5): [True: 285k, False: 14.6k]
  ------------------
 1356|   285k|        ctx->framedrop_flags = *(int *)arg;
 1357|   285k|        return CONTROL_TRUE;
  ------------------
  |  |   69|   285k|#define CONTROL_TRUE 1
  ------------------
 1358|  3.54k|    case VDCTRL_CHECK_FORCED_EOF: {
  ------------------
  |  Branch (1358:5): [True: 3.54k, False: 296k]
  ------------------
 1359|  3.54k|        *(bool *)arg = ctx->force_eof;
 1360|  3.54k|        return CONTROL_TRUE;
  ------------------
  |  |   69|  3.54k|#define CONTROL_TRUE 1
  ------------------
 1361|      0|    }
 1362|      0|    case VDCTRL_GET_BFRAMES: {
  ------------------
  |  Branch (1362:5): [True: 0, False: 299k]
  ------------------
 1363|      0|        AVCodecContext *avctx = ctx->avctx;
 1364|      0|        if (!avctx)
  ------------------
  |  Branch (1364:13): [True: 0, False: 0]
  ------------------
 1365|      0|            break;
 1366|      0|        *(int *)arg = avctx->has_b_frames;
 1367|      0|        return CONTROL_TRUE;
  ------------------
  |  |   69|      0|#define CONTROL_TRUE 1
  ------------------
 1368|      0|    }
 1369|  11.1k|    case VDCTRL_GET_HWDEC: {
  ------------------
  |  Branch (1369:5): [True: 11.1k, False: 288k]
  ------------------
 1370|  11.1k|        if (!ctx->hwdec_notified)
  ------------------
  |  Branch (1370:13): [True: 9.87k, False: 1.24k]
  ------------------
 1371|  9.87k|            return CONTROL_FALSE;
  ------------------
  |  |   70|  9.87k|#define CONTROL_FALSE 0
  ------------------
 1372|  1.24k|        *(char **)arg = ctx->use_hwdec ? ctx->hwdec.method_name : NULL;
  ------------------
  |  Branch (1372:25): [True: 0, False: 1.24k]
  ------------------
 1373|  1.24k|        return CONTROL_TRUE;
  ------------------
  |  |   69|  1.24k|#define CONTROL_TRUE 1
  ------------------
 1374|  11.1k|    }
 1375|      0|    case VDCTRL_FORCE_HWDEC_FALLBACK:
  ------------------
  |  Branch (1375:5): [True: 0, False: 299k]
  ------------------
 1376|      0|        if (ctx->use_hwdec) {
  ------------------
  |  Branch (1376:13): [True: 0, False: 0]
  ------------------
 1377|      0|            force_fallback(vd);
 1378|      0|            return ctx->avctx ? CONTROL_OK : CONTROL_ERROR;
  ------------------
  |  |   68|      0|#define CONTROL_OK 1
  ------------------
                          return ctx->avctx ? CONTROL_OK : CONTROL_ERROR;
  ------------------
  |  |   72|      0|#define CONTROL_ERROR -2
  ------------------
  |  Branch (1378:20): [True: 0, False: 0]
  ------------------
 1379|      0|        }
 1380|      0|        return CONTROL_FALSE;
  ------------------
  |  |   70|      0|#define CONTROL_FALSE 0
  ------------------
 1381|      0|    case VDCTRL_REINIT:
  ------------------
  |  Branch (1381:5): [True: 0, False: 299k]
  ------------------
 1382|      0|        reinit(vd);
 1383|      0|        return CONTROL_TRUE;
  ------------------
  |  |   69|      0|#define CONTROL_TRUE 1
  ------------------
 1384|   299k|    }
 1385|      0|    return CONTROL_UNKNOWN;
  ------------------
  |  |   71|      0|#define CONTROL_UNKNOWN -1
  ------------------
 1386|   299k|}
vd_lavc.c:reinit:
  675|  7.59k|{
  676|  7.59k|    vd_ffmpeg_ctx *ctx = vd->priv;
  677|       |
  678|  7.59k|    uninit_avctx(vd);
  679|       |
  680|       |    /*
  681|       |     * Reset attempted hwdecs so that if the hwdec list is reconfigured
  682|       |     * we attempt all of them from the beginning. The most practical
  683|       |     * reason for this is that ctrl+h toggles between `no` and
  684|       |     * `auto`, and we want to reevaluate from a clean slate each time.
  685|       |     */
  686|  7.59k|    TA_FREEP(&ctx->attempted_hwdecs);
  ------------------
  |  |   81|  7.59k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  7.59k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
  687|  7.59k|    ctx->num_attempted_hwdecs = 0;
  688|  7.59k|    ctx->hwdec_notified = false;
  689|       |
  690|  7.59k|    select_and_set_hwdec(vd);
  691|       |
  692|  7.59k|    bool use_hwdec = ctx->use_hwdec;
  693|  7.59k|    init_avctx(vd);
  694|  7.59k|    if (!ctx->avctx && use_hwdec) {
  ------------------
  |  Branch (694:9): [True: 25, False: 7.56k]
  |  Branch (694:24): [True: 0, False: 25]
  ------------------
  695|      0|        do {
  696|      0|            force_fallback(vd);
  697|      0|        } while (!ctx->avctx);
  ------------------
  |  Branch (697:18): [True: 0, False: 0]
  ------------------
  698|      0|    }
  699|  7.59k|}
vd_lavc.c:add_decoders:
 1471|  8.46k|{
 1472|  8.46k|    mp_add_lavc_decoders(list, AVMEDIA_TYPE_VIDEO);
 1473|  8.46k|}

imgfmt2pixfmt:
   75|   244k|{
   76|   244k|    if (fmt == IMGFMT_NONE)
  ------------------
  |  Branch (76:9): [True: 0, False: 244k]
  ------------------
   77|      0|        return AV_PIX_FMT_NONE;
   78|       |
   79|   244k|    if (fmt >= IMGFMT_AVPIXFMT_START && fmt < IMGFMT_AVPIXFMT_END) {
  ------------------
  |  Branch (79:9): [True: 5.60k, False: 238k]
  |  Branch (79:41): [True: 5.60k, False: 0]
  ------------------
   80|  5.60k|        enum AVPixelFormat pixfmt = fmt - IMGFMT_AVPIXFMT_START;
   81|       |        // Avoid duplicate format - each format must be unique.
   82|  5.60k|        int mpfmt = pixfmt2imgfmt(pixfmt);
   83|  5.60k|        if (mpfmt == fmt && av_pix_fmt_desc_get(pixfmt))
  ------------------
  |  Branch (83:13): [True: 5.60k, False: 0]
  |  Branch (83:29): [True: 5.60k, False: 0]
  ------------------
   84|  5.60k|            return pixfmt;
   85|      0|        return AV_PIX_FMT_NONE;
   86|  5.60k|    }
   87|       |
   88|  2.21M|    for (int i = 0; conversion_map[i].fmt; i++) {
  ------------------
  |  Branch (88:21): [True: 2.21M, False: 0]
  ------------------
   89|  2.21M|        if (conversion_map[i].fmt == fmt)
  ------------------
  |  Branch (89:13): [True: 238k, False: 1.97M]
  ------------------
   90|   238k|            return conversion_map[i].pix_fmt;
   91|  2.21M|    }
   92|      0|    return AV_PIX_FMT_NONE;
   93|   238k|}
pixfmt2imgfmt:
   96|   165k|{
   97|   165k|    if (pix_fmt == AV_PIX_FMT_NONE)
  ------------------
  |  Branch (97:9): [True: 0, False: 165k]
  ------------------
   98|      0|        return IMGFMT_NONE;
   99|       |
  100|  1.61M|    for (int i = 0; conversion_map[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
  ------------------
  |  Branch (100:21): [True: 1.60M, False: 7.83k]
  ------------------
  101|  1.60M|        if (conversion_map[i].pix_fmt == pix_fmt)
  ------------------
  |  Branch (101:13): [True: 157k, False: 1.44M]
  ------------------
  102|   157k|            return conversion_map[i].fmt;
  103|  1.60M|    }
  104|       |
  105|  7.83k|    int generic = IMGFMT_AVPIXFMT_START + pix_fmt;
  106|  7.83k|    if (generic < IMGFMT_AVPIXFMT_END && av_pix_fmt_desc_get(pix_fmt))
  ------------------
  |  Branch (106:9): [True: 7.83k, False: 0]
  |  Branch (106:42): [True: 7.83k, False: 0]
  ------------------
  107|  7.83k|        return generic;
  108|       |
  109|      0|    return 0;
  110|  7.83k|}

mp_imgfmt_to_name_buf:
  167|  84.1k|{
  168|  84.1k|    const struct mp_imgfmt_entry *p = get_mp_desc(fmt);
  169|  84.1k|    const char *name = p ? p->name : NULL;
  ------------------
  |  Branch (169:24): [True: 0, False: 84.1k]
  ------------------
  170|  84.1k|    if (!name) {
  ------------------
  |  Branch (170:9): [True: 84.1k, False: 0]
  ------------------
  171|  84.1k|        const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(imgfmt2pixfmt(fmt));
  172|  84.1k|        if (pixdesc)
  ------------------
  |  Branch (172:13): [True: 84.1k, False: 0]
  ------------------
  173|  84.1k|            name = pixdesc->name;
  174|  84.1k|    }
  175|  84.1k|    if (!name)
  ------------------
  |  Branch (175:9): [True: 0, False: 84.1k]
  ------------------
  176|      0|        name = "unknown";
  177|  84.1k|    snprintf(buf, buf_size, "%s", name);
  178|  84.1k|    int len = strlen(buf);
  179|  84.1k|    if (len > 2 && buf[len - 2] == MP_SELECT_LE_BE('l', 'b') && buf[len - 1] == 'e')
  ------------------
  |  |   38|   168k|#define MP_SELECT_LE_BE(LE, BE) LE
  ------------------
  |  Branch (179:9): [True: 84.1k, False: 0]
  |  Branch (179:20): [True: 17.3k, False: 66.8k]
  |  Branch (179:65): [True: 14.9k, False: 2.35k]
  ------------------
  180|  14.9k|        buf[len - 2] = '\0';
  181|  84.1k|    return buf;
  182|  84.1k|}
mp_imgfmt_desc_get_num_comps:
  555|  22.2k|{
  556|  22.2k|    int flags = desc->flags;
  557|  22.2k|    if (!(flags & MP_IMGFLAG_COLOR_MASK))
  ------------------
  |  |   55|  22.2k|#define MP_IMGFLAG_COLOR_MASK   (15 << 6)
  ------------------
  |  Branch (557:9): [True: 0, False: 22.2k]
  ------------------
  558|      0|        return 0;
  559|  22.2k|    return 3 + (flags & MP_IMGFLAG_GRAY ? -2 : 0) + !!(flags & MP_IMGFLAG_ALPHA);
  ------------------
  |  |   75|  22.2k|#define MP_IMGFLAG_GRAY         (1 << 14)
  ------------------
                  return 3 + (flags & MP_IMGFLAG_GRAY ? -2 : 0) + !!(flags & MP_IMGFLAG_ALPHA);
  ------------------
  |  |   52|  22.2k|#define MP_IMGFLAG_ALPHA        (1 << 5)
  ------------------
  |  Branch (559:17): [True: 17.6k, False: 4.55k]
  ------------------
  560|  22.2k|}
mp_imgfmt_get_desc:
  563|  81.2k|{
  564|  81.2k|    struct mp_imgfmt_desc desc;
  565|       |
  566|  81.2k|    if (!get_native_desc(mpfmt, &desc) &&
  ------------------
  |  Branch (566:9): [True: 81.2k, False: 0]
  ------------------
  567|  81.2k|        !mp_imgfmt_get_desc_from_pixdesc(mpfmt, &desc))
  ------------------
  |  Branch (567:9): [True: 0, False: 81.2k]
  ------------------
  568|      0|        return (struct mp_imgfmt_desc){0};
  569|       |
  570|   162k|    for (int p = 0; p < desc.num_planes; p++) {
  ------------------
  |  Branch (570:21): [True: 81.6k, False: 81.2k]
  ------------------
  571|  81.6k|        desc.xs[p] = (p == 1 || p == 2) ? desc.chroma_xs : 0;
  ------------------
  |  Branch (571:23): [True: 219, False: 81.4k]
  |  Branch (571:33): [True: 219, False: 81.2k]
  ------------------
  572|  81.6k|        desc.ys[p] = (p == 1 || p == 2) ? desc.chroma_ys : 0;
  ------------------
  |  Branch (572:23): [True: 219, False: 81.4k]
  |  Branch (572:33): [True: 219, False: 81.2k]
  ------------------
  573|  81.6k|    }
  574|       |
  575|  81.2k|    bool is_ba = desc.num_planes > 0;
  576|   162k|    for (int p = 0; p < desc.num_planes; p++)
  ------------------
  |  Branch (576:21): [True: 81.6k, False: 81.2k]
  ------------------
  577|  81.6k|        is_ba = !(desc.bpp[p] % 8u);
  578|       |
  579|  81.2k|    if (is_ba)
  ------------------
  |  Branch (579:9): [True: 80.3k, False: 865]
  ------------------
  580|  80.3k|        desc.flags |= MP_IMGFLAG_BYTE_ALIGNED;
  ------------------
  |  |   40|  80.3k|#define MP_IMGFLAG_BYTE_ALIGNED (1 << 2)
  ------------------
  581|       |
  582|  81.2k|    if (desc.flags & MP_IMGFLAG_HAS_COMPS) {
  ------------------
  |  |   34|  81.2k|#define MP_IMGFLAG_HAS_COMPS    (1 << 0)
  ------------------
  |  Branch (582:9): [True: 23.1k, False: 58.0k]
  ------------------
  583|  23.1k|        if (desc.comps[3].size)
  ------------------
  |  Branch (583:13): [True: 0, False: 23.1k]
  ------------------
  584|      0|            desc.flags |= MP_IMGFLAG_ALPHA;
  ------------------
  |  |   52|      0|#define MP_IMGFLAG_ALPHA        (1 << 5)
  ------------------
  585|       |
  586|       |        // Assuming all colors are (CCC+[A]) or (C+[A]), the latter being gray.
  587|  23.1k|        if (!desc.comps[1].size)
  ------------------
  |  Branch (587:13): [True: 18.5k, False: 4.63k]
  ------------------
  588|  18.5k|            desc.flags |= MP_IMGFLAG_GRAY;
  ------------------
  |  |   75|  18.5k|#define MP_IMGFLAG_GRAY         (1 << 14)
  ------------------
  589|       |
  590|  23.1k|        bool bb = true;
  591|   115k|        for (int n = 0; n < MP_NUM_COMPONENTS; n++) {
  ------------------
  |  |   29|   115k|#define MP_NUM_COMPONENTS 4
  ------------------
  |  Branch (591:25): [True: 92.5k, False: 23.1k]
  ------------------
  592|  92.5k|            if (desc.comps[n].offset % 8u || desc.comps[n].size % 8u)
  ------------------
  |  Branch (592:17): [True: 0, False: 92.5k]
  |  Branch (592:46): [True: 865, False: 91.7k]
  ------------------
  593|    865|                bb = false;
  594|  92.5k|        }
  595|  23.1k|        if (bb)
  ------------------
  |  Branch (595:13): [True: 22.2k, False: 865]
  ------------------
  596|  22.2k|            desc.flags |= MP_IMGFLAG_BYTES;
  ------------------
  |  |   37|  22.2k|#define MP_IMGFLAG_BYTES        (1 << 1)
  ------------------
  597|  23.1k|    }
  598|       |
  599|  81.2k|    if ((desc.flags & (MP_IMGFLAG_YUV | MP_IMGFLAG_RGB))
  ------------------
  |  |   67|  81.2k|#define MP_IMGFLAG_YUV          MP_IMGFLAG_COLOR_YUV
  |  |  ------------------
  |  |  |  |   56|  81.2k|#define MP_IMGFLAG_COLOR_YUV    (1 << 6)
  |  |  ------------------
  ------------------
                  if ((desc.flags & (MP_IMGFLAG_YUV | MP_IMGFLAG_RGB))
  ------------------
  |  |   68|  81.2k|#define MP_IMGFLAG_RGB          MP_IMGFLAG_COLOR_RGB
  |  |  ------------------
  |  |  |  |   57|  81.2k|#define MP_IMGFLAG_COLOR_RGB    (2 << 6)
  |  |  ------------------
  ------------------
  |  Branch (599:9): [True: 81.2k, False: 0]
  ------------------
  600|  81.2k|        && (desc.flags & MP_IMGFLAG_HAS_COMPS)
  ------------------
  |  |   34|  81.2k|#define MP_IMGFLAG_HAS_COMPS    (1 << 0)
  ------------------
  |  Branch (600:12): [True: 23.1k, False: 58.0k]
  ------------------
  601|  81.2k|        && (desc.flags & MP_IMGFLAG_BYTES)
  ------------------
  |  |   37|  23.1k|#define MP_IMGFLAG_BYTES        (1 << 1)
  ------------------
  |  Branch (601:12): [True: 22.2k, False: 865]
  ------------------
  602|  81.2k|        && ((desc.flags & MP_IMGFLAG_TYPE_MASK) == MP_IMGFLAG_TYPE_UINT))
  ------------------
  |  |   61|  22.2k|#define MP_IMGFLAG_TYPE_MASK    (15 << 10)
  ------------------
                      && ((desc.flags & MP_IMGFLAG_TYPE_MASK) == MP_IMGFLAG_TYPE_UINT))
  ------------------
  |  |   62|  22.2k|#define MP_IMGFLAG_TYPE_UINT    (1 << 10)
  ------------------
  |  Branch (602:12): [True: 22.2k, False: 77]
  ------------------
  603|  22.2k|    {
  604|  22.2k|        int cnt = mp_imgfmt_desc_get_num_comps(&desc);
  605|  22.2k|        bool same_depth = true;
  606|  44.6k|        for (int p = 0; p < desc.num_planes; p++)
  ------------------
  |  Branch (606:25): [True: 22.4k, False: 22.2k]
  ------------------
  607|  22.4k|            same_depth &= desc.bpp[p] == desc.bpp[0];
  608|  22.2k|        if (same_depth && cnt == desc.num_planes) {
  ------------------
  |  Branch (608:13): [True: 22.2k, False: 0]
  |  Branch (608:27): [True: 17.7k, False: 4.41k]
  ------------------
  609|  17.7k|            if (desc.flags & MP_IMGFLAG_YUV) {
  ------------------
  |  |   67|  17.7k|#define MP_IMGFLAG_YUV          MP_IMGFLAG_COLOR_YUV
  |  |  ------------------
  |  |  |  |   56|  17.7k|#define MP_IMGFLAG_COLOR_YUV    (1 << 6)
  |  |  ------------------
  ------------------
  |  Branch (609:17): [True: 17.7k, False: 0]
  ------------------
  610|  17.7k|                desc.flags |= MP_IMGFLAG_YUV_P;
  ------------------
  |  |   94|  17.7k|#define MP_IMGFLAG_YUV_P        (1 << 16)
  ------------------
  611|  17.7k|            } else {
  612|      0|                desc.flags |= MP_IMGFLAG_RGB_P;
  ------------------
  |  |   98|      0|#define MP_IMGFLAG_RGB_P        (1 << 17)
  ------------------
  613|      0|            }
  614|  17.7k|        }
  615|  22.2k|        if (cnt == 3 && desc.num_planes == 2 &&
  ------------------
  |  Branch (615:13): [True: 4.55k, False: 17.6k]
  |  Branch (615:25): [True: 0, False: 4.55k]
  ------------------
  616|  22.2k|            desc.bpp[1] == desc.bpp[0] * 2 &&
  ------------------
  |  Branch (616:13): [True: 0, False: 0]
  ------------------
  617|  22.2k|            (desc.flags & MP_IMGFLAG_YUV))
  ------------------
  |  |   67|      0|#define MP_IMGFLAG_YUV          MP_IMGFLAG_COLOR_YUV
  |  |  ------------------
  |  |  |  |   56|      0|#define MP_IMGFLAG_COLOR_YUV    (1 << 6)
  |  |  ------------------
  ------------------
  |  Branch (617:13): [True: 0, False: 0]
  ------------------
  618|      0|        {
  619|       |
  620|      0|            desc.flags |= MP_IMGFLAG_YUV_NV;
  ------------------
  |  |  101|      0|#define MP_IMGFLAG_YUV_NV       (1 << 18)
  ------------------
  621|      0|        }
  622|  22.2k|    }
  623|       |
  624|  81.2k|    return desc;
  625|  81.2k|}
mp_imgfmt_get_forced_csp:
  680|  9.26k|{
  681|  9.26k|    return get_forced_csp_from_flags(mp_imgfmt_get_desc(imgfmt).flags);
  682|  9.26k|}
img_format.c:get_mp_desc:
  131|   165k|{
  132|   165k|    if (imgfmt < IMGFMT_CUST_BASE)
  ------------------
  |  Branch (132:9): [True: 160k, False: 4.96k]
  ------------------
  133|   160k|        return NULL;
  134|  4.96k|    int index = imgfmt - IMGFMT_CUST_BASE;
  135|  4.96k|    if (index >= MP_ARRAY_SIZE(mp_imgfmt_list))
  ------------------
  |  |   48|  4.96k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (135:9): [True: 4.96k, False: 0]
  ------------------
  136|  4.96k|        return NULL;
  137|      0|    const struct mp_imgfmt_entry *e = &mp_imgfmt_list[index];
  138|      0|    return e->name ? e : NULL;
  ------------------
  |  Branch (138:12): [True: 0, False: 0]
  ------------------
  139|  4.96k|}
img_format.c:get_native_desc:
  521|  81.2k|{
  522|  81.2k|    const struct mp_imgfmt_entry *p = get_mp_desc(mpfmt);
  523|  81.2k|    if (!p || !p->desc.flags)
  ------------------
  |  Branch (523:9): [True: 81.2k, False: 0]
  |  Branch (523:15): [True: 0, False: 0]
  ------------------
  524|  81.2k|        return false;
  525|       |
  526|      0|    *desc = p->desc;
  527|       |
  528|       |    // Fill in some fields mp_imgfmt_entry.desc is not required to set.
  529|       |
  530|      0|    desc->id = mpfmt;
  531|       |
  532|      0|    for (int n = 0; n < MP_NUM_COMPONENTS; n++) {
  ------------------
  |  |   29|      0|#define MP_NUM_COMPONENTS 4
  ------------------
  |  Branch (532:21): [True: 0, False: 0]
  ------------------
  533|      0|        struct mp_imgfmt_comp_desc *cd = &desc->comps[n];
  534|      0|        if (cd->size)
  ------------------
  |  Branch (534:13): [True: 0, False: 0]
  ------------------
  535|      0|            desc->num_planes = MPMAX(desc->num_planes, cd->plane + 1);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  536|      0|        desc->bpp[cd->plane] =
  537|      0|            MPMAX(desc->bpp[cd->plane], MP_ALIGN_UP(cd->offset + cd->size, 8));
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  538|      0|    }
  539|       |
  540|      0|    if (!desc->align_x && !desc->align_y) {
  ------------------
  |  Branch (540:9): [True: 0, False: 0]
  |  Branch (540:27): [True: 0, False: 0]
  ------------------
  541|      0|        desc->align_x = 1 << desc->chroma_xs;
  542|      0|        desc->align_y = 1 << desc->chroma_ys;
  543|      0|    }
  544|       |
  545|      0|    if (desc->num_planes)
  ------------------
  |  Branch (545:9): [True: 0, False: 0]
  ------------------
  546|      0|        desc->flags |= MP_IMGFLAG_HAS_COMPS | MP_IMGFLAG_NE;
  ------------------
  |  |   34|      0|#define MP_IMGFLAG_HAS_COMPS    (1 << 0)
  ------------------
                      desc->flags |= MP_IMGFLAG_HAS_COMPS | MP_IMGFLAG_NE;
  ------------------
  |  |   49|      0|#define MP_IMGFLAG_NE           MP_SELECT_LE_BE(MP_IMGFLAG_LE, MP_IMGFLAG_BE)
  |  |  ------------------
  |  |  |  |   38|      0|#define MP_SELECT_LE_BE(LE, BE) LE
  |  |  ------------------
  ------------------
  547|       |
  548|      0|    if (!(desc->flags & MP_IMGFLAG_TYPE_MASK))
  ------------------
  |  |   61|      0|#define MP_IMGFLAG_TYPE_MASK    (15 << 10)
  ------------------
  |  Branch (548:9): [True: 0, False: 0]
  ------------------
  549|      0|        desc->flags |= MP_IMGFLAG_TYPE_UINT;
  ------------------
  |  |   62|      0|#define MP_IMGFLAG_TYPE_UINT    (1 << 10)
  ------------------
  550|       |
  551|      0|    return true;
  552|  81.2k|}
img_format.c:mp_imgfmt_get_desc_from_pixdesc:
  411|  81.2k|{
  412|  81.2k|    enum AVPixelFormat fmt = imgfmt2pixfmt(mpfmt);
  413|  81.2k|    const AVPixFmtDescriptor *pd = av_pix_fmt_desc_get(fmt);
  414|  81.2k|    if (!pd || pd->nb_components > 4)
  ------------------
  |  Branch (414:9): [True: 0, False: 81.2k]
  |  Branch (414:16): [True: 0, False: 81.2k]
  ------------------
  415|      0|        return false;
  416|       |
  417|  81.2k|    struct mp_imgfmt_desc desc = {
  418|  81.2k|        .id = mpfmt,
  419|  81.2k|        .chroma_xs = pd->log2_chroma_w,
  420|  81.2k|        .chroma_ys = pd->log2_chroma_h,
  421|  81.2k|    };
  422|       |
  423|  81.2k|    if (pd->flags & AV_PIX_FMT_FLAG_ALPHA)
  ------------------
  |  Branch (423:9): [True: 58.0k, False: 23.1k]
  ------------------
  424|  58.0k|        desc.flags |= MP_IMGFLAG_ALPHA;
  ------------------
  |  |   52|  58.0k|#define MP_IMGFLAG_ALPHA        (1 << 5)
  ------------------
  425|       |
  426|  81.2k|    if (pd->flags & AV_PIX_FMT_FLAG_HWACCEL)
  ------------------
  |  Branch (426:9): [True: 0, False: 81.2k]
  ------------------
  427|      0|        desc.flags |= MP_IMGFLAG_TYPE_HW;
  ------------------
  |  |   65|      0|#define MP_IMGFLAG_TYPE_HW      (8 << 10)
  ------------------
  428|       |
  429|       |    // Pixdesc does not provide a flag for XYZ, so this is the best we can do.
  430|  81.2k|    if (strncmp(pd->name, "xyz", 3) == 0) {
  ------------------
  |  Branch (430:9): [True: 0, False: 81.2k]
  ------------------
  431|      0|        desc.flags |= MP_IMGFLAG_COLOR_XYZ;
  ------------------
  |  |   58|      0|#define MP_IMGFLAG_COLOR_XYZ    (4 << 6)
  ------------------
  432|  81.2k|    } else if (pd->flags & AV_PIX_FMT_FLAG_RGB) {
  ------------------
  |  Branch (432:16): [True: 4.48k, False: 76.7k]
  ------------------
  433|  4.48k|        desc.flags |= MP_IMGFLAG_COLOR_RGB;
  ------------------
  |  |   57|  4.48k|#define MP_IMGFLAG_COLOR_RGB    (2 << 6)
  ------------------
  434|  76.7k|    } else if (fmt == AV_PIX_FMT_MONOBLACK || fmt == AV_PIX_FMT_MONOWHITE) {
  ------------------
  |  Branch (434:16): [True: 0, False: 76.7k]
  |  Branch (434:47): [True: 865, False: 75.8k]
  ------------------
  435|    865|        desc.flags |= MP_IMGFLAG_COLOR_RGB;
  ------------------
  |  |   57|    865|#define MP_IMGFLAG_COLOR_RGB    (2 << 6)
  ------------------
  436|  75.8k|    } else if (fmt == AV_PIX_FMT_PAL8) {
  ------------------
  |  Branch (436:16): [True: 58.0k, False: 17.7k]
  ------------------
  437|  58.0k|        desc.flags |= MP_IMGFLAG_COLOR_RGB | MP_IMGFLAG_TYPE_PAL8;
  ------------------
  |  |   57|  58.0k|#define MP_IMGFLAG_COLOR_RGB    (2 << 6)
  ------------------
                      desc.flags |= MP_IMGFLAG_COLOR_RGB | MP_IMGFLAG_TYPE_PAL8;
  ------------------
  |  |   64|  58.0k|#define MP_IMGFLAG_TYPE_PAL8    (4 << 10)
  ------------------
  438|  58.0k|    }
  439|       |
  440|  81.2k|    if (pd->flags & AV_PIX_FMT_FLAG_FLOAT)
  ------------------
  |  Branch (440:9): [True: 77, False: 81.1k]
  ------------------
  441|     77|        desc.flags |= MP_IMGFLAG_TYPE_FLOAT;
  ------------------
  |  |   63|     77|#define MP_IMGFLAG_TYPE_FLOAT   (2 << 10)
  ------------------
  442|       |
  443|       |    // Educated guess.
  444|  81.2k|    if (!(desc.flags & MP_IMGFLAG_COLOR_MASK) &&
  ------------------
  |  |   55|  81.2k|#define MP_IMGFLAG_COLOR_MASK   (15 << 6)
  ------------------
  |  Branch (444:9): [True: 17.7k, False: 63.4k]
  ------------------
  445|  81.2k|        !(desc.flags & MP_IMGFLAG_TYPE_HW))
  ------------------
  |  |   65|  17.7k|#define MP_IMGFLAG_TYPE_HW      (8 << 10)
  ------------------
  |  Branch (445:9): [True: 17.7k, False: 0]
  ------------------
  446|  17.7k|        desc.flags |= MP_IMGFLAG_COLOR_YUV;
  ------------------
  |  |   56|  17.7k|#define MP_IMGFLAG_COLOR_YUV    (1 << 6)
  ------------------
  447|       |
  448|  81.2k|    desc.align_x = 1 << desc.chroma_xs;
  449|  81.2k|    desc.align_y = 1 << desc.chroma_ys;
  450|       |
  451|  81.2k|    fill_pixdesc_layout(&desc, fmt, pd);
  452|       |
  453|  81.2k|    if (desc.flags & (MP_IMGFLAG_HAS_COMPS | MP_IMGFLAG_PACKED_SS_YUV)) {
  ------------------
  |  |   34|  81.2k|#define MP_IMGFLAG_HAS_COMPS    (1 << 0)
  ------------------
                  if (desc.flags & (MP_IMGFLAG_HAS_COMPS | MP_IMGFLAG_PACKED_SS_YUV)) {
  ------------------
  |  |   86|  81.2k|#define MP_IMGFLAG_PACKED_SS_YUV (1 << 15)
  ------------------
  |  Branch (453:9): [True: 23.1k, False: 58.0k]
  ------------------
  454|  23.1k|        if (!(desc.flags & MP_IMGFLAG_TYPE_MASK))
  ------------------
  |  |   61|  23.1k|#define MP_IMGFLAG_TYPE_MASK    (15 << 10)
  ------------------
  |  Branch (454:13): [True: 23.0k, False: 77]
  ------------------
  455|  23.0k|            desc.flags |= MP_IMGFLAG_TYPE_UINT;
  ------------------
  |  |   62|  23.0k|#define MP_IMGFLAG_TYPE_UINT    (1 << 10)
  ------------------
  456|  23.1k|    }
  457|       |
  458|  81.2k|    if (desc.bpp[0] % 8u && (pd->flags & AV_PIX_FMT_FLAG_BITSTREAM))
  ------------------
  |  Branch (458:9): [True: 865, False: 80.3k]
  |  Branch (458:29): [True: 865, False: 0]
  ------------------
  459|    865|        desc.align_x = 8 / desc.bpp[0]; // expect power of 2
  460|       |
  461|       |    // Very heuristical.
  462|  81.2k|    bool is_ne = !desc.endian_shift;
  463|  81.2k|    bool need_endian = (desc.comps[0].size % 8u && desc.bpp[0] > 8) ||
  ------------------
  |  Branch (463:25): [True: 865, False: 80.3k]
  |  Branch (463:52): [True: 0, False: 865]
  ------------------
  464|  81.2k|                       desc.comps[0].size > 8;
  ------------------
  |  Branch (464:24): [True: 3.73k, False: 77.5k]
  ------------------
  465|       |
  466|  81.2k|    if (need_endian) {
  ------------------
  |  Branch (466:9): [True: 3.73k, False: 77.5k]
  ------------------
  467|  3.73k|        bool is_le = MP_SELECT_LE_BE(is_ne, !is_ne);
  ------------------
  |  |   38|  3.73k|#define MP_SELECT_LE_BE(LE, BE) LE
  ------------------
  468|  3.73k|        desc.flags |= is_le ? MP_IMGFLAG_LE : MP_IMGFLAG_BE;
  ------------------
  |  |   43|  3.73k|#define MP_IMGFLAG_LE           (1 << 3)
  ------------------
                      desc.flags |= is_le ? MP_IMGFLAG_LE : MP_IMGFLAG_BE;
  ------------------
  |  |   46|  3.73k|#define MP_IMGFLAG_BE           (1 << 4)
  ------------------
  |  Branch (468:23): [True: 3.73k, False: 0]
  ------------------
  469|  77.5k|    } else {
  470|  77.5k|        desc.flags |= MP_IMGFLAG_LE | MP_IMGFLAG_BE;
  ------------------
  |  |   43|  77.5k|#define MP_IMGFLAG_LE           (1 << 3)
  ------------------
                      desc.flags |= MP_IMGFLAG_LE | MP_IMGFLAG_BE;
  ------------------
  |  |   46|  77.5k|#define MP_IMGFLAG_BE           (1 << 4)
  ------------------
  471|  77.5k|    }
  472|       |
  473|  81.2k|    *out = desc;
  474|  81.2k|    return true;
  475|  81.2k|}
img_format.c:fill_pixdesc_layout:
  187|  81.2k|{
  188|  81.2k|    if (pd->flags & AV_PIX_FMT_FLAG_PAL ||
  ------------------
  |  Branch (188:9): [True: 58.0k, False: 23.1k]
  ------------------
  189|  81.2k|        pd->flags & AV_PIX_FMT_FLAG_HWACCEL)
  ------------------
  |  Branch (189:9): [True: 0, False: 23.1k]
  ------------------
  190|  58.0k|        goto fail;
  191|       |
  192|  23.1k|    bool has_alpha = pd->flags & AV_PIX_FMT_FLAG_ALPHA;
  193|  23.1k|    if (pd->nb_components != 1 + has_alpha &&
  ------------------
  |  Branch (193:9): [True: 4.63k, False: 18.5k]
  ------------------
  194|  23.1k|        pd->nb_components != 3 + has_alpha)
  ------------------
  |  Branch (194:9): [True: 0, False: 4.63k]
  ------------------
  195|      0|        goto fail;
  196|       |
  197|       |    // Very convenient: we assume we're always on little endian, and FFmpeg
  198|       |    // explicitly marks big endian formats => don't need to guess whether a
  199|       |    // format is little endian, or not affected by byte order.
  200|  23.1k|    bool is_be = pd->flags & AV_PIX_FMT_FLAG_BE;
  201|  23.1k|    bool is_ne = MP_SELECT_LE_BE(false, true) == is_be;
  ------------------
  |  |   38|  23.1k|#define MP_SELECT_LE_BE(LE, BE) LE
  ------------------
  202|       |
  203|       |    // Packed sub-sampled YUV is very... special.
  204|  23.1k|    bool is_packed_ss_yuv = pd->log2_chroma_w && !pd->log2_chroma_h &&
  ------------------
  |  Branch (204:29): [True: 144, False: 23.0k]
  |  Branch (204:50): [True: 0, False: 144]
  ------------------
  205|  23.1k|        pd->comp[1].plane == 0 && pd->comp[2].plane == 0 &&
  ------------------
  |  Branch (205:9): [True: 0, False: 0]
  |  Branch (205:35): [True: 0, False: 0]
  ------------------
  206|  23.1k|        pd->nb_components == 3;
  ------------------
  |  Branch (206:9): [True: 0, False: 0]
  ------------------
  207|       |
  208|  23.1k|    if (is_packed_ss_yuv)
  ------------------
  |  Branch (208:9): [True: 0, False: 23.1k]
  ------------------
  209|      0|        desc->bpp[0] = pd->comp[1].step * 8;
  210|       |
  211|       |    // Determine if there are any byte overlaps => relevant for determining
  212|       |    // access unit for endian, since pixdesc does not expose this, and assumes
  213|       |    // a weird model where you do separate memory fetches for each component.
  214|  23.1k|    bool any_shared_bytes = !!(pd->flags & AV_PIX_FMT_FLAG_BITSTREAM);
  215|  55.5k|    for (int c = 0; c < pd->nb_components; c++) {
  ------------------
  |  Branch (215:21): [True: 32.4k, False: 23.1k]
  ------------------
  216|  46.3k|        for (int i = 0; i < c; i++) {
  ------------------
  |  Branch (216:25): [True: 13.8k, False: 32.4k]
  ------------------
  217|  13.8k|            const AVComponentDescriptor *d1 = &pd->comp[c];
  218|  13.8k|            const AVComponentDescriptor *d2 = &pd->comp[i];
  219|  13.8k|            if (d1->plane == d2->plane) {
  ------------------
  |  Branch (219:17): [True: 13.2k, False: 657]
  ------------------
  220|  13.2k|                if (d1->offset + (d1->depth + 7) / 8u > d2->offset &&
  ------------------
  |  Branch (220:21): [True: 13.2k, False: 0]
  ------------------
  221|  13.2k|                    d2->offset + (d2->depth + 7) / 8u > d1->offset)
  ------------------
  |  Branch (221:21): [True: 0, False: 13.2k]
  ------------------
  222|      0|                    any_shared_bytes = true;
  223|  13.2k|            }
  224|  13.8k|        }
  225|  32.4k|    }
  226|       |
  227|  23.1k|    int el_bits = (pd->flags & AV_PIX_FMT_FLAG_BITSTREAM) ? 1 : 8;
  ------------------
  |  Branch (227:19): [True: 865, False: 22.2k]
  ------------------
  228|  55.5k|    for (int c = 0; c < pd->nb_components; c++) {
  ------------------
  |  Branch (228:21): [True: 32.4k, False: 23.1k]
  ------------------
  229|  32.4k|        const AVComponentDescriptor *d = &pd->comp[c];
  230|  32.4k|        if (d->plane >= MP_MAX_PLANES)
  ------------------
  |  |   28|  32.4k|#define MP_MAX_PLANES 4
  ------------------
  |  Branch (230:13): [True: 0, False: 32.4k]
  ------------------
  231|      0|            goto fail;
  232|       |
  233|  32.4k|        desc->num_planes = MPMAX(desc->num_planes, d->plane + 1);
  ------------------
  |  |   43|  32.4k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 150, False: 32.2k]
  |  |  ------------------
  ------------------
  234|       |
  235|  32.4k|        int plane_bits = desc->bpp[d->plane];
  236|  32.4k|        int c_bits = d->step * el_bits;
  237|       |
  238|       |        // The first component wins, because either all components result in
  239|       |        // the same value, or luma wins (luma always comes before chroma).
  240|  32.4k|        if (plane_bits) {
  ------------------
  |  Branch (240:13): [True: 8.82k, False: 23.5k]
  ------------------
  241|  8.82k|            if (c_bits > plane_bits)
  ------------------
  |  Branch (241:17): [True: 0, False: 8.82k]
  ------------------
  242|      0|                goto fail; // inconsistent
  243|  23.5k|        } else {
  244|  23.5k|            desc->bpp[d->plane] = plane_bits = c_bits;
  245|  23.5k|        }
  246|       |
  247|  32.4k|        int shift = d->shift;
  248|       |        // What the fuck: for some inexplicable reason, MONOB uses shift=7
  249|       |        // in pixdesc, which is basically out of bounds. Pixdesc bug?
  250|       |        // Make it behave like MONOW. (No, the bit-order is not different.)
  251|  32.4k|        if (fmt == AV_PIX_FMT_MONOBLACK)
  ------------------
  |  Branch (251:13): [True: 0, False: 32.4k]
  ------------------
  252|      0|            shift = 0;
  253|       |
  254|  32.4k|        int offset = d->offset * el_bits;
  255|       |        // The pixdesc logic for reading and endian swapping is as follows
  256|       |        // (reverse engineered from av_read_image_line2()):
  257|       |        // - determine a word size that will include the component fully;
  258|       |        //   this includes the "active" bits and the amount "shifted" away
  259|       |        //   (for example shift=7/depth=18 => 32 bit word reading [31:0])
  260|       |        // - the same format can use different word sizes (e.g. bgr565: the R
  261|       |        //   component at offset 0 is read as 8 bit; BG is read as 16 bits)
  262|       |        // - if BE flag is set, swap the word before proceeding
  263|       |        // - extract via shift and mask derived by depth
  264|  32.4k|        int word = mp_round_next_power_of_2(MPMAX(d->depth + shift, 8));
  ------------------
  |  |   43|  32.4k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 4.13k, False: 28.2k]
  |  |  ------------------
  ------------------
  265|       |        // The purpose of this is unknown. It's an absurdity fished out of
  266|       |        // av_read_image_line2()'s implementation. It seems technically
  267|       |        // unnecessary, and provides no information. On the other hand, it
  268|       |        // compensates for seemingly bogus packed integer pixdescs; this
  269|       |        // is "why" some formats use d->offset = -1.
  270|  32.4k|        if (is_be && el_bits == 8 && word == 8)
  ------------------
  |  Branch (270:13): [True: 0, False: 32.4k]
  |  Branch (270:22): [True: 0, False: 0]
  |  Branch (270:38): [True: 0, False: 0]
  ------------------
  271|      0|            offset += 8;
  272|       |        // Pixdesc's model sometimes requires accesses with varying word-sizes,
  273|       |        // as seen in bgr565 and other formats. Also, it makes you read some
  274|       |        // formats with multiple endian-dependent accesses, where accessing a
  275|       |        // larger unit would make more sense. (Consider X2RGB10BE, for which
  276|       |        // pixdesc wants you to perform 3 * 2 byte accesses, and swap each of
  277|       |        // the read 16 bit words. What you really want is to swap the entire 4
  278|       |        // byte thing, and then extract the components with bit shifts).
  279|       |        // This is complete bullshit, so we transform it into word swaps before
  280|       |        // further processing. Care needs to be taken to not change formats like
  281|       |        // P010 or YA16 (prefer component accesses for them; P010 isn't even
  282|       |        // representable, because endian_shift is for all planes).
  283|       |        // As a heuristic, assume that if any components share a byte, the whole
  284|       |        // pixel is read as a single memory access and endian swapped at once.
  285|  32.4k|        int access_size = 8;
  286|  32.4k|        if (plane_bits > 8) {
  ------------------
  |  Branch (286:13): [True: 17.0k, False: 15.4k]
  ------------------
  287|  17.0k|            if (any_shared_bytes) {
  ------------------
  |  Branch (287:17): [True: 0, False: 17.0k]
  ------------------
  288|      0|                access_size = plane_bits;
  289|      0|                if (is_be && word != access_size) {
  ------------------
  |  Branch (289:21): [True: 0, False: 0]
  |  Branch (289:30): [True: 0, False: 0]
  ------------------
  290|       |                    // Before: offset = 8*byte_offset (with word bits of data)
  291|       |                    // After: offset = bit_offset into swapped endian_size word
  292|      0|                    offset = access_size - word - offset;
  293|      0|                }
  294|  17.0k|            } else {
  295|  17.0k|                access_size = word;
  296|  17.0k|            }
  297|  17.0k|        }
  298|  32.4k|        int endian_size = (access_size && !is_ne) ? access_size : 8;
  ------------------
  |  Branch (298:28): [True: 32.4k, False: 0]
  |  Branch (298:43): [True: 0, False: 32.4k]
  ------------------
  299|  32.4k|        int endian_shift = mp_log2(endian_size) - 3;
  300|  32.4k|        if (!MP_IS_POWER_OF_2(endian_size) || endian_shift < 0 || endian_shift > 3)
  ------------------
  |  |   55|  64.8k|#define MP_IS_POWER_OF_2(x) ((x) > 0 && !((x) & ((x) - 1)))
  |  |  ------------------
  |  |  |  Branch (55:30): [True: 32.4k, False: 0]
  |  |  |  Branch (55:41): [True: 32.4k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (300:47): [True: 0, False: 32.4k]
  |  Branch (300:67): [True: 0, False: 32.4k]
  ------------------
  301|      0|            goto fail;
  302|  32.4k|        if (desc->endian_shift && desc->endian_shift != endian_shift)
  ------------------
  |  Branch (302:13): [True: 0, False: 32.4k]
  |  Branch (302:35): [True: 0, False: 0]
  ------------------
  303|      0|            goto fail;
  304|  32.4k|        desc->endian_shift = endian_shift;
  305|       |
  306|       |        // We always use bit offsets; this doesn't lose any information,
  307|       |        // and pixdesc is merely more redundant.
  308|  32.4k|        offset += shift;
  309|  32.4k|        if (offset < 0 || offset >= (1 << 6))
  ------------------
  |  Branch (309:13): [True: 0, False: 32.4k]
  |  Branch (309:27): [True: 0, False: 32.4k]
  ------------------
  310|      0|            goto fail;
  311|  32.4k|        if (offset + d->depth > plane_bits)
  ------------------
  |  Branch (311:13): [True: 0, False: 32.4k]
  ------------------
  312|      0|            goto fail;
  313|  32.4k|        if (d->depth < 0 || d->depth >= (1 << 6))
  ------------------
  |  Branch (313:13): [True: 0, False: 32.4k]
  |  Branch (313:29): [True: 0, False: 32.4k]
  ------------------
  314|      0|            goto fail;
  315|  32.4k|        desc->comps[c] = (struct mp_imgfmt_comp_desc){
  316|  32.4k|            .plane = d->plane,
  317|  32.4k|            .offset = offset,
  318|  32.4k|            .size = d->depth,
  319|  32.4k|        };
  320|  32.4k|    }
  321|       |
  322|  46.7k|    for (int p = 0; p < desc->num_planes; p++) {
  ------------------
  |  Branch (322:21): [True: 23.5k, False: 23.1k]
  ------------------
  323|  23.5k|        if (!desc->bpp[p])
  ------------------
  |  Branch (323:13): [True: 0, False: 23.5k]
  ------------------
  324|      0|            goto fail; // plane doesn't exist
  325|  23.5k|    }
  326|       |
  327|       |    // What the fuck: this is probably a pixdesc bug, so fix it.
  328|  23.1k|    if (fmt == AV_PIX_FMT_RGB8) {
  ------------------
  |  Branch (328:9): [True: 0, False: 23.1k]
  ------------------
  329|      0|        desc->comps[2] = (struct mp_imgfmt_comp_desc){0, 0, 2};
  330|      0|        desc->comps[1] = (struct mp_imgfmt_comp_desc){0, 2, 3};
  331|      0|        desc->comps[0] = (struct mp_imgfmt_comp_desc){0, 5, 3};
  332|      0|    }
  333|       |
  334|       |    // Overlap test. If any shared bits are happening, this is not a format we
  335|       |    // can represent (or it's something like Bayer: components in the same bits,
  336|       |    // but different alternating lines).
  337|  23.1k|    bool any_shared_bits = false;
  338|  55.5k|    for (int c = 0; c < pd->nb_components; c++) {
  ------------------
  |  Branch (338:21): [True: 32.4k, False: 23.1k]
  ------------------
  339|  46.3k|        for (int i = 0; i < c; i++) {
  ------------------
  |  Branch (339:25): [True: 13.8k, False: 32.4k]
  ------------------
  340|  13.8k|            struct mp_imgfmt_comp_desc *c1 = &desc->comps[c];
  341|  13.8k|            struct mp_imgfmt_comp_desc *c2 = &desc->comps[i];
  342|  13.8k|            if (c1->plane == c2->plane) {
  ------------------
  |  Branch (342:17): [True: 13.2k, False: 657]
  ------------------
  343|  13.2k|                if (c1->offset + c1->size > c2->offset &&
  ------------------
  |  Branch (343:21): [True: 13.2k, False: 0]
  ------------------
  344|  13.2k|                    c2->offset + c2->size > c1->offset)
  ------------------
  |  Branch (344:21): [True: 0, False: 13.2k]
  ------------------
  345|      0|                    any_shared_bits = true;
  346|  13.2k|            }
  347|  13.8k|        }
  348|  32.4k|    }
  349|       |
  350|  23.1k|    if (any_shared_bits) {
  ------------------
  |  Branch (350:9): [True: 0, False: 23.1k]
  ------------------
  351|      0|        for (int c = 0; c < pd->nb_components; c++)
  ------------------
  |  Branch (351:25): [True: 0, False: 0]
  ------------------
  352|      0|            desc->comps[c] = (struct mp_imgfmt_comp_desc){0};
  353|      0|    }
  354|       |
  355|       |    // Many important formats have padding within an access word. For example
  356|       |    // yuv420p10 has the upper 6 bit cleared to 0; P010 has the lower 6 bits
  357|       |    // cleared to 0. Pixdesc cannot represent that these bits are 0. There are
  358|       |    // other formats where padding is not guaranteed to be 0, but they are
  359|       |    // described in the same way.
  360|       |    // Apply a heuristic that is supposed to identify formats which use
  361|       |    // guaranteed 0 padding. This could fail, but nobody said this pixdesc crap
  362|       |    // is robust.
  363|  55.5k|    for (int c = 0; c < pd->nb_components; c++) {
  ------------------
  |  Branch (363:21): [True: 32.4k, False: 23.1k]
  ------------------
  364|  32.4k|        struct mp_imgfmt_comp_desc *cd = &desc->comps[c];
  365|       |        // Note: rgb444 would defeat our heuristic if we checked only per comp.
  366|       |        //       also, exclude "bitstream" formats due to monow/monob
  367|  32.4k|        int fsize = MP_ALIGN_UP(cd->size, 8);
  ------------------
  |  |   52|  32.4k|#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
  ------------------
  368|  32.4k|        if (!any_shared_bytes && el_bits == 8 && fsize != cd->size &&
  ------------------
  |  Branch (368:13): [True: 31.5k, False: 865]
  |  Branch (368:34): [True: 31.5k, False: 0]
  |  Branch (368:50): [True: 0, False: 31.5k]
  ------------------
  369|  32.4k|            fsize - cd->size <= (1 << 3))
  ------------------
  |  Branch (369:13): [True: 0, False: 0]
  ------------------
  370|      0|        {
  371|      0|            if (!(cd->offset % 8u)) {
  ------------------
  |  Branch (371:17): [True: 0, False: 0]
  ------------------
  372|      0|                cd->pad = -(fsize - cd->size);
  373|      0|                cd->size = fsize;
  374|      0|            } else if (!((cd->offset + cd->size) % 8u)) {
  ------------------
  |  Branch (374:24): [True: 0, False: 0]
  ------------------
  375|      0|                cd->pad = fsize - cd->size;
  376|      0|                cd->size = fsize;
  377|      0|                cd->offset = MP_ALIGN_DOWN(cd->offset, 8);
  ------------------
  |  |   53|      0|#define MP_ALIGN_DOWN(x, align) ((x) & ~((align) - 1))
  ------------------
  378|      0|            }
  379|      0|        }
  380|  32.4k|    }
  381|       |
  382|       |    // The alpha component always has ID 4 (index 3) in our representation, so
  383|       |    // move the alpha component to there.
  384|  23.1k|    if (has_alpha && pd->nb_components < 4) {
  ------------------
  |  Branch (384:9): [True: 0, False: 23.1k]
  |  Branch (384:22): [True: 0, False: 0]
  ------------------
  385|      0|        desc->comps[3] = desc->comps[pd->nb_components - 1];
  386|      0|        desc->comps[pd->nb_components - 1] = (struct mp_imgfmt_comp_desc){0};
  387|      0|    }
  388|       |
  389|  23.1k|    if (is_packed_ss_yuv) {
  ------------------
  |  Branch (389:9): [True: 0, False: 23.1k]
  ------------------
  390|      0|        desc->flags |= MP_IMGFLAG_PACKED_SS_YUV;
  ------------------
  |  |   86|      0|#define MP_IMGFLAG_PACKED_SS_YUV (1 << 15)
  ------------------
  391|      0|        desc->bpp[0] /= 1 << pd->log2_chroma_w;
  392|  23.1k|    } else if (!any_shared_bits) {
  ------------------
  |  Branch (392:16): [True: 23.1k, False: 0]
  ------------------
  393|  23.1k|        desc->flags |= MP_IMGFLAG_HAS_COMPS;
  ------------------
  |  |   34|  23.1k|#define MP_IMGFLAG_HAS_COMPS    (1 << 0)
  ------------------
  394|  23.1k|    }
  395|       |
  396|  23.1k|    return;
  397|       |
  398|  58.0k|fail:
  399|   290k|    for (int n = 0; n < 4; n++)
  ------------------
  |  Branch (399:21): [True: 232k, False: 58.0k]
  ------------------
  400|   232k|        desc->comps[n] = (struct mp_imgfmt_comp_desc){0};
  401|       |    // Average bit size fallback.
  402|  58.0k|    int num_planes = av_pix_fmt_count_planes(fmt);
  403|  58.0k|    desc->num_planes = MPCLAMP(num_planes, 0, MP_MAX_PLANES);
  ------------------
  |  |   45|  58.0k|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 58.0k]
  |  |  |  Branch (45:56): [True: 0, False: 58.0k]
  |  |  ------------------
  ------------------
  404|   116k|    for (int p = 0; p < desc->num_planes; p++) {
  ------------------
  |  Branch (404:21): [True: 58.0k, False: 58.0k]
  ------------------
  405|  58.0k|        int ls = av_image_get_linesize(fmt, 256, p);
  406|  58.0k|        desc->bpp[p] = ls > 0 ? ls * 8 / 256 : 0;
  ------------------
  |  Branch (406:24): [True: 58.0k, False: 0]
  ------------------
  407|  58.0k|    }
  408|  58.0k|}
img_format.c:get_forced_csp_from_flags:
  669|  9.26k|{
  670|  9.26k|    if (flags & MP_IMGFLAG_COLOR_XYZ)
  ------------------
  |  |   58|  9.26k|#define MP_IMGFLAG_COLOR_XYZ    (4 << 6)
  ------------------
  |  Branch (670:9): [True: 0, False: 9.26k]
  ------------------
  671|      0|        return PL_COLOR_SYSTEM_XYZ;
  672|       |
  673|  9.26k|    if (flags & MP_IMGFLAG_COLOR_RGB)
  ------------------
  |  |   57|  9.26k|#define MP_IMGFLAG_COLOR_RGB    (2 << 6)
  ------------------
  |  Branch (673:9): [True: 2.06k, False: 7.19k]
  ------------------
  674|  2.06k|        return PL_COLOR_SYSTEM_RGB;
  675|       |
  676|  7.19k|    return PL_COLOR_SYSTEM_UNKNOWN;
  677|  9.26k|}

mp_image_setfmt:
  191|  71.9k|{
  192|  71.9k|    struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(out_fmt);
  193|  71.9k|    mpi->params.imgfmt = fmt.id;
  194|  71.9k|    mpi->fmt = fmt;
  195|  71.9k|    mpi->imgfmt = fmt.id;
  196|  71.9k|    mpi->num_planes = fmt.num_planes;
  197|  71.9k|    mpi->params.repr.alpha = (fmt.flags & MP_IMGFLAG_ALPHA) ? PL_ALPHA_INDEPENDENT
  ------------------
  |  |   52|  71.9k|#define MP_IMGFLAG_ALPHA        (1 << 5)
  ------------------
  |  Branch (197:30): [True: 57.8k, False: 14.1k]
  ------------------
  198|  71.9k|#if PL_API_VER >= 344
  199|  71.9k|                                                            : PL_ALPHA_NONE;
  200|       |#else
  201|       |                                                            : PL_ALPHA_UNKNOWN;
  202|       |#endif
  203|  71.9k|    mpi->params.repr.bits = (struct pl_bit_encoding) {
  204|  71.9k|        .sample_depth = fmt.comps[0].size,
  205|  71.9k|        .color_depth = fmt.comps[0].size - abs(fmt.comps[0].pad),
  206|  71.9k|        .bit_shift = MPMAX(0, fmt.comps[0].pad),
  ------------------
  |  |   43|  71.9k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 71.9k]
  |  |  ------------------
  ------------------
  207|  71.9k|    };
  208|  71.9k|}
mp_image_set_size:
  244|  71.9k|{
  245|  71.9k|    mp_assert(w >= 0 && h >= 0);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  246|  71.9k|    mpi->w = mpi->params.w = w;
  247|  71.9k|    mpi->h = mpi->params.h = h;
  248|  71.9k|}
mp_image_new_ref:
  335|   216k|{
  336|   216k|    if (!img)
  ------------------
  |  Branch (336:9): [True: 0, False: 216k]
  ------------------
  337|      0|        return NULL;
  338|       |
  339|   216k|    if (!img->bufs[0])
  ------------------
  |  Branch (339:9): [True: 0, False: 216k]
  ------------------
  340|      0|        return mp_image_new_copy(img);
  341|       |
  342|   216k|    struct mp_image *new = talloc_ptrtype(NULL, new);
  ------------------
  |  |   34|   216k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   216k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   216k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  343|   216k|    talloc_set_destructor(new, mp_image_destructor);
  ------------------
  |  |   41|   216k|#define talloc_set_destructor           ta_set_destructor
  ------------------
  344|   216k|    *new = *img;
  345|       |
  346|  1.08M|    for (int p = 0; p < MP_MAX_PLANES; p++)
  ------------------
  |  |   28|  1.08M|#define MP_MAX_PLANES 4
  ------------------
  |  Branch (346:21): [True: 865k, False: 216k]
  ------------------
  347|   865k|        ref_buffer(&new->bufs[p]);
  348|       |
  349|   216k|    ref_buffer(&new->hwctx);
  350|   216k|    ref_buffer(&new->icc_profile);
  351|   216k|    ref_buffer(&new->a53_cc);
  352|   216k|    ref_buffer(&new->dovi);
  353|   216k|    ref_buffer(&new->film_grain);
  354|       |
  355|   216k|    new->ff_side_data = talloc_memdup(NULL, new->ff_side_data,
  ------------------
  |  |   49|   216k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|   216k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|   216k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|   216k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|   216k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  356|   216k|                        new->num_ff_side_data * sizeof(new->ff_side_data[0]));
  357|   216k|    for (int n = 0; n < new->num_ff_side_data; n++)
  ------------------
  |  Branch (357:21): [True: 0, False: 216k]
  ------------------
  358|      0|        ref_buffer(&new->ff_side_data[n].buf);
  359|       |
  360|   216k|    return new;
  361|   216k|}
mp_image_unrefp:
  459|   263k|{
  460|   263k|    talloc_free(*p_img);
  ------------------
  |  |   47|   263k|#define talloc_free                     ta_free
  ------------------
  461|   263k|    *p_img = NULL;
  462|   263k|}
mp_image_crop_valid:
  745|   155k|{
  746|   155k|    return p->crop.x1 > p->crop.x0 && p->crop.y1 > p->crop.y0 &&
  ------------------
  |  Branch (746:12): [True: 155k, False: 0]
  |  Branch (746:39): [True: 155k, False: 0]
  ------------------
  747|   155k|           p->crop.x0 >= 0 && p->crop.y0 >= 0 &&
  ------------------
  |  Branch (747:12): [True: 155k, False: 0]
  |  Branch (747:31): [True: 155k, False: 0]
  ------------------
  748|   155k|           p->crop.x1 <= p->w && p->crop.y1 <= p->h;
  ------------------
  |  Branch (748:12): [True: 155k, False: 0]
  |  Branch (748:34): [True: 155k, False: 0]
  ------------------
  749|   155k|}
mp_image_params_get_dsize:
  754|  9.26k|{
  755|  9.26k|    if (mp_image_crop_valid(p))
  ------------------
  |  Branch (755:9): [True: 9.26k, False: 0]
  ------------------
  756|  9.26k|    {
  757|  9.26k|        *d_w = mp_rect_w(p->crop);
  ------------------
  |  |  128|  9.26k|#define mp_rect_w(r) ((r).x1 - (r).x0)
  ------------------
  758|  9.26k|        *d_h = mp_rect_h(p->crop);
  ------------------
  |  |  129|  9.26k|#define mp_rect_h(r) ((r).y1 - (r).y0)
  ------------------
  759|  9.26k|    } else {
  760|      0|        *d_w = p->w;
  761|      0|        *d_h = p->h;
  762|      0|    }
  763|       |
  764|  9.26k|    if (p->p_w > p->p_h && p->p_h >= 1)
  ------------------
  |  Branch (764:9): [True: 0, False: 9.26k]
  |  Branch (764:28): [True: 0, False: 0]
  ------------------
  765|      0|        *d_w = MPCLAMP(*d_w * (int64_t)p->p_w / p->p_h, 1, INT_MAX);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  766|  9.26k|    if (p->p_h > p->p_w && p->p_w >= 1)
  ------------------
  |  Branch (766:9): [True: 0, False: 9.26k]
  |  Branch (766:28): [True: 0, False: 0]
  ------------------
  767|      0|        *d_h = MPCLAMP(*d_h * (int64_t)p->p_h / p->p_w, 1, INT_MAX);
  ------------------
  |  |   45|      0|#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  |  Branch (45:56): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  768|  9.26k|}
mp_image_params_to_str_buf:
  779|  74.1k|{
  780|  74.1k|    if (p && p->imgfmt) {
  ------------------
  |  Branch (780:9): [True: 74.1k, False: 0]
  |  Branch (780:14): [True: 74.1k, False: 0]
  ------------------
  781|  74.1k|        snprintf(b, bs, "%dx%d", p->w, p->h);
  782|  74.1k|        if (p->p_w != p->p_h || !p->p_w)
  ------------------
  |  Branch (782:13): [True: 9.26k, False: 64.8k]
  |  Branch (782:33): [True: 0, False: 64.8k]
  ------------------
  783|  9.26k|            mp_snprintf_cat(b, bs, " [%d:%d]", p->p_w, p->p_h);
  784|  74.1k|        mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt));
  ------------------
  |  |  331|  74.1k|#define mp_imgfmt_to_name(fmt) mp_imgfmt_to_name_buf((char[16]){0}, 16, (fmt))
  ------------------
  785|  74.1k|        if (p->hw_subfmt)
  ------------------
  |  Branch (785:13): [True: 0, False: 74.1k]
  ------------------
  786|      0|            mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt));
  ------------------
  |  |  331|      0|#define mp_imgfmt_to_name(fmt) mp_imgfmt_to_name_buf((char[16]){0}, 16, (fmt))
  ------------------
  787|  74.1k|        mp_snprintf_cat(b, bs, " %s/%s/%s/%s/%s",
  788|  74.1k|                        m_opt_choice_str(pl_csp_names, p->repr.sys),
  789|  74.1k|                        m_opt_choice_str(pl_csp_prim_names, p->color.primaries),
  790|  74.1k|                        m_opt_choice_str(pl_csp_trc_names, p->color.transfer),
  791|  74.1k|                        m_opt_choice_str(pl_csp_levels_names, p->repr.levels),
  792|  74.1k|                        m_opt_choice_str(mp_csp_light_names, p->light));
  793|  74.1k|        mp_snprintf_cat(b, bs, " CL=%s",
  794|  74.1k|                        m_opt_choice_str(pl_chroma_names, p->chroma_location));
  795|  74.1k|        if (mp_image_crop_valid(p)) {
  ------------------
  |  Branch (795:13): [True: 74.1k, False: 0]
  ------------------
  796|  74.1k|            mp_snprintf_cat(b, bs, " crop=%dx%d+%d+%d", mp_rect_w(p->crop),
  ------------------
  |  |  128|  74.1k|#define mp_rect_w(r) ((r).x1 - (r).x0)
  ------------------
  797|  74.1k|                            mp_rect_h(p->crop), p->crop.x0, p->crop.y0);
  ------------------
  |  |  129|  74.1k|#define mp_rect_h(r) ((r).y1 - (r).y0)
  ------------------
  798|  74.1k|        }
  799|  74.1k|        if (p->rotate)
  ------------------
  |  Branch (799:13): [True: 0, False: 74.1k]
  ------------------
  800|      0|            mp_snprintf_cat(b, bs, " rot=%d", p->rotate);
  801|  74.1k|        if (p->stereo3d > 0) {
  ------------------
  |  Branch (801:13): [True: 0, False: 74.1k]
  ------------------
  802|      0|            mp_snprintf_cat(b, bs, " stereo=%s",
  803|      0|                            MP_STEREO3D_NAME_DEF(p->stereo3d, "?"));
  ------------------
  |  |   67|      0|    (MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def))
  |  |  ------------------
  |  |  |  |   64|      0|#define MP_STEREO3D_NAME(x) m_opt_choice_str(mp_stereo3d_names, x)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (64:29): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (MP_STEREO3D_NAME(x) ? MP_STEREO3D_NAME(x) : (def))
  |  |  ------------------
  |  |  |  |   64|      0|#define MP_STEREO3D_NAME(x) m_opt_choice_str(mp_stereo3d_names, x)
  |  |  ------------------
  ------------------
  804|      0|        }
  805|  74.1k|        if (p->repr.alpha) {
  ------------------
  |  Branch (805:13): [True: 74.1k, False: 0]
  ------------------
  806|  74.1k|            mp_snprintf_cat(b, bs, " A=%s",
  807|  74.1k|                            m_opt_choice_str(pl_alpha_names, p->repr.alpha));
  808|  74.1k|        }
  809|  74.1k|    } else {
  810|      0|        snprintf(b, bs, "???");
  811|      0|    }
  812|  74.1k|    return b;
  813|  74.1k|}
mp_image_params_equal:
  845|   640k|{
  846|   640k|    return p1->imgfmt == p2->imgfmt &&
  ------------------
  |  Branch (846:12): [True: 542k, False: 97.5k]
  ------------------
  847|   640k|           p1->hw_subfmt == p2->hw_subfmt &&
  ------------------
  |  Branch (847:12): [True: 542k, False: 0]
  ------------------
  848|   640k|           p1->w == p2->w && p1->h == p2->h &&
  ------------------
  |  Branch (848:12): [True: 540k, False: 2.65k]
  |  Branch (848:30): [True: 502k, False: 38.1k]
  ------------------
  849|   640k|           p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
  ------------------
  |  Branch (849:12): [True: 502k, False: 0]
  |  Branch (849:34): [True: 502k, False: 0]
  ------------------
  850|   640k|           p1->force_window == p2->force_window &&
  ------------------
  |  Branch (850:12): [True: 502k, False: 0]
  ------------------
  851|   640k|           pl_color_space_equal(&p1->color, &p2->color) &&
  ------------------
  |  Branch (851:12): [True: 502k, False: 0]
  ------------------
  852|   640k|           pl_color_repr_equal(&p1->repr, &p2->repr) &&
  ------------------
  |  Branch (852:12): [True: 502k, False: 0]
  ------------------
  853|   640k|           p1->light == p2->light &&
  ------------------
  |  Branch (853:12): [True: 502k, False: 0]
  ------------------
  854|   640k|           p1->chroma_location == p2->chroma_location &&
  ------------------
  |  Branch (854:12): [True: 502k, False: 0]
  ------------------
  855|   640k|           p1->vflip == p2->vflip &&
  ------------------
  |  Branch (855:12): [True: 502k, False: 0]
  ------------------
  856|   640k|           p1->rotate == p2->rotate &&
  ------------------
  |  Branch (856:12): [True: 502k, False: 0]
  ------------------
  857|   640k|           p1->stereo3d == p2->stereo3d &&
  ------------------
  |  Branch (857:12): [True: 502k, False: 0]
  ------------------
  858|   640k|           mp_rect_equals(&p1->crop, &p2->crop);
  ------------------
  |  Branch (858:12): [True: 502k, False: 0]
  ------------------
  859|   640k|}
mp_image_params_static_equal:
  863|   136k|{
  864|       |    // Compare only static video parameters, excluding dynamic metadata.
  865|   136k|    struct mp_image_params a = *p1;
  866|   136k|    struct mp_image_params b = *p2;
  867|   136k|    a.repr.dovi = b.repr.dovi = NULL;
  868|   136k|    a.color.hdr = b.color.hdr = (struct pl_hdr_metadata){0};
  869|   136k|    return mp_image_params_equal(&a, &b);
  870|   136k|}
mp_image_params_update_dynamic:
  875|  63.0k|{
  876|  63.0k|    dst->repr.dovi = src->repr.dovi;
  877|       |    // Don't overwrite peak-detected HDR metadata if available.
  878|  63.0k|    float max_pq_y = dst->color.hdr.max_pq_y;
  879|  63.0k|    float avg_pq_y = dst->color.hdr.avg_pq_y;
  880|  63.0k|    dst->color.hdr = src->color.hdr;
  881|  63.0k|    if (has_peak_detect_values) {
  ------------------
  |  Branch (881:9): [True: 0, False: 63.0k]
  ------------------
  882|      0|        dst->color.hdr.max_pq_y = max_pq_y;
  883|      0|        dst->color.hdr.avg_pq_y = avg_pq_y;
  884|      0|    }
  885|  63.0k|}
mp_image_params_guess_csp:
  950|  9.26k|{
  951|  9.26k|    enum pl_color_system forced_csp = mp_image_params_get_forced_csp(params);
  952|  9.26k|    if (forced_csp == PL_COLOR_SYSTEM_UNKNOWN) { // YUV/other
  ------------------
  |  Branch (952:9): [True: 7.19k, False: 2.06k]
  ------------------
  953|  7.19k|        if (params->repr.sys != PL_COLOR_SYSTEM_BT_601 &&
  ------------------
  |  Branch (953:13): [True: 7.19k, False: 0]
  ------------------
  954|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_BT_709 &&
  ------------------
  |  Branch (954:13): [True: 7.13k, False: 65]
  ------------------
  955|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_BT_2020_NC &&
  ------------------
  |  Branch (955:13): [True: 7.13k, False: 0]
  ------------------
  956|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_BT_2020_C &&
  ------------------
  |  Branch (956:13): [True: 7.13k, False: 0]
  ------------------
  957|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_BT_2100_PQ &&
  ------------------
  |  Branch (957:13): [True: 7.13k, False: 0]
  ------------------
  958|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_BT_2100_HLG &&
  ------------------
  |  Branch (958:13): [True: 7.13k, False: 0]
  ------------------
  959|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_DOLBYVISION &&
  ------------------
  |  Branch (959:13): [True: 7.13k, False: 0]
  ------------------
  960|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_SMPTE_240M &&
  ------------------
  |  Branch (960:13): [True: 7.13k, False: 0]
  ------------------
  961|  7.19k|            params->repr.sys != PL_COLOR_SYSTEM_YCGCO)
  ------------------
  |  Branch (961:13): [True: 7.13k, False: 0]
  ------------------
  962|  7.13k|        {
  963|       |            // Makes no sense, so guess instead
  964|       |            // YCGCO should be separate, but libavcodec disagrees
  965|  7.13k|            params->repr.sys = PL_COLOR_SYSTEM_UNKNOWN;
  966|  7.13k|        }
  967|  7.19k|        if (params->repr.sys == PL_COLOR_SYSTEM_UNKNOWN)
  ------------------
  |  Branch (967:13): [True: 7.13k, False: 65]
  ------------------
  968|  7.13k|            params->repr.sys = mp_csp_guess_colorspace(params->w, params->h);
  969|  7.19k|        if (params->repr.levels == PL_COLOR_LEVELS_UNKNOWN) {
  ------------------
  |  Branch (969:13): [True: 7.13k, False: 65]
  ------------------
  970|  7.13k|            if (params->color.transfer == PL_COLOR_TRC_V_LOG) {
  ------------------
  |  Branch (970:17): [True: 0, False: 7.13k]
  ------------------
  971|      0|                params->repr.levels = PL_COLOR_LEVELS_FULL;
  972|  7.13k|            } else {
  973|  7.13k|                params->repr.levels = infer_levels(params->imgfmt);
  974|  7.13k|            }
  975|  7.13k|        }
  976|  7.19k|        if (params->color.primaries == PL_COLOR_PRIM_UNKNOWN) {
  ------------------
  |  Branch (976:13): [True: 7.13k, False: 65]
  ------------------
  977|       |            // Guess based on the colormatrix as a first priority
  978|  7.13k|            if (params->repr.sys == PL_COLOR_SYSTEM_BT_2020_NC ||
  ------------------
  |  Branch (978:17): [True: 0, False: 7.13k]
  ------------------
  979|  7.13k|                params->repr.sys == PL_COLOR_SYSTEM_BT_2020_C) {
  ------------------
  |  Branch (979:17): [True: 0, False: 7.13k]
  ------------------
  980|      0|                params->color.primaries = PL_COLOR_PRIM_BT_2020;
  981|  7.13k|            } else if (params->repr.sys == PL_COLOR_SYSTEM_BT_709) {
  ------------------
  |  Branch (981:24): [True: 0, False: 7.13k]
  ------------------
  982|      0|                params->color.primaries = PL_COLOR_PRIM_BT_709;
  983|  7.13k|            } else {
  984|       |                // Ambiguous colormatrix for BT.601, guess based on res
  985|  7.13k|                params->color.primaries = mp_csp_guess_primaries(params->w, params->h);
  986|  7.13k|            }
  987|  7.13k|        }
  988|  7.19k|        if (params->color.transfer == PL_COLOR_TRC_UNKNOWN)
  ------------------
  |  Branch (988:13): [True: 7.13k, False: 65]
  ------------------
  989|  7.13k|            params->color.transfer = PL_COLOR_TRC_BT_1886;
  990|  7.19k|    } else if (forced_csp == PL_COLOR_SYSTEM_RGB) {
  ------------------
  |  Branch (990:16): [True: 2.06k, False: 0]
  ------------------
  991|  2.06k|        params->repr.sys = PL_COLOR_SYSTEM_RGB;
  992|  2.06k|        params->repr.levels = PL_COLOR_LEVELS_FULL;
  993|       |
  994|       |        // The majority of RGB content is either sRGB or (rarely) some other
  995|       |        // color space which we don't even handle, like AdobeRGB or
  996|       |        // ProPhotoRGB. The only reasonable thing we can do is assume it's
  997|       |        // sRGB and hope for the best, which should usually just work out fine.
  998|       |        // Note: sRGB primaries = BT.709 primaries
  999|  2.06k|        if (params->color.primaries == PL_COLOR_PRIM_UNKNOWN)
  ------------------
  |  Branch (999:13): [True: 2.06k, False: 0]
  ------------------
 1000|  2.06k|            params->color.primaries = PL_COLOR_PRIM_BT_709;
 1001|  2.06k|        if (params->color.transfer == PL_COLOR_TRC_UNKNOWN)
  ------------------
  |  Branch (1001:13): [True: 2.06k, False: 0]
  ------------------
 1002|  2.06k|            params->color.transfer = PL_COLOR_TRC_SRGB;
 1003|  2.06k|    } else if (forced_csp == PL_COLOR_SYSTEM_XYZ) {
  ------------------
  |  Branch (1003:16): [True: 0, False: 0]
  ------------------
 1004|      0|        params->repr.sys = PL_COLOR_SYSTEM_XYZ;
 1005|      0|        params->repr.levels = PL_COLOR_LEVELS_FULL;
 1006|       |        // Force gamma to ST428 as this is the only correct for DCDM X'Y'Z'
 1007|      0|        params->color.transfer = PL_COLOR_TRC_ST428;
 1008|       |        // Don't care about primaries, they shouldn't be used, or if anything
 1009|       |        // MP_CSP_PRIM_ST428 should be defined.
 1010|      0|    } else {
 1011|       |        // We have no clue.
 1012|      0|        params->repr.sys = PL_COLOR_SYSTEM_UNKNOWN;
 1013|      0|        params->repr.levels = PL_COLOR_LEVELS_UNKNOWN;
 1014|      0|        params->color.primaries = PL_COLOR_PRIM_UNKNOWN;
 1015|      0|        params->color.transfer = PL_COLOR_TRC_UNKNOWN;
 1016|      0|    }
 1017|       |
 1018|  9.26k|    if (!params->color.hdr.max_luma) {
  ------------------
  |  Branch (1018:9): [True: 9.26k, False: 0]
  ------------------
 1019|  9.26k|        if (params->color.transfer == PL_COLOR_TRC_HLG) {
  ------------------
  |  Branch (1019:13): [True: 0, False: 9.26k]
  ------------------
 1020|      0|            params->color.hdr.max_luma = 1000; // reference display
 1021|  9.26k|        } else {
 1022|       |            // If the signal peak is unknown, we're forced to pick the TRC's
 1023|       |            // nominal range as the signal peak to prevent clipping
 1024|  9.26k|            params->color.hdr.max_luma = pl_color_transfer_nominal_peak(params->color.transfer) * MP_REF_WHITE;
  ------------------
  |  |   74|  9.26k|#define MP_REF_WHITE 203.0
  ------------------
 1025|  9.26k|        }
 1026|  9.26k|    }
 1027|       |
 1028|  9.26k|    if (!pl_color_space_is_hdr(&params->color)) {
  ------------------
  |  Branch (1028:9): [True: 9.26k, False: 0]
  ------------------
 1029|       |        // Some clips have leftover HDR metadata after conversion to SDR, so to
 1030|       |        // avoid blowing up the tone mapping code, strip/sanitize it
 1031|  9.26k|        params->color.hdr = pl_hdr_metadata_empty;
 1032|  9.26k|    }
 1033|       |
 1034|  9.26k|    if (params->chroma_location == PL_CHROMA_UNKNOWN) {
  ------------------
  |  Branch (1034:9): [True: 9.26k, False: 0]
  ------------------
 1035|  9.26k|        if (params->repr.levels == PL_COLOR_LEVELS_LIMITED)
  ------------------
  |  Branch (1035:13): [True: 8, False: 9.25k]
  ------------------
 1036|      8|            params->chroma_location = PL_CHROMA_LEFT;
 1037|  9.26k|        if (params->repr.levels == PL_COLOR_LEVELS_FULL)
  ------------------
  |  Branch (1037:13): [True: 9.25k, False: 8]
  ------------------
 1038|  9.25k|            params->chroma_location = PL_CHROMA_CENTER;
 1039|  9.26k|    }
 1040|       |
 1041|  9.26k|    if (params->light == MP_CSP_LIGHT_AUTO) {
  ------------------
  |  Branch (1041:9): [True: 9.26k, False: 0]
  ------------------
 1042|       |        // HLG is always scene-referred (using its own OOTF), everything else
 1043|       |        // we assume is display-referred by default.
 1044|  9.26k|        if (params->color.transfer == PL_COLOR_TRC_HLG) {
  ------------------
  |  Branch (1044:13): [True: 0, False: 9.26k]
  ------------------
 1045|      0|            params->light = MP_CSP_LIGHT_SCENE_HLG;
 1046|  9.26k|        } else {
 1047|  9.26k|            params->light = MP_CSP_LIGHT_DISPLAY;
 1048|  9.26k|        }
 1049|  9.26k|    }
 1050|  9.26k|}
mp_image_from_av_frame:
 1054|  71.9k|{
 1055|  71.9k|    struct mp_image *dst = &(struct mp_image){0};
 1056|  71.9k|    AVFrameSideData *sd;
 1057|       |
 1058|   359k|    for (int p = 0; p < MP_MAX_PLANES; p++)
  ------------------
  |  |   28|   359k|#define MP_MAX_PLANES 4
  ------------------
  |  Branch (1058:21): [True: 287k, False: 71.9k]
  ------------------
 1059|   287k|        dst->bufs[p] = src->buf[p];
 1060|       |
 1061|  71.9k|    dst->hwctx = src->hw_frames_ctx;
 1062|       |
 1063|  71.9k|    mp_image_setfmt(dst, pixfmt2imgfmt(src->format));
 1064|  71.9k|    mp_image_set_size(dst, src->width, src->height);
 1065|       |
 1066|  71.9k|    dst->params.p_w = src->sample_aspect_ratio.num;
 1067|  71.9k|    dst->params.p_h = src->sample_aspect_ratio.den;
 1068|       |
 1069|   359k|    for (int i = 0; i < 4; i++) {
  ------------------
  |  Branch (1069:21): [True: 287k, False: 71.9k]
  ------------------
 1070|   287k|        dst->planes[i] = src->data[i];
 1071|   287k|        dst->stride[i] = src->linesize[i];
 1072|   287k|    }
 1073|       |
 1074|  71.9k|    dst->pict_type = src->pict_type;
 1075|       |
 1076|  71.9k|    dst->params.crop.x0 = src->crop_left;
 1077|  71.9k|    dst->params.crop.y0 = src->crop_top;
 1078|  71.9k|    dst->params.crop.x1 = src->width - src->crop_right;
 1079|  71.9k|    dst->params.crop.y1 = src->height - src->crop_bottom;
 1080|       |
 1081|  71.9k|    dst->fields = 0;
 1082|  71.9k|    if (src->flags & AV_FRAME_FLAG_INTERLACED)
  ------------------
  |  Branch (1082:9): [True: 0, False: 71.9k]
  ------------------
 1083|      0|        dst->fields |= MP_IMGFIELD_INTERLACED;
  ------------------
  |  |   39|      0|#define MP_IMGFIELD_INTERLACED 0x20
  ------------------
 1084|  71.9k|    if (src->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)
  ------------------
  |  Branch (1084:9): [True: 0, False: 71.9k]
  ------------------
 1085|      0|        dst->fields |= MP_IMGFIELD_TOP_FIRST;
  ------------------
  |  |   37|      0|#define MP_IMGFIELD_TOP_FIRST 0x02
  ------------------
 1086|  71.9k|    if (src->repeat_pict == 1)
  ------------------
  |  Branch (1086:9): [True: 0, False: 71.9k]
  ------------------
 1087|      0|        dst->fields |= MP_IMGFIELD_REPEAT_FIRST;
  ------------------
  |  |   38|      0|#define MP_IMGFIELD_REPEAT_FIRST 0x04
  ------------------
 1088|       |
 1089|  71.9k|    dst->params.repr.sys = pl_system_from_av(src->colorspace);
 1090|  71.9k|    dst->params.repr.levels = pl_levels_from_av(src->color_range);
 1091|       |
 1092|  71.9k|    dst->params.color = (struct pl_color_space){
 1093|  71.9k|        .primaries = pl_primaries_from_av(src->color_primaries),
 1094|  71.9k|        .transfer = pl_transfer_from_av(src->color_trc),
 1095|  71.9k|    };
 1096|       |
 1097|  71.9k|    dst->params.chroma_location = pl_chroma_from_av(src->chroma_location);
 1098|       |
 1099|  71.9k|    if (src->opaque_ref) {
  ------------------
  |  Branch (1099:9): [True: 0, False: 71.9k]
  ------------------
 1100|      0|        struct mp_image_params *p = (void *)src->opaque_ref->data;
 1101|      0|        dst->params.stereo3d = p->stereo3d;
 1102|       |        // Might be incorrect if colorspace changes.
 1103|      0|        dst->params.light = p->light;
 1104|      0|        dst->params.repr.alpha = p->repr.alpha;
 1105|      0|    }
 1106|       |
 1107|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_DISPLAYMATRIX);
 1108|  71.9k|    if (sd) {
  ------------------
  |  Branch (1108:9): [True: 0, False: 71.9k]
  ------------------
 1109|      0|        int32_t *matrix = (int32_t *) sd->data;
 1110|       |        // determinant
 1111|      0|        int vflip = ((int64_t)matrix[0] * (int64_t)matrix[4]
 1112|      0|                    - (int64_t)matrix[1] * (int64_t)matrix[3]) < 0;
 1113|      0|        double r = av_display_rotation_get(matrix);
 1114|      0|        if (!isnan(r)) {
  ------------------
  |  Branch (1114:13): [True: 0, False: 0]
  ------------------
 1115|      0|            dst->params.rotate = (((int)(-r) % 360) + 360) % 360;
 1116|      0|            dst->params.vflip = vflip;
 1117|      0|        }
 1118|      0|    }
 1119|       |
 1120|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_ICC_PROFILE);
 1121|  71.9k|    if (sd)
  ------------------
  |  Branch (1121:9): [True: 0, False: 71.9k]
  ------------------
 1122|      0|        dst->icc_profile = sd->buf;
 1123|       |
 1124|  71.9k|    AVFrameSideData *mdm = av_frame_get_side_data(src, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
 1125|  71.9k|    AVFrameSideData *clm = av_frame_get_side_data(src, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
 1126|  71.9k|    AVFrameSideData *dhp = av_frame_get_side_data(src, AV_FRAME_DATA_DYNAMIC_HDR_PLUS);
 1127|  71.9k|    pl_map_hdr_metadata(&dst->params.color.hdr, &(struct pl_av_hdr_metadata) {
 1128|  71.9k|        .mdm = (void *)(mdm ? mdm->data : NULL),
  ------------------
  |  Branch (1128:25): [True: 0, False: 71.9k]
  ------------------
 1129|  71.9k|        .clm = (void *)(clm ? clm->data : NULL),
  ------------------
  |  Branch (1129:25): [True: 0, False: 71.9k]
  ------------------
 1130|  71.9k|        .dhp = (void *)(dhp ? dhp->data : NULL),
  ------------------
  |  Branch (1130:25): [True: 0, False: 71.9k]
  ------------------
 1131|  71.9k|    });
 1132|       |
 1133|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_A53_CC);
 1134|  71.9k|    if (sd)
  ------------------
  |  Branch (1134:9): [True: 0, False: 71.9k]
  ------------------
 1135|      0|        dst->a53_cc = sd->buf;
 1136|       |
 1137|  71.9k|    dst->params.primaries_orig = dst->params.color.primaries;
 1138|  71.9k|    dst->params.transfer_orig = dst->params.color.transfer;
 1139|  71.9k|    dst->params.sys_orig = dst->params.repr.sys;
 1140|  71.9k|    AVBufferRef *dovi = NULL;
 1141|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_METADATA);
 1142|  71.9k|    if (sd) {
  ------------------
  |  Branch (1142:9): [True: 0, False: 71.9k]
  ------------------
 1143|      0|#ifdef PL_HAVE_LAV_DOLBY_VISION
 1144|      0|        const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->buf->data;
 1145|      0|        const AVDOVIRpuDataHeader *header = av_dovi_get_header(metadata);
 1146|      0|        if (header->disable_residual_flag) {
  ------------------
  |  Branch (1146:13): [True: 0, False: 0]
  ------------------
 1147|      0|            dst->dovi = dovi = av_buffer_alloc(sizeof(struct pl_dovi_metadata));
 1148|      0|            MP_HANDLE_OOM(dovi);
  ------------------
  |  |  176|      0|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|      0|        void *oom_p_ = (x);     \
  |  |  178|      0|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  179|      0|            abort();            \
  |  |  180|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1149|      0|#if PL_API_VER >= 343
 1150|      0|            pl_map_avdovi_metadata(&dst->params.color, &dst->params.repr,
 1151|      0|                                   (void *)dst->dovi->data, metadata);
 1152|       |#else
 1153|       |            struct pl_frame frame;
 1154|       |            frame.repr = dst->params.repr;
 1155|       |            frame.color = dst->params.color;
 1156|       |            pl_frame_map_avdovi_metadata(&frame, (void *)dst->dovi->data, metadata);
 1157|       |            dst->params.repr = frame.repr;
 1158|       |            dst->params.color = frame.color;
 1159|       |#endif
 1160|      0|        }
 1161|      0|#endif
 1162|      0|    }
 1163|       |
 1164|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_DOVI_RPU_BUFFER);
 1165|  71.9k|    if (sd) {
  ------------------
  |  Branch (1165:9): [True: 0, False: 71.9k]
  ------------------
 1166|      0|        pl_hdr_metadata_from_dovi_rpu(&dst->params.color.hdr, sd->buf->data,
 1167|      0|                                      sd->buf->size);
 1168|      0|    }
 1169|       |
 1170|  71.9k|    sd = av_frame_get_side_data(src, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
 1171|  71.9k|    if (sd)
  ------------------
  |  Branch (1171:9): [True: 0, False: 71.9k]
  ------------------
 1172|      0|        dst->film_grain = sd->buf;
 1173|       |
 1174|  71.9k|    for (int n = 0; n < src->nb_side_data; n++) {
  ------------------
  |  Branch (1174:21): [True: 0, False: 71.9k]
  ------------------
 1175|      0|        sd = src->side_data[n];
 1176|      0|        struct mp_ff_side_data mpsd = {
 1177|      0|            .type = sd->type,
 1178|      0|            .buf = sd->buf,
 1179|      0|        };
 1180|      0|        MP_TARRAY_APPEND(NULL, dst->ff_side_data, dst->num_ff_side_data, mpsd);
  ------------------
  |  |  105|      0|    do {                                            \
  |  |  106|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  107|      0|        (p)[(idxvar)] = (__VA_ARGS__);              \
  |  |  108|      0|        (idxvar)++;                                 \
  |  |  109|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (109:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1181|      0|    }
 1182|       |
 1183|  71.9k|    if (dst->hwctx) {
  ------------------
  |  Branch (1183:9): [True: 0, False: 71.9k]
  ------------------
 1184|      0|        AVHWFramesContext *fctx = (void *)dst->hwctx->data;
 1185|      0|        dst->params.hw_subfmt = pixfmt2imgfmt(fctx->sw_format);
 1186|      0|    }
 1187|       |
 1188|  71.9k|    struct mp_image *res = mp_image_new_ref(dst);
 1189|       |
 1190|       |    // Allocated, but non-refcounted data.
 1191|  71.9k|    talloc_free(dst->ff_side_data);
  ------------------
  |  |   47|  71.9k|#define talloc_free                     ta_free
  ------------------
 1192|  71.9k|    av_buffer_unref(&dovi);
 1193|       |
 1194|  71.9k|    return res;
 1195|  71.9k|}
mp_image.c:mp_image_destructor:
  211|   216k|{
  212|   216k|    mp_image_t *mpi = ptr;
  213|  1.08M|    for (int p = 0; p < MP_MAX_PLANES; p++)
  ------------------
  |  |   28|  1.08M|#define MP_MAX_PLANES 4
  ------------------
  |  Branch (213:21): [True: 865k, False: 216k]
  ------------------
  214|   865k|        av_buffer_unref(&mpi->bufs[p]);
  215|   216k|    av_buffer_unref(&mpi->hwctx);
  216|   216k|    av_buffer_unref(&mpi->icc_profile);
  217|   216k|    av_buffer_unref(&mpi->a53_cc);
  218|   216k|    av_buffer_unref(&mpi->dovi);
  219|   216k|    av_buffer_unref(&mpi->film_grain);
  220|   216k|    for (int n = 0; n < mpi->num_ff_side_data; n++)
  ------------------
  |  Branch (220:21): [True: 0, False: 216k]
  ------------------
  221|      0|        av_buffer_unref(&mpi->ff_side_data[n].buf);
  222|   216k|    talloc_free(mpi->ff_side_data);
  ------------------
  |  |   47|   216k|#define talloc_free                     ta_free
  ------------------
  223|   216k|}
mp_image.c:ref_buffer:
  325|  1.94M|{
  326|  1.94M|    if (*dst) {
  ------------------
  |  Branch (326:9): [True: 391k, False: 1.55M]
  ------------------
  327|   391k|        *dst = av_buffer_ref(*dst);
  328|   391k|        MP_HANDLE_OOM(*dst);
  ------------------
  |  |  176|   391k|#define MP_HANDLE_OOM(x) do {   \
  |  |  177|   391k|        void *oom_p_ = (x);     \
  |  |  178|   391k|        if (!oom_p_)            \
  |  |  ------------------
  |  |  |  Branch (178:13): [True: 0, False: 391k]
  |  |  ------------------
  |  |  179|   391k|            abort();            \
  |  |  180|   391k|    } while (0)
  |  |  ------------------
  |  |  |  Branch (180:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  329|   391k|    }
  330|  1.94M|}
mp_image.c:mp_image_params_get_forced_csp:
  500|  9.26k|{
  501|  9.26k|    int imgfmt = params->hw_subfmt ? params->hw_subfmt : params->imgfmt;
  ------------------
  |  Branch (501:18): [True: 0, False: 9.26k]
  ------------------
  502|  9.26k|    enum pl_color_system csp = mp_imgfmt_get_forced_csp(imgfmt);
  503|       |
  504|  9.26k|    if (csp == PL_COLOR_SYSTEM_RGB && params->repr.sys == PL_COLOR_SYSTEM_XYZ)
  ------------------
  |  Branch (504:9): [True: 2.06k, False: 7.19k]
  |  Branch (504:39): [True: 0, False: 2.06k]
  ------------------
  505|      0|        csp = PL_COLOR_SYSTEM_XYZ;
  506|       |
  507|  9.26k|    return csp;
  508|  9.26k|}
mp_image.c:infer_levels:
  919|  7.13k|{
  920|  7.13k|    switch (imgfmt2pixfmt(imgfmt)) {
  921|      0|    case AV_PIX_FMT_YUVJ420P:
  ------------------
  |  Branch (921:5): [True: 0, False: 7.13k]
  ------------------
  922|      0|    case AV_PIX_FMT_YUVJ411P:
  ------------------
  |  Branch (922:5): [True: 0, False: 7.13k]
  ------------------
  923|      0|    case AV_PIX_FMT_YUVJ422P:
  ------------------
  |  Branch (923:5): [True: 0, False: 7.13k]
  ------------------
  924|      0|    case AV_PIX_FMT_YUVJ444P:
  ------------------
  |  Branch (924:5): [True: 0, False: 7.13k]
  ------------------
  925|      0|    case AV_PIX_FMT_YUVJ440P:
  ------------------
  |  Branch (925:5): [True: 0, False: 7.13k]
  ------------------
  926|  5.55k|    case AV_PIX_FMT_GRAY8:
  ------------------
  |  Branch (926:5): [True: 5.55k, False: 1.58k]
  ------------------
  927|  5.55k|    case AV_PIX_FMT_YA8:
  ------------------
  |  Branch (927:5): [True: 0, False: 7.13k]
  ------------------
  928|  5.55k|    case AV_PIX_FMT_GRAY9LE:
  ------------------
  |  Branch (928:5): [True: 0, False: 7.13k]
  ------------------
  929|  5.55k|    case AV_PIX_FMT_GRAY9BE:
  ------------------
  |  Branch (929:5): [True: 0, False: 7.13k]
  ------------------
  930|  5.55k|    case AV_PIX_FMT_GRAY10LE:
  ------------------
  |  Branch (930:5): [True: 0, False: 7.13k]
  ------------------
  931|  5.55k|    case AV_PIX_FMT_GRAY10BE:
  ------------------
  |  Branch (931:5): [True: 0, False: 7.13k]
  ------------------
  932|  5.55k|    case AV_PIX_FMT_GRAY12LE:
  ------------------
  |  Branch (932:5): [True: 0, False: 7.13k]
  ------------------
  933|  5.55k|    case AV_PIX_FMT_GRAY12BE:
  ------------------
  |  Branch (933:5): [True: 0, False: 7.13k]
  ------------------
  934|  5.55k|    case AV_PIX_FMT_GRAY14LE:
  ------------------
  |  Branch (934:5): [True: 0, False: 7.13k]
  ------------------
  935|  5.55k|    case AV_PIX_FMT_GRAY14BE:
  ------------------
  |  Branch (935:5): [True: 0, False: 7.13k]
  ------------------
  936|  7.12k|    case AV_PIX_FMT_GRAY16LE:
  ------------------
  |  Branch (936:5): [True: 1.57k, False: 5.56k]
  ------------------
  937|  7.12k|    case AV_PIX_FMT_GRAY16BE:
  ------------------
  |  Branch (937:5): [True: 0, False: 7.13k]
  ------------------
  938|  7.12k|    case AV_PIX_FMT_YA16BE:
  ------------------
  |  Branch (938:5): [True: 0, False: 7.13k]
  ------------------
  939|  7.12k|    case AV_PIX_FMT_YA16LE:
  ------------------
  |  Branch (939:5): [True: 0, False: 7.13k]
  ------------------
  940|  7.12k|        return PL_COLOR_LEVELS_FULL;
  941|      8|    default:
  ------------------
  |  Branch (941:5): [True: 8, False: 7.12k]
  ------------------
  942|      8|        return PL_COLOR_LEVELS_LIMITED;
  943|  7.13k|    }
  944|  7.13k|}

mp_image_pool_new:
   79|  15.1k|{
   80|  15.1k|    struct mp_image_pool *pool = talloc_ptrtype(tparent, pool);
  ------------------
  |  |   34|  15.1k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  15.1k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  15.1k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   81|  15.1k|    talloc_set_destructor(pool, image_pool_destructor);
  ------------------
  |  |   41|  15.1k|#define talloc_set_destructor           ta_set_destructor
  ------------------
   82|  15.1k|    *pool = (struct mp_image_pool) {0};
   83|  15.1k|    return pool;
   84|  15.1k|}
mp_image_pool_clear:
   87|  15.9k|{
   88|  15.9k|    for (int n = 0; n < pool->num_images; n++) {
  ------------------
  |  Branch (88:21): [True: 0, False: 15.9k]
  ------------------
   89|      0|        struct mp_image *img = pool->images[n];
   90|      0|        struct image_flags *it = img->priv;
   91|      0|        bool referenced;
   92|      0|        pool_lock();
  ------------------
  |  |   42|      0|#define pool_lock() mp_mutex_lock(&pool_mutex)
  |  |  ------------------
  |  |  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
   93|      0|        mp_assert(it->pool_alive);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
   94|      0|        it->pool_alive = false;
   95|      0|        referenced = it->referenced;
   96|      0|        pool_unlock();
  ------------------
  |  |   43|      0|#define pool_unlock() mp_mutex_unlock(&pool_mutex)
  |  |  ------------------
  |  |  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
   97|      0|        if (!referenced)
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            talloc_free(img);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
   99|      0|    }
  100|  15.9k|    pool->num_images = 0;
  101|  15.9k|}
mp_image_pool_get_no_alloc:
  123|    805|{
  124|    805|    struct mp_image *new = NULL;
  125|    805|    pool_lock();
  ------------------
  |  |   42|    805|#define pool_lock() mp_mutex_lock(&pool_mutex)
  |  |  ------------------
  |  |  |  |  131|    805|#define mp_mutex_lock       pthread_mutex_lock
  |  |  ------------------
  ------------------
  126|    805|    for (int n = 0; n < pool->num_images; n++) {
  ------------------
  |  Branch (126:21): [True: 0, False: 805]
  ------------------
  127|      0|        struct mp_image *img = pool->images[n];
  128|      0|        struct image_flags *img_it = img->priv;
  129|      0|        mp_assert(img_it->pool_alive);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  130|      0|        if (!img_it->referenced) {
  ------------------
  |  Branch (130:13): [True: 0, False: 0]
  ------------------
  131|      0|            if (img->imgfmt == fmt && img->w == w && img->h == h) {
  ------------------
  |  Branch (131:17): [True: 0, False: 0]
  |  Branch (131:39): [True: 0, False: 0]
  |  Branch (131:54): [True: 0, False: 0]
  ------------------
  132|      0|                if (pool->use_lru) {
  ------------------
  |  Branch (132:21): [True: 0, False: 0]
  ------------------
  133|      0|                    struct image_flags *new_it = new ? new->priv : NULL;
  ------------------
  |  Branch (133:50): [True: 0, False: 0]
  ------------------
  134|      0|                    if (!new_it || new_it->order > img_it->order)
  ------------------
  |  Branch (134:25): [True: 0, False: 0]
  |  Branch (134:36): [True: 0, False: 0]
  ------------------
  135|      0|                        new = img;
  136|      0|                } else {
  137|      0|                    new = img;
  138|      0|                    break;
  139|      0|                }
  140|      0|            }
  141|      0|        }
  142|      0|    }
  143|    805|    pool_unlock();
  ------------------
  |  |   43|    805|#define pool_unlock() mp_mutex_unlock(&pool_mutex)
  |  |  ------------------
  |  |  |  |  133|    805|#define mp_mutex_unlock     pthread_mutex_unlock
  |  |  ------------------
  ------------------
  144|    805|    if (!new)
  ------------------
  |  Branch (144:9): [True: 805, False: 0]
  ------------------
  145|    805|        return NULL;
  146|       |
  147|       |    // Reference the new image. Since mp_image_pool is not declared thread-safe,
  148|       |    // and unreffing images from other threads does not allocate new images,
  149|       |    // no synchronization is required here.
  150|      0|    for (int p = 0; p < MP_MAX_PLANES; p++)
  ------------------
  |  |   28|      0|#define MP_MAX_PLANES 4
  ------------------
  |  Branch (150:21): [True: 0, False: 0]
  ------------------
  151|      0|        mp_assert(!!new->bufs[p] == !p); // only 1 AVBufferRef
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  152|       |
  153|      0|    struct mp_image *ref = mp_image_new_dummy_ref(new);
  154|       |
  155|       |    // This assumes the buffer is at this point exclusively owned by us: we
  156|       |    // can't track whether the buffer is unique otherwise.
  157|       |    // (av_buffer_is_writable() checks the refcount of the new buffer only.)
  158|      0|    int flags = av_buffer_is_writable(new->bufs[0]) ? 0 : AV_BUFFER_FLAG_READONLY;
  ------------------
  |  Branch (158:17): [True: 0, False: 0]
  ------------------
  159|      0|    ref->bufs[0] = av_buffer_create(new->bufs[0]->data, new->bufs[0]->size,
  160|      0|                                    unref_image, new, flags);
  161|      0|    if (!ref->bufs[0]) {
  ------------------
  |  Branch (161:9): [True: 0, False: 0]
  ------------------
  162|      0|        talloc_free(ref);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  163|      0|        return NULL;
  164|      0|    }
  165|       |
  166|      0|    struct image_flags *it = new->priv;
  167|      0|    mp_assert(!it->referenced && it->pool_alive);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  168|      0|    it->referenced = true;
  169|      0|    it->order = ++pool->lru_counter;
  170|      0|    return ref;
  171|      0|}
mp_image_pool.c:image_pool_destructor:
   72|  15.1k|{
   73|  15.1k|    struct mp_image_pool *pool = ptr;
   74|  15.1k|    mp_image_pool_clear(pool);
   75|  15.1k|}

context.c:get_desc:
  147|  11.6k|{
  148|  11.6k|    if (index >= MP_ARRAY_SIZE(contexts))
  ------------------
  |  |   48|  11.6k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (148:9): [True: 5.81k, False: 5.81k]
  ------------------
  149|  5.81k|        return false;
  150|  5.81k|    const struct ra_ctx_fns *ctx = contexts[index];
  151|  5.81k|    *dst = (struct m_obj_desc) {
  152|  5.81k|        .name = ctx->name,
  153|  5.81k|        .description = ctx->description,
  154|  5.81k|    };
  155|  5.81k|    return true;
  156|  11.6k|}
context.c:get_type_desc:
  173|  11.6k|{
  174|  11.6k|    int api_index = 0;
  175|       |
  176|  17.4k|    for (int i = 0; i < MP_ARRAY_SIZE(contexts); i++) {
  ------------------
  |  |   48|  17.4k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (176:21): [True: 11.6k, False: 5.81k]
  ------------------
  177|  11.6k|        if (i && strcmp(contexts[i - 1]->type, contexts[i]->type))
  ------------------
  |  Branch (177:13): [True: 0, False: 11.6k]
  |  Branch (177:18): [True: 0, False: 0]
  ------------------
  178|      0|            api_index++;
  179|       |
  180|  11.6k|        if (api_index == index) {
  ------------------
  |  Branch (180:13): [True: 5.81k, False: 5.81k]
  ------------------
  181|  5.81k|            *dst = (struct m_obj_desc) {
  182|  5.81k|                .name = contexts[i]->type,
  183|  5.81k|                .description = "",
  184|  5.81k|            };
  185|  5.81k|            return true;
  186|  5.81k|        }
  187|  11.6k|    }
  188|       |
  189|  5.81k|    return false;
  190|  11.6k|}

init_best_video_out:
  335|  2.78k|{
  336|  2.78k|    struct mp_vo_opts *opts = mp_get_config_group(NULL, global, &vo_sub_opts);
  337|  2.78k|    struct m_obj_settings *vo_list = opts->video_driver_list;
  338|  2.78k|    struct vo *vo = NULL;
  339|       |    // first try the preferred drivers, with their optional subdevice param:
  340|  2.78k|    if (vo_list && vo_list[0].name) {
  ------------------
  |  Branch (340:9): [True: 2.78k, False: 0]
  |  Branch (340:20): [True: 2.78k, False: 0]
  ------------------
  341|  2.78k|        for (int n = 0; vo_list[n].name; n++) {
  ------------------
  |  Branch (341:25): [True: 2.78k, False: 0]
  ------------------
  342|       |            // Something like "-vo name," allows fallback to autoprobing.
  343|  2.78k|            if (strlen(vo_list[n].name) == 0)
  ------------------
  |  Branch (343:17): [True: 0, False: 2.78k]
  ------------------
  344|      0|                goto autoprobe;
  345|  2.78k|            bool p = !!vo_list[n + 1].name;
  346|  2.78k|            vo = vo_create(p, global, ex, vo_list[n].name);
  347|  2.78k|            if (vo)
  ------------------
  |  Branch (347:17): [True: 2.78k, False: 0]
  ------------------
  348|  2.78k|                goto done;
  349|  2.78k|        }
  350|      0|        goto done;
  351|  2.78k|    }
  352|      0|autoprobe:
  353|       |    // now try the rest...
  354|      0|    for (int i = 0; i < MP_ARRAY_SIZE(video_out_drivers); i++) {
  ------------------
  |  |   48|      0|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (354:21): [True: 0, False: 0]
  ------------------
  355|      0|        const struct vo_driver *driver = video_out_drivers[i];
  356|      0|        if (driver == &video_out_null)
  ------------------
  |  Branch (356:13): [True: 0, False: 0]
  ------------------
  357|      0|            break;
  358|      0|        vo = vo_create(true, global, ex, (char *)driver->name);
  359|      0|        if (vo)
  ------------------
  |  Branch (359:13): [True: 0, False: 0]
  ------------------
  360|      0|            goto done;
  361|      0|    }
  362|  2.78k|done:
  363|  2.78k|    talloc_free(opts);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
  364|  2.78k|    return vo;
  365|      0|}
vo_destroy:
  375|  2.78k|{
  376|  2.78k|    struct vo_internal *in = vo->in;
  377|  2.78k|    mp_dispatch_run(in->dispatch, terminate_vo, vo);
  378|  2.78k|    mp_thread_join(vo->in->thread);
  ------------------
  |  |  212|  2.78k|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  379|  2.78k|    dealloc_vo(vo);
  380|  2.78k|}
vo_reconfig2:
  650|  9.26k|{
  651|  9.26k|    int ret;
  652|  9.26k|    void *p[] = {vo, img, &ret};
  653|  9.26k|    mp_dispatch_run(vo->in->dispatch, run_reconfig, p);
  654|  9.26k|    return ret;
  655|  9.26k|}
vo_control:
  670|  6.85k|{
  671|  6.85k|    int ret;
  672|  6.85k|    void *p[] = {vo, (void *)(intptr_t)request, data, &ret};
  673|  6.85k|    mp_dispatch_run(vo->in->dispatch, run_control, p);
  674|  6.85k|    return ret;
  675|  6.85k|}
vo_control_async:
  680|  50.9k|{
  681|  50.9k|    void *p[4] = {vo, (void *)(intptr_t)request, NULL, NULL};
  682|  50.9k|    void **d = talloc_memdup(NULL, p, sizeof(p));
  ------------------
  |  |   49|  50.9k|#define talloc_memdup                   ta_xmemdup
  |  |  ------------------
  |  |  |  |  157|  50.9k|#define ta_xmemdup(...)         ta_dbg_set_loc(ta_xmemdup(__VA_ARGS__), TA_LOC)
  |  |  |  |  ------------------
  |  |  |  |  |  |   43|  50.9k|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  50.9k|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   37|  50.9k|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  683|       |
  684|  50.9k|    switch (request) {
  685|  44.1k|    case VOCTRL_UPDATE_PLAYBACK_STATE:
  ------------------
  |  Branch (685:5): [True: 44.1k, False: 6.88k]
  ------------------
  686|  44.1k|        d[2] = talloc_dup(d, (struct voctrl_playback_state *)data);
  ------------------
  |  |   48|  44.1k|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|  44.1k|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  44.1k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  687|  44.1k|        break;
  688|  1.41k|    case VOCTRL_KILL_SCREENSAVER:
  ------------------
  |  Branch (688:5): [True: 1.41k, False: 49.5k]
  ------------------
  689|  6.88k|    case VOCTRL_RESTORE_SCREENSAVER:
  ------------------
  |  Branch (689:5): [True: 5.46k, False: 45.5k]
  ------------------
  690|  6.88k|        break;
  691|      0|    default:
  ------------------
  |  Branch (691:5): [True: 0, False: 50.9k]
  ------------------
  692|      0|        abort(); // requires explicit support
  693|  50.9k|    }
  694|       |
  695|  50.9k|    mp_dispatch_enqueue_autofree(vo->in->dispatch, run_control, d);
  696|  50.9k|}
vo_wait_default:
  720|   115k|{
  721|   115k|    struct vo_internal *in = vo->in;
  722|       |
  723|   115k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   115k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  724|   115k|    if (!in->need_wakeup)
  ------------------
  |  Branch (724:9): [True: 112k, False: 3.05k]
  ------------------
  725|   112k|        mp_cond_timedwait_until(&in->wakeup, &in->lock, until_time);
  726|   115k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   115k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  727|   115k|}
vo_wakeup:
  757|  84.1k|{
  758|  84.1k|    struct vo_internal *in = vo->in;
  759|       |
  760|  84.1k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  84.1k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  761|  84.1k|    wakeup_locked(vo);
  762|  84.1k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  84.1k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  763|  84.1k|}
vo_still_displaying:
  812|  10.0k|{
  813|  10.0k|    mp_mutex_lock(&vo->in->lock);
  ------------------
  |  |  131|  10.0k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  814|  10.0k|    bool res = still_displaying(vo);
  815|  10.0k|    mp_mutex_unlock(&vo->in->lock);
  ------------------
  |  |  133|  10.0k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  816|  10.0k|    return res;
  817|  10.0k|}
vo_is_ready_for_frame:
  841|  75.0k|{
  842|  75.0k|    struct vo_internal *in = vo->in;
  843|  75.0k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  75.0k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  844|  75.0k|    bool blocked = vo->driver->initially_blocked &&
  ------------------
  |  Branch (844:20): [True: 0, False: 75.0k]
  ------------------
  845|  75.0k|                   !(in->internal_events & VO_EVENT_INITIAL_UNBLOCK);
  ------------------
  |  Branch (845:20): [True: 0, False: 0]
  ------------------
  846|  75.0k|    bool r = vo->config_ok && !in->frame_queued && !blocked &&
  ------------------
  |  Branch (846:14): [True: 73.5k, False: 1.46k]
  |  Branch (846:31): [True: 73.2k, False: 342]
  |  Branch (846:52): [True: 73.2k, False: 0]
  ------------------
  847|  75.0k|             (!in->current_frame || in->current_frame->num_vsyncs < 1);
  ------------------
  |  Branch (847:15): [True: 9.26k, False: 63.9k]
  |  Branch (847:37): [True: 63.9k, False: 0]
  ------------------
  848|  75.0k|    if (r && next_pts >= 0) {
  ------------------
  |  Branch (848:9): [True: 73.2k, False: 1.80k]
  |  Branch (848:14): [True: 71.9k, False: 1.22k]
  ------------------
  849|       |        // Don't show the frame too early - it would basically freeze the
  850|       |        // display by disallowing OSD redrawing or VO interaction.
  851|       |        // Actually render the frame at earliest the given offset before target
  852|       |        // time.
  853|  71.9k|        next_pts -= in->timing_offset;
  854|  71.9k|        next_pts -= in->flip_queue_offset;
  855|  71.9k|        int64_t now = mp_time_ns();
  856|  71.9k|        if (next_pts > now)
  ------------------
  |  Branch (856:13): [True: 0, False: 71.9k]
  ------------------
  857|      0|            r = false;
  858|  71.9k|        if (!in->wakeup_pts || next_pts < in->wakeup_pts) {
  ------------------
  |  Branch (858:13): [True: 71.9k, False: 46]
  |  Branch (858:32): [True: 46, False: 0]
  ------------------
  859|  71.9k|            in->wakeup_pts = next_pts;
  860|       |            // If we have to wait, update the vo thread's timer.
  861|  71.9k|            if (!r)
  ------------------
  |  Branch (861:17): [True: 0, False: 71.9k]
  ------------------
  862|      0|                wakeup_locked(vo);
  863|  71.9k|        }
  864|  71.9k|    }
  865|  75.0k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  75.0k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  866|  75.0k|    return r;
  867|  75.0k|}
vo_queue_frame:
  883|  71.9k|{
  884|  71.9k|    struct vo_internal *in = vo->in;
  885|  71.9k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  71.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  886|  71.9k|    mp_assert(vo->config_ok && !in->frame_queued &&
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  887|  71.9k|           (!in->current_frame || in->current_frame->num_vsyncs < 1));
  888|  71.9k|    in->hasframe = true;
  889|  71.9k|    frame->frame_id = ++(in->current_frame_id);
  890|  71.9k|    in->frame_queued = frame;
  891|  71.9k|    in->wakeup_pts = frame->display_synced
  ------------------
  |  Branch (891:22): [True: 0, False: 71.9k]
  ------------------
  892|  71.9k|                   ? 0 : frame->pts + MPMAX(frame->duration, 0);
  ------------------
  |  |   43|   143k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 71.9k]
  |  |  ------------------
  ------------------
  893|  71.9k|    wakeup_locked(vo);
  894|  71.9k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  71.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  895|  71.9k|}
vo_wait_frame:
  900|    561|{
  901|    561|    struct vo_internal *in = vo->in;
  902|    561|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|    561|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  903|  1.12k|    while (in->frame_queued || in->rendering)
  ------------------
  |  Branch (903:12): [True: 561, False: 561]
  |  Branch (903:32): [True: 0, False: 561]
  ------------------
  904|    561|        mp_cond_wait(&in->wakeup, &in->lock);
  905|    561|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|    561|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  906|    561|}
vo_set_paused:
 1225|  2.07k|{
 1226|  2.07k|    struct vo_internal *in = vo->in;
 1227|  2.07k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  2.07k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1228|  2.07k|    if (in->paused != paused) {
  ------------------
  |  Branch (1228:9): [True: 42, False: 2.02k]
  ------------------
 1229|     42|        in->paused = paused;
 1230|     42|        if (in->paused && in->dropped_frame) {
  ------------------
  |  Branch (1230:13): [True: 21, False: 21]
  |  Branch (1230:27): [True: 0, False: 21]
  ------------------
 1231|      0|            in->request_redraw = true;
 1232|      0|            wakeup_core(vo);
 1233|      0|        }
 1234|     42|        reset_vsync_timings(vo);
 1235|     42|        wakeup_locked(vo);
 1236|     42|    }
 1237|  2.07k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  2.07k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1238|  2.07k|}
vo_redraw:
 1257|    544|{
 1258|    544|    struct vo_internal *in = vo->in;
 1259|    544|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|    544|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1260|    544|    if (!in->request_redraw) {
  ------------------
  |  Branch (1260:9): [True: 544, False: 0]
  ------------------
 1261|    544|        in->request_redraw = true;
 1262|    544|        in->want_redraw = false;
 1263|    544|        wakeup_locked(vo);
 1264|    544|    }
 1265|    544|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|    544|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1266|    544|}
vo_want_redraw:
 1269|    444|{
 1270|    444|    struct vo_internal *in = vo->in;
 1271|    444|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|    444|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1272|    444|    bool r = in->want_redraw;
 1273|    444|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|    444|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1274|    444|    return r;
 1275|    444|}
vo_seek_reset:
 1278|  4.95k|{
 1279|  4.95k|    struct vo_internal *in = vo->in;
 1280|  4.95k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  4.95k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1281|  4.95k|    forget_frames(vo);
 1282|  4.95k|    reset_vsync_timings(vo);
 1283|  4.95k|    in->send_reset = true;
 1284|  4.95k|    wakeup_locked(vo);
 1285|  4.95k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  4.95k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1286|  4.95k|}
vo_has_frame:
 1290|  3.64k|{
 1291|  3.64k|    return vo->in->hasframe;
 1292|  3.64k|}
vo_query_formats:
 1306|  14.2k|{
 1307|  14.2k|    void *p[] = {vo, list};
 1308|  14.2k|    mp_dispatch_run(vo->in->dispatch, run_query_format, p);
 1309|  14.2k|}
vo_get_num_req_frames:
 1344|  71.9k|{
 1345|  71.9k|    struct vo_internal *in = vo->in;
 1346|  71.9k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  71.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1347|  71.9k|    int res = in->req_frames;
 1348|  71.9k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  71.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1349|  71.9k|    return res;
 1350|  71.9k|}
vo_event:
 1423|  2.78k|{
 1424|  2.78k|    struct vo_internal *in = vo->in;
 1425|  2.78k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  2.78k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1426|  2.78k|    if ((in->queued_events & event & VO_EVENTS_USER) != (event & VO_EVENTS_USER))
  ------------------
  |  Branch (1426:9): [True: 2.78k, False: 0]
  ------------------
 1427|  2.78k|        wakeup_core(vo);
 1428|  2.78k|    if (event)
  ------------------
  |  Branch (1428:9): [True: 2.78k, False: 0]
  ------------------
 1429|  2.78k|        wakeup_locked(vo);
 1430|  2.78k|    in->queued_events |= event;
 1431|  2.78k|    in->internal_events |= event;
 1432|  2.78k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  2.78k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1433|  2.78k|}
vo_query_and_reset_events:
 1438|  85.4k|{
 1439|  85.4k|    struct vo_internal *in = vo->in;
 1440|  85.4k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  85.4k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1441|  85.4k|    int r = in->queued_events & events;
 1442|  85.4k|    in->queued_events &= ~(unsigned)r;
 1443|  85.4k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  85.4k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1444|  85.4k|    return r;
 1445|  85.4k|}
vo_get_image:
 1469|    805|{
 1470|    805|    if (vo->driver->get_image_ts)
  ------------------
  |  Branch (1470:9): [True: 0, False: 805]
  ------------------
 1471|      0|        return vo->driver->get_image_ts(vo, imgfmt, w, h, stride_align, flags);
 1472|    805|    if (vo->in->dr_helper)
  ------------------
  |  Branch (1472:9): [True: 0, False: 805]
  ------------------
 1473|      0|        return dr_helper_get_image(vo->in->dr_helper, imgfmt, w, h, stride_align, flags);
 1474|    805|    return NULL;
 1475|    805|}
vo_frame_ref:
 1488|   144k|{
 1489|   144k|    if (!frame)
  ------------------
  |  Branch (1489:9): [True: 0, False: 144k]
  ------------------
 1490|      0|        return NULL;
 1491|       |
 1492|   144k|    struct vo_frame *new = talloc_ptrtype(NULL, new);
  ------------------
  |  |   34|   144k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|   144k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|   144k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1493|   144k|    talloc_set_destructor(new, destroy_frame);
  ------------------
  |  |   41|   144k|#define talloc_set_destructor           ta_set_destructor
  ------------------
 1494|   144k|    *new = *frame;
 1495|   288k|    for (int n = 0; n < frame->num_frames; n++)
  ------------------
  |  Branch (1495:21): [True: 144k, False: 144k]
  ------------------
 1496|   144k|        new->frames[n] = mp_image_new_ref(frame->frames[n]);
 1497|   144k|    new->current = new->num_frames ? new->frames[0] : NULL;
  ------------------
  |  Branch (1497:20): [True: 144k, False: 0]
  ------------------
 1498|   144k|    return new;
 1499|   144k|}
vo.c:get_desc:
  187|   133k|{
  188|   133k|    if (index >= MP_ARRAY_SIZE(video_out_drivers))
  ------------------
  |  |   48|   133k|#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
  ------------------
  |  Branch (188:9): [True: 5.81k, False: 127k]
  ------------------
  189|  5.81k|        return false;
  190|   127k|    const struct vo_driver *vo = video_out_drivers[index];
  191|   127k|    *dst = (struct m_obj_desc) {
  192|   127k|        .name = vo->name,
  193|   127k|        .description = vo->description,
  194|   127k|        .priv_size = vo->priv_size,
  195|   127k|        .priv_defaults = vo->priv_defaults,
  196|   127k|        .options = vo->options,
  197|   127k|        .options_prefix = vo->options_prefix,
  198|   127k|        .global_opts = vo->global_opts,
  199|   127k|        .hidden = vo->encode,
  200|   127k|        .p = vo,
  201|   127k|    };
  202|   127k|    return true;
  203|   133k|}
vo.c:vo_create:
  270|  2.78k|{
  271|  2.78k|    mp_assert(ex->wakeup_cb);
  ------------------
  |  |   41|  2.78k|#define mp_assert assert
  ------------------
  272|       |
  273|  2.78k|    struct mp_log *log = mp_log_new(NULL, global->log, "vo");
  274|  2.78k|    struct m_obj_desc desc;
  275|  2.78k|    if (!m_obj_list_find(&desc, &vo_obj_list, bstr0(name))) {
  ------------------
  |  Branch (275:9): [True: 0, False: 2.78k]
  ------------------
  276|      0|        mp_msg(log, MSGL_ERR, "Video output %s not found!\n", name);
  277|      0|        talloc_free(log);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  278|      0|        return NULL;
  279|  2.78k|    };
  280|  2.78k|    struct vo *vo = talloc_ptrtype(NULL, vo);
  ------------------
  |  |   34|  2.78k|#define talloc_ptrtype                  ta_xnew_ptrtype
  |  |  ------------------
  |  |  |  |  138|  2.78k|#define ta_xnew_ptrtype(...)            ta_oom_g(ta_new_ptrtype(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  2.78k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  281|  2.78k|    *vo = (struct vo) {
  282|  2.78k|        .log = mp_log_new(vo, log, name),
  283|  2.78k|        .driver = desc.p,
  284|  2.78k|        .global = global,
  285|  2.78k|        .encode_lavc_ctx = ex->encode_lavc_ctx,
  286|  2.78k|        .input_ctx = ex->input_ctx,
  287|  2.78k|        .osd = ex->osd,
  288|  2.78k|        .monitor_par = 1,
  289|  2.78k|        .extra = *ex,
  290|  2.78k|        .probing = probing,
  291|  2.78k|        .in = talloc(vo, struct vo_internal),
  ------------------
  |  |   26|  2.78k|#define talloc                          ta_xnew
  |  |  ------------------
  |  |  |  |  133|  2.78k|#define ta_xnew(...)                    ta_oom_g(ta_new(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  2.78k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  292|  2.78k|    };
  293|  2.78k|    mp_mutex_init(&vo->params_mutex);
  294|  2.78k|    talloc_steal(vo, log);
  ------------------
  |  |   38|  2.78k|#define talloc_steal                    ta_steal
  |  |  ------------------
  |  |  |  |  100|  2.78k|#define ta_steal(ta_parent, ptr) (TA_TYPEOF(ptr))ta_steal_(ta_parent, ptr)
  |  |  ------------------
  ------------------
  295|  2.78k|    *vo->in = (struct vo_internal) {
  296|  2.78k|        .dispatch = mp_dispatch_create(vo),
  297|  2.78k|        .req_frames = 1,
  298|  2.78k|        .estimated_vsync_jitter = -1,
  299|  2.78k|        .stats = stats_ctx_create(vo, global, "vo"),
  300|  2.78k|    };
  301|  2.78k|    mp_dispatch_set_wakeup_fn(vo->in->dispatch, dispatch_wakeup_cb, vo);
  302|  2.78k|    mp_mutex_init(&vo->in->lock);
  303|  2.78k|    mp_cond_init(&vo->in->wakeup);
  304|       |
  305|  2.78k|    vo->opts_cache = m_config_cache_alloc(NULL, global, &vo_sub_opts);
  306|  2.78k|    vo->opts = vo->opts_cache->opts;
  307|       |
  308|  2.78k|    m_config_cache_set_dispatch_change_cb(vo->opts_cache, vo->in->dispatch,
  309|  2.78k|                                          update_opts, vo);
  310|       |
  311|  2.78k|    vo->gl_opts_cache = m_config_cache_alloc(NULL, global, &gl_video_conf);
  312|  2.78k|    vo->eq_opts_cache = m_config_cache_alloc(NULL, global, &mp_csp_equalizer_conf);
  313|       |
  314|  2.78k|    mp_input_set_mouse_transform(vo->input_ctx, NULL, NULL);
  315|  2.78k|    if (vo->driver->encode != !!vo->encode_lavc_ctx)
  ------------------
  |  Branch (315:9): [True: 0, False: 2.78k]
  ------------------
  316|      0|        goto error;
  317|  2.78k|    vo->priv = m_config_group_from_desc(vo, vo->log, global, &desc, name);
  318|  2.78k|    if (!vo->priv)
  ------------------
  |  Branch (318:9): [True: 0, False: 2.78k]
  ------------------
  319|      0|        goto error;
  320|       |
  321|  2.78k|    if (mp_thread_create(&vo->in->thread, vo_thread, vo))
  ------------------
  |  |  211|  2.78k|#define mp_thread_create(t, f, a) pthread_create(t, NULL, f, a)
  |  |  ------------------
  |  |  |  Branch (211:35): [True: 0, False: 2.78k]
  |  |  ------------------
  ------------------
  322|      0|        goto error;
  323|  2.78k|    if (mp_rendezvous(vo, 0) < 0) { // init barrier
  ------------------
  |  Branch (323:9): [True: 0, False: 2.78k]
  ------------------
  324|      0|        mp_thread_join(vo->in->thread);
  ------------------
  |  |  212|      0|#define mp_thread_join(t)         pthread_join(t, NULL)
  ------------------
  325|      0|        goto error;
  326|      0|    }
  327|  2.78k|    return vo;
  328|       |
  329|      0|error:
  330|      0|    dealloc_vo(vo);
  331|      0|    return NULL;
  332|  2.78k|}
vo.c:dispatch_wakeup_cb:
  222|  84.1k|{
  223|  84.1k|    struct vo *vo = ptr;
  224|  84.1k|    vo_wakeup(vo);
  225|  84.1k|}
vo.c:update_opts:
  238|  67.1k|{
  239|  67.1k|    struct vo *vo = p;
  240|       |
  241|  67.1k|    if (m_config_cache_update(vo->opts_cache)) {
  ------------------
  |  Branch (241:9): [True: 0, False: 67.1k]
  ------------------
  242|      0|        read_opts(vo);
  243|      0|        if (vo->driver->control) {
  ------------------
  |  Branch (243:13): [True: 0, False: 0]
  ------------------
  244|      0|            vo->driver->control(vo, VOCTRL_VO_OPTS_CHANGED, NULL);
  245|       |            // "Legacy" update of video position related options.
  246|       |            // Unlike VOCTRL_VO_OPTS_CHANGED, often not propagated to backends.
  247|      0|            vo->driver->control(vo, VOCTRL_SET_PANSCAN, NULL);
  248|      0|        }
  249|      0|    }
  250|  67.1k|}
vo.c:read_opts:
  229|  2.78k|{
  230|  2.78k|    struct vo_internal *in = vo->in;
  231|       |
  232|  2.78k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  2.78k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  233|  2.78k|    in->timing_offset = (uint64_t)(MP_TIME_S_TO_NS(vo->opts->timing_offset));
  ------------------
  |  |   59|  2.78k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  ------------------
  234|  2.78k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  2.78k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  235|  2.78k|}
vo.c:vo_thread:
 1125|  2.78k|{
 1126|  2.78k|    struct vo *vo = ptr;
 1127|  2.78k|    struct vo_internal *in = vo->in;
 1128|  2.78k|    bool vo_paused = false;
 1129|       |
 1130|  2.78k|    mp_thread_set_name("vo");
 1131|       |
 1132|  2.78k|    if (vo->driver->get_image) {
  ------------------
  |  Branch (1132:9): [True: 0, False: 2.78k]
  ------------------
 1133|      0|        in->dr_helper = dr_helper_create(in->dispatch, get_image_vo, vo);
 1134|      0|        dr_helper_acquire_thread(in->dr_helper);
 1135|      0|    }
 1136|       |
 1137|  2.78k|    int r = vo->driver->preinit(vo) ? -1 : 0;
  ------------------
  |  Branch (1137:13): [True: 0, False: 2.78k]
  ------------------
 1138|  2.78k|    mp_rendezvous(vo, r); // init barrier
 1139|  2.78k|    if (r < 0)
  ------------------
  |  Branch (1139:9): [True: 0, False: 2.78k]
  ------------------
 1140|      0|        goto done;
 1141|       |
 1142|  2.78k|    read_opts(vo);
 1143|  2.78k|    update_display_fps(vo);
 1144|  2.78k|    vo_event(vo, VO_EVENT_WIN_STATE);
 1145|       |
 1146|   118k|    while (1) {
  ------------------
  |  Branch (1146:12): [Folded - Ignored]
  ------------------
 1147|   118k|        mp_dispatch_queue_process(vo->in->dispatch, 0);
 1148|   118k|        if (in->terminate)
  ------------------
  |  Branch (1148:13): [True: 2.78k, False: 115k]
  ------------------
 1149|  2.78k|            break;
 1150|   115k|        stats_event(in->stats, "iterations");
 1151|   115k|        vo->driver->control(vo, VOCTRL_CHECK_EVENTS, NULL);
 1152|   115k|        bool working = render_frame(vo);
 1153|   115k|        int64_t now = mp_time_ns();
 1154|   115k|        int64_t wait_until = now + MP_TIME_S_TO_NS(working ? 0 : 1000);
  ------------------
  |  |   59|   231k|#define MP_TIME_S_TO_NS(s) ((s) * INT64_C(1000000000))
  |  |  ------------------
  |  |  |  Branch (59:30): [True: 0, False: 115k]
  |  |  ------------------
  ------------------
 1155|   115k|        bool wakeup_on_done = false;
 1156|   115k|        int64_t wakeup_core_after = 0;
 1157|       |
 1158|   115k|        mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   115k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1159|   115k|        if (in->wakeup_pts) {
  ------------------
  |  Branch (1159:13): [True: 72.0k, False: 43.8k]
  ------------------
 1160|  72.0k|            if (in->wakeup_pts > now) {
  ------------------
  |  Branch (1160:17): [True: 0, False: 72.0k]
  ------------------
 1161|      0|                wait_until = MPMIN(wait_until, in->wakeup_pts);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1162|  72.0k|            } else {
 1163|  72.0k|                in->wakeup_pts = 0;
 1164|  72.0k|                wakeup_core(vo);
 1165|  72.0k|            }
 1166|  72.0k|        }
 1167|   115k|        if (vo->want_redraw && !in->want_redraw) {
  ------------------
  |  Branch (1167:13): [True: 0, False: 115k]
  |  Branch (1167:32): [True: 0, False: 0]
  ------------------
 1168|      0|            in->want_redraw = true;
 1169|      0|            wakeup_core(vo);
 1170|      0|        }
 1171|   115k|        if ((!working && !in->rendering && !in->frame_queued) && in->wakeup_on_done) {
  ------------------
  |  Branch (1171:14): [True: 115k, False: 0]
  |  Branch (1171:26): [True: 115k, False: 0]
  |  Branch (1171:44): [True: 115k, False: 22]
  |  Branch (1171:66): [True: 0, False: 115k]
  ------------------
 1172|       |            // At this point we know VO is going to sleep
 1173|      0|            int64_t frame_end = get_current_frame_end(vo);
 1174|      0|            if (frame_end >= 0)
  ------------------
  |  Branch (1174:17): [True: 0, False: 0]
  ------------------
 1175|      0|                wakeup_core_after = frame_end;
 1176|      0|            wakeup_on_done = true;
 1177|      0|            in->wakeup_on_done = false;
 1178|      0|        }
 1179|   115k|        vo->want_redraw = false;
 1180|   115k|        bool redraw = in->request_redraw;
 1181|   115k|        bool send_reset = in->send_reset;
 1182|   115k|        in->send_reset = false;
 1183|   115k|        bool send_pause = in->paused != vo_paused;
 1184|   115k|        vo_paused = in->paused;
 1185|   115k|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   115k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1186|       |
 1187|   115k|        if (send_reset)
  ------------------
  |  Branch (1187:13): [True: 4.82k, False: 111k]
  ------------------
 1188|  4.82k|            vo->driver->control(vo, VOCTRL_RESET, NULL);
 1189|   115k|        if (send_pause)
  ------------------
  |  Branch (1189:13): [True: 42, False: 115k]
  ------------------
 1190|     42|            vo->driver->control(vo, vo_paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL);
  ------------------
  |  Branch (1190:37): [True: 21, False: 21]
  ------------------
 1191|   115k|        if (wait_until > now && redraw) {
  ------------------
  |  Branch (1191:13): [True: 115k, False: 0]
  |  Branch (1191:33): [True: 531, False: 115k]
  ------------------
 1192|    531|            vo->driver->control(vo, VOCTRL_REDRAW, NULL);
 1193|    531|            do_redraw(vo); // now is a good time
 1194|    531|            continue;
 1195|    531|        }
 1196|   115k|        if (vo->want_redraw) // might have been set by VOCTRLs
  ------------------
  |  Branch (1196:13): [True: 0, False: 115k]
  ------------------
 1197|      0|            wait_until = 0;
 1198|       |
 1199|   115k|        if (wait_until <= now)
  ------------------
  |  Branch (1199:13): [True: 0, False: 115k]
  ------------------
 1200|      0|            continue;
 1201|       |
 1202|   115k|        if (wakeup_on_done) {
  ------------------
  |  Branch (1202:13): [True: 0, False: 115k]
  ------------------
 1203|       |            // At this point wait_until should be longer than frame duration
 1204|      0|            if (wakeup_core_after >= 0 && wait_until >= wakeup_core_after) {
  ------------------
  |  Branch (1204:17): [True: 0, False: 0]
  |  Branch (1204:43): [True: 0, False: 0]
  ------------------
 1205|      0|                wait_vo(vo, wakeup_core_after);
 1206|      0|                mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1207|      0|                in->need_wakeup = true;
 1208|      0|                mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1209|      0|            }
 1210|      0|            wakeup_core(vo);
 1211|      0|        }
 1212|       |
 1213|   115k|        wait_vo(vo, wait_until);
 1214|   115k|    }
 1215|  2.78k|    forget_frames(vo); // implicitly synchronized
 1216|  2.78k|    talloc_free(in->current_frame);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
 1217|  2.78k|    in->current_frame = NULL;
 1218|  2.78k|    vo->driver->uninit(vo);
 1219|  2.78k|done:
 1220|  2.78k|    TA_FREEP(&in->dr_helper);
  ------------------
  |  |   81|  2.78k|#define TA_FREEP(pctx) do {talloc_free(*(pctx)); *(pctx) = NULL;} while(0)
  |  |  ------------------
  |  |  |  |   47|  2.78k|#define talloc_free                     ta_free
  |  |  ------------------
  |  |  |  Branch (81:73): [Folded - Ignored]
  |  |  ------------------
  ------------------
 1221|  2.78k|    MP_THREAD_RETURN();
  ------------------
  |  |  209|  2.78k|#define MP_THREAD_RETURN() return NULL
  ------------------
 1222|  2.78k|}
vo.c:update_display_fps:
  540|   127k|{
  541|   127k|    struct vo_internal *in = vo->in;
  542|   127k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   127k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  543|   127k|    if (in->internal_events & VO_EVENT_WIN_STATE) {
  ------------------
  |  Branch (543:9): [True: 2.78k, False: 125k]
  ------------------
  544|  2.78k|        in->internal_events &= ~(unsigned)VO_EVENT_WIN_STATE;
  545|       |
  546|  2.78k|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  2.78k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  547|       |
  548|  2.78k|        double fps = 0;
  549|  2.78k|        vo->driver->control(vo, VOCTRL_GET_DISPLAY_FPS, &fps);
  550|       |
  551|  2.78k|        mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  2.78k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  552|       |
  553|  2.78k|        in->reported_display_fps = fps;
  554|  2.78k|    }
  555|       |
  556|   127k|    double display_fps = vo->opts->display_fps_override;
  557|   127k|    if (display_fps <= 0)
  ------------------
  |  Branch (557:9): [True: 127k, False: 0]
  ------------------
  558|   127k|        display_fps = in->reported_display_fps;
  559|       |
  560|   127k|    if (in->display_fps != display_fps) {
  ------------------
  |  Branch (560:9): [True: 0, False: 127k]
  ------------------
  561|      0|        in->nominal_vsync_interval =  display_fps > 0 ? 1e9 / display_fps : 0;
  ------------------
  |  Branch (561:39): [True: 0, False: 0]
  ------------------
  562|      0|        in->vsync_interval = MPMAX(in->nominal_vsync_interval, 1);
  ------------------
  |  |   43|      0|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  563|      0|        in->display_fps = display_fps;
  564|       |
  565|      0|        MP_VERBOSE(vo, "Assuming %f FPS for display sync.\n", display_fps);
  ------------------
  |  |   88|      0|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  566|       |
  567|       |        // make sure to update the player
  568|      0|        in->queued_events |= VO_EVENT_WIN_STATE;
  569|      0|        wakeup_core(vo);
  570|      0|    }
  571|       |
  572|   127k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   127k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  573|   127k|}
vo.c:render_frame:
  924|   115k|{
  925|   115k|    struct vo_internal *in = vo->in;
  926|   115k|    struct vo_frame *frame = NULL;
  927|   115k|    bool more_frames = false;
  928|       |
  929|   115k|    update_display_fps(vo);
  930|       |
  931|   115k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   115k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  932|       |
  933|   115k|    if (in->frame_queued) {
  ------------------
  |  Branch (933:9): [True: 71.9k, False: 43.8k]
  ------------------
  934|  71.9k|        talloc_free(in->current_frame);
  ------------------
  |  |   47|  71.9k|#define talloc_free                     ta_free
  ------------------
  935|  71.9k|        in->current_frame = in->frame_queued;
  936|  71.9k|        in->frame_queued = NULL;
  937|  71.9k|    } else if (in->paused || !in->current_frame || !in->hasframe ||
  ------------------
  |  Branch (937:16): [True: 54, False: 43.8k]
  |  Branch (937:30): [True: 32.9k, False: 10.8k]
  |  Branch (937:52): [True: 601, False: 10.2k]
  ------------------
  938|  43.8k|               (in->current_frame->display_synced && in->current_frame->num_vsyncs < 1) ||
  ------------------
  |  Branch (938:17): [True: 0, False: 10.2k]
  |  Branch (938:54): [True: 0, False: 0]
  ------------------
  939|  43.8k|               !in->current_frame->display_synced)
  ------------------
  |  Branch (939:16): [True: 10.2k, False: 0]
  ------------------
  940|  43.8k|    {
  941|  43.8k|        goto done;
  942|  43.8k|    }
  943|       |
  944|  71.9k|    frame = vo_frame_ref(in->current_frame);
  945|  71.9k|    mp_assert(frame);
  ------------------
  |  |   41|  71.9k|#define mp_assert assert
  ------------------
  946|       |
  947|  71.9k|    if (frame->display_synced) {
  ------------------
  |  Branch (947:9): [True: 0, False: 71.9k]
  ------------------
  948|      0|        frame->pts = 0;
  949|      0|        frame->duration = -1;
  950|      0|    }
  951|       |
  952|  71.9k|    int64_t now = mp_time_ns();
  953|  71.9k|    int64_t pts = frame->pts;
  954|  71.9k|    int64_t duration = frame->duration;
  955|  71.9k|    int64_t end_time = pts + duration;
  956|       |
  957|       |    // Time at which we should flip_page on the VO.
  958|  71.9k|    int64_t target = frame->display_synced ? 0 : pts - in->flip_queue_offset;
  ------------------
  |  Branch (958:22): [True: 0, False: 71.9k]
  ------------------
  959|       |
  960|       |    // "normal" strict drop threshold.
  961|  71.9k|    in->dropped_frame = duration >= 0 && end_time < now;
  ------------------
  |  Branch (961:25): [True: 0, False: 71.9k]
  |  Branch (961:42): [True: 0, False: 0]
  ------------------
  962|       |
  963|  71.9k|    in->dropped_frame &= !frame->display_synced;
  964|  71.9k|    in->dropped_frame &= !(vo->driver->caps & VO_CAP_FRAMEDROP);
  965|  71.9k|    in->dropped_frame &= frame->can_drop;
  966|       |    // Even if we're hopelessly behind, rather degrade to 10 FPS playback,
  967|       |    // instead of just freezing the display forever.
  968|  71.9k|    in->dropped_frame &= now - in->prev_vsync < MP_TIME_MS_TO_NS(100);
  ------------------
  |  |   60|  71.9k|#define MP_TIME_MS_TO_NS(ms) ((ms) * INT64_C(1000000))
  ------------------
  969|  71.9k|    in->dropped_frame &= in->hasframe_rendered;
  970|       |
  971|       |    // Setup parameters for the next time this frame is drawn. ("frame" is the
  972|       |    // frame currently drawn, while in->current_frame is the potentially next.)
  973|  71.9k|    in->current_frame->repeat = true;
  974|  71.9k|    if (frame->display_synced) {
  ------------------
  |  Branch (974:9): [True: 0, False: 71.9k]
  ------------------
  975|       |        // Increment the offset only if it's not the last vsync. The current_frame
  976|       |        // can still be reused. This is mostly important for redraws that might
  977|       |        // overshoot the target vsync point.
  978|      0|        if (in->current_frame->num_vsyncs > 1) {
  ------------------
  |  Branch (978:13): [True: 0, False: 0]
  ------------------
  979|      0|            in->current_frame->vsync_offset += in->current_frame->vsync_interval;
  980|      0|            in->current_frame->ideal_frame_vsync += in->current_frame->ideal_frame_vsync_duration;
  981|      0|        }
  982|      0|        in->dropped_frame |= in->current_frame->num_vsyncs < 1;
  983|      0|    }
  984|  71.9k|    if (in->current_frame->num_vsyncs > 0)
  ------------------
  |  Branch (984:9): [True: 71.9k, False: 0]
  ------------------
  985|  71.9k|        in->current_frame->num_vsyncs -= 1;
  986|       |
  987|       |    // Always render when paused (it's typically the last frame for a while).
  988|  71.9k|    in->dropped_frame &= !in->paused;
  989|       |
  990|  71.9k|    bool use_vsync = in->current_frame->display_synced && !in->paused;
  ------------------
  |  Branch (990:22): [True: 0, False: 71.9k]
  |  Branch (990:59): [True: 0, False: 0]
  ------------------
  991|  71.9k|    if (use_vsync && !in->expecting_vsync) // first DS frame in a row
  ------------------
  |  Branch (991:9): [True: 0, False: 71.9k]
  |  Branch (991:22): [True: 0, False: 0]
  ------------------
  992|      0|        in->prev_vsync = now;
  993|  71.9k|    in->expecting_vsync = use_vsync;
  994|       |
  995|       |    // Store the initial value before we unlock.
  996|  71.9k|    bool request_redraw = in->request_redraw;
  997|       |
  998|  71.9k|    if (in->dropped_frame) {
  ------------------
  |  Branch (998:9): [True: 0, False: 71.9k]
  ------------------
  999|      0|        in->drop_count += 1;
 1000|      0|        wakeup_core(vo);
 1001|  71.9k|    } else {
 1002|  71.9k|        in->rendering = true;
 1003|  71.9k|        in->hasframe_rendered = true;
 1004|  71.9k|        int64_t prev_drop_count = vo->in->drop_count;
 1005|       |        // Can the core queue new video now? Non-display-sync uses a separate
 1006|       |        // timer instead, but possibly benefits from preparing a frame early.
 1007|  71.9k|        bool can_queue = !in->frame_queued &&
  ------------------
  |  Branch (1007:26): [True: 71.9k, False: 0]
  ------------------
 1008|  71.9k|            (in->current_frame->num_vsyncs < 1 || !use_vsync);
  ------------------
  |  Branch (1008:14): [True: 71.9k, False: 0]
  |  Branch (1008:51): [True: 0, False: 0]
  ------------------
 1009|  71.9k|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  71.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1010|       |
 1011|  71.9k|        if (can_queue)
  ------------------
  |  Branch (1011:13): [True: 71.9k, False: 0]
  ------------------
 1012|  71.9k|            wakeup_core(vo);
 1013|       |
 1014|  71.9k|        stats_time_start(in->stats, "video-draw");
 1015|       |
 1016|  71.9k|        in->visible = vo->driver->draw_frame(vo, frame);
 1017|       |
 1018|  71.9k|        stats_time_end(in->stats, "video-draw");
 1019|       |
 1020|  71.9k|        wait_until(vo, target);
 1021|       |
 1022|  71.9k|        stats_time_start(in->stats, "video-flip");
 1023|       |
 1024|  71.9k|        vo->driver->flip_page(vo);
 1025|       |
 1026|  71.9k|        struct vo_vsync_info vsync = {
 1027|  71.9k|            .last_queue_display_time = -1,
 1028|  71.9k|            .skipped_vsyncs = -1,
 1029|  71.9k|        };
 1030|  71.9k|        if (vo->driver->get_vsync)
  ------------------
  |  Branch (1030:13): [True: 0, False: 71.9k]
  ------------------
 1031|      0|            vo->driver->get_vsync(vo, &vsync);
 1032|       |
 1033|       |        // Make up some crap if presentation feedback is missing.
 1034|  71.9k|        if (vsync.last_queue_display_time <= 0)
  ------------------
  |  Branch (1034:13): [True: 71.9k, False: 0]
  ------------------
 1035|  71.9k|            vsync.last_queue_display_time = mp_time_ns();
 1036|       |
 1037|  71.9k|        stats_time_end(in->stats, "video-flip");
 1038|       |
 1039|  71.9k|        mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  71.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1040|  71.9k|        in->dropped_frame = prev_drop_count < vo->in->drop_count;
 1041|  71.9k|        in->rendering = false;
 1042|       |
 1043|  71.9k|        update_vsync_timing_after_swap(vo, &vsync);
 1044|  71.9k|    }
 1045|       |
 1046|  71.9k|    if (vo->driver->caps & VO_CAP_NORETAIN) {
  ------------------
  |  Branch (1046:9): [True: 0, False: 71.9k]
  ------------------
 1047|      0|        talloc_free(in->current_frame);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
 1048|      0|        in->current_frame = NULL;
 1049|      0|    }
 1050|       |
 1051|  71.9k|    if (in->dropped_frame) {
  ------------------
  |  Branch (1051:9): [True: 0, False: 71.9k]
  ------------------
 1052|      0|        MP_STATS(vo, "drop-vo");
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1053|  71.9k|    } else {
 1054|       |        // If the initial redraw request was true or mpv is still playing,
 1055|       |        // then we can clear it here since we just performed a redraw, or the
 1056|       |        // next loop will draw what we need. However if there initially is
 1057|       |        // no redraw request, then something can change this (i.e. the OSD)
 1058|       |        // while the vo was unlocked. If we are paused, don't touch
 1059|       |        // in->request_redraw in that case.
 1060|  71.9k|        if (request_redraw || !in->paused)
  ------------------
  |  Branch (1060:13): [True: 13, False: 71.9k]
  |  Branch (1060:31): [True: 71.9k, False: 0]
  ------------------
 1061|  71.9k|            in->request_redraw = false;
 1062|  71.9k|    }
 1063|       |
 1064|  71.9k|    if (in->current_frame && in->current_frame->num_vsyncs &&
  ------------------
  |  Branch (1064:9): [True: 71.9k, False: 0]
  |  Branch (1064:30): [True: 0, False: 71.9k]
  ------------------
 1065|  71.9k|        in->current_frame->display_synced)
  ------------------
  |  Branch (1065:9): [True: 0, False: 0]
  ------------------
 1066|      0|        more_frames = true;
 1067|       |
 1068|  71.9k|    if (in->frame_queued && in->frame_queued->display_synced)
  ------------------
  |  Branch (1068:9): [True: 22, False: 71.9k]
  |  Branch (1068:29): [True: 0, False: 22]
  ------------------
 1069|      0|        more_frames = true;
 1070|       |
 1071|  71.9k|    mp_cond_broadcast(&in->wakeup); // for vo_wait_frame()
 1072|       |
 1073|   115k|done:
 1074|   115k|    if (!(vo->driver->caps & VO_CAP_FRAMEOWNER) || in->dropped_frame)
  ------------------
  |  Branch (1074:9): [True: 115k, False: 0]
  |  Branch (1074:52): [True: 0, False: 0]
  ------------------
 1075|   115k|        talloc_free(frame);
  ------------------
  |  |   47|   115k|#define talloc_free                     ta_free
  ------------------
 1076|   115k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   115k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1077|       |
 1078|   115k|    return more_frames;
 1079|  71.9k|}
vo.c:wait_until:
  911|  71.9k|{
  912|  71.9k|    struct vo_internal *in = vo->in;
  913|  71.9k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  71.9k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  914|  71.9k|    while (target > mp_time_ns()) {
  ------------------
  |  Branch (914:12): [True: 0, False: 71.9k]
  ------------------
  915|      0|        if (in->queued_events & VO_EVENT_LIVE_RESIZING)
  ------------------
  |  Branch (915:13): [True: 0, False: 0]
  ------------------
  916|      0|            break;
  917|      0|        if (mp_cond_timedwait_until(&in->wakeup, &in->lock, target))
  ------------------
  |  Branch (917:13): [True: 0, False: 0]
  ------------------
  918|      0|            break;
  919|      0|    }
  920|  71.9k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  71.9k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  921|  71.9k|}
vo.c:update_vsync_timing_after_swap:
  483|  71.9k|{
  484|  71.9k|    struct vo_internal *in = vo->in;
  485|       |
  486|  71.9k|    int64_t vsync_time = vsync->last_queue_display_time;
  487|  71.9k|    int64_t prev_vsync = in->prev_vsync;
  488|  71.9k|    in->prev_vsync = vsync_time;
  489|       |
  490|  71.9k|    if (!in->expecting_vsync) {
  ------------------
  |  Branch (490:9): [True: 71.9k, False: 0]
  ------------------
  491|  71.9k|        reset_vsync_timings(vo);
  492|  71.9k|        return;
  493|  71.9k|    }
  494|       |
  495|      0|    in->num_successive_vsyncs++;
  496|      0|    if (in->num_successive_vsyncs <= DELAY_VSYNC_SAMPLES) {
  ------------------
  |  |  411|      0|#define DELAY_VSYNC_SAMPLES 10
  ------------------
  |  Branch (496:9): [True: 0, False: 0]
  ------------------
  497|      0|        in->base_vsync = vsync_time;
  498|      0|        return;
  499|      0|    }
  500|       |
  501|      0|    if (vsync_time <= 0 || vsync_time <= prev_vsync) {
  ------------------
  |  Branch (501:9): [True: 0, False: 0]
  |  Branch (501:28): [True: 0, False: 0]
  ------------------
  502|      0|        in->prev_vsync = 0;
  503|      0|        in->base_vsync = 0;
  504|      0|        return;
  505|      0|    }
  506|       |
  507|      0|    if (prev_vsync <= 0)
  ------------------
  |  Branch (507:9): [True: 0, False: 0]
  ------------------
  508|      0|        return;
  509|       |
  510|      0|    if (in->num_vsync_samples >= MAX_VSYNC_SAMPLES)
  ------------------
  |  |  410|      0|#define MAX_VSYNC_SAMPLES 1000
  ------------------
  |  Branch (510:9): [True: 0, False: 0]
  ------------------
  511|      0|        in->num_vsync_samples -= 1;
  512|      0|    MP_TARRAY_INSERT_AT(in, in->vsync_samples, in->num_vsync_samples, 0,
  ------------------
  |  |  115|      0|    do {                                            \
  |  |  116|      0|        size_t at_ = (at);                          \
  |  |  117|      0|        assert(at_ <= (idxvar));                    \
  |  |  118|      0|        MP_TARRAY_GROW(ctx, p, idxvar);             \
  |  |  ------------------
  |  |  |  |   96|      0|    do {                                            \
  |  |  |  |   97|      0|        size_t nextidx_ = (nextidx);                \
  |  |  |  |   98|      0|        if (nextidx_ >= MP_TALLOC_AVAIL(p))         \
  |  |  |  |  ------------------
  |  |  |  |  |  |   84|      0|#define MP_TALLOC_AVAIL(p) (talloc_get_size(p) / sizeof((p)[0]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   45|      0|#define talloc_get_size                 ta_get_size
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (98:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   99|      0|            MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|      0|    do {                                                        \
  |  |  |  |  |  |   89|      0|        (p) = ta_xrealloc_size(ctx, p,                          \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  158|      0|#define ta_xrealloc_size(...)   ta_dbg_set_loc(ta_xrealloc_size(__VA_ARGS__), TA_LOC)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |   43|      0|#define TA_LOC __FILE__ ":" TA_STRINGIFY(__LINE__)
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |   38|      0|#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  |  |  |  |   37|      0|#define TA_STRINGIFY_(x) # x
  |  |  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   90|      0|                    ta_calc_array_size(sizeof((p)[0]), count)); \
  |  |  |  |  |  |   91|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (91:14): [Folded - Ignored]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  100|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (100:14): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  119|      0|        memmove((p) + at_ + 1, (p) + at_,           \
  |  |  120|      0|                ((idxvar) - at_) * sizeof((p)[0])); \
  |  |  121|      0|        (idxvar)++;                                 \
  |  |  122|      0|        (p)[at_] = (__VA_ARGS__);                   \
  |  |  123|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (123:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  513|      0|                        vsync_time - prev_vsync);
  514|      0|    in->drop_point = MPMIN(in->drop_point + 1, in->num_vsync_samples);
  ------------------
  |  |   44|      0|#define MPMIN(a, b) ((a) > (b) ? (b) : (a))
  |  |  ------------------
  |  |  |  Branch (44:22): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  515|      0|    in->num_total_vsync_samples += 1;
  516|      0|    if (in->base_vsync) {
  ------------------
  |  Branch (516:9): [True: 0, False: 0]
  ------------------
  517|      0|        in->base_vsync += in->vsync_interval;
  518|      0|    } else {
  519|      0|        in->base_vsync = vsync_time;
  520|      0|    }
  521|       |
  522|      0|    double avg = 0;
  523|      0|    for (int n = 0; n < in->num_vsync_samples; n++) {
  ------------------
  |  Branch (523:21): [True: 0, False: 0]
  ------------------
  524|      0|        mp_assert(in->vsync_samples[n] > 0);
  ------------------
  |  |   41|      0|#define mp_assert assert
  ------------------
  525|      0|        avg += in->vsync_samples[n];
  526|      0|    }
  527|      0|    in->estimated_vsync_interval = avg / in->num_vsync_samples;
  528|      0|    in->estimated_vsync_jitter =
  529|      0|        vsync_stddef(vo, in->vsync_interval) / in->vsync_interval;
  530|       |
  531|      0|    check_estimated_display_fps(vo);
  532|      0|    vsync_skip_detection(vo);
  533|       |
  534|      0|    MP_STATS(vo, "value %f jitter", in->estimated_vsync_jitter);
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  535|      0|    MP_STATS(vo, "value %f vsync-diff", MP_TIME_NS_TO_S(in->vsync_samples[0]));
  ------------------
  |  |   95|      0|#define MP_STATS(obj, ...)      MP_MSG(obj, MSGL_STATS, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  536|      0|}
vo.c:get_current_frame_end:
  766|  10.0k|{
  767|  10.0k|    struct vo_internal *in = vo->in;
  768|  10.0k|    if (!in->current_frame)
  ------------------
  |  Branch (768:9): [True: 558, False: 9.50k]
  ------------------
  769|    558|        return -1;
  770|  9.50k|    return in->current_frame->pts + MPMAX(in->current_frame->duration, 0);
  ------------------
  |  |   43|  9.50k|#define MPMAX(a, b) ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (43:22): [True: 0, False: 9.50k]
  |  |  ------------------
  ------------------
  771|  10.0k|}
vo.c:do_redraw:
 1082|    531|{
 1083|    531|    struct vo_internal *in = vo->in;
 1084|       |
 1085|    531|    if (!vo->config_ok)
  ------------------
  |  Branch (1085:9): [True: 0, False: 531]
  ------------------
 1086|      0|        return;
 1087|       |
 1088|    531|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|    531|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
 1089|    531|    in->request_redraw = false;
 1090|       |
 1091|    531|    if (vo->driver->caps & (VO_CAP_NORETAIN | VO_CAP_UNTIMED)) {
  ------------------
  |  Branch (1091:9): [True: 0, False: 531]
  ------------------
 1092|      0|        mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1093|      0|        return;
 1094|      0|    }
 1095|       |
 1096|    531|    bool full_redraw = in->dropped_frame;
 1097|    531|    struct vo_frame *frame = vo_frame_ref(in->current_frame);
 1098|    531|    if (frame)
  ------------------
  |  Branch (1098:9): [True: 531, False: 0]
  ------------------
 1099|    531|        in->dropped_frame = false;
 1100|    531|    struct vo_frame dummy = {0};
 1101|    531|    if (!frame)
  ------------------
  |  Branch (1101:9): [True: 0, False: 531]
  ------------------
 1102|      0|        frame = &dummy;
 1103|    531|    frame->redraw = !full_redraw; // unconditionally redraw if it was dropped
 1104|    531|    frame->repeat = false;
 1105|    531|    frame->still = true;
 1106|    531|    frame->pts = 0;
 1107|    531|    frame->duration = -1;
 1108|    531|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|    531|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
 1109|       |
 1110|    531|    vo->driver->draw_frame(vo, frame);
 1111|    531|    vo->driver->flip_page(vo);
 1112|       |
 1113|    531|    if (frame != &dummy && !(vo->driver->caps & VO_CAP_FRAMEOWNER))
  ------------------
  |  Branch (1113:9): [True: 531, False: 0]
  |  Branch (1113:28): [True: 531, False: 0]
  ------------------
 1114|    531|        talloc_free(frame);
  ------------------
  |  |   47|    531|#define talloc_free                     ta_free
  ------------------
 1115|    531|}
vo.c:wait_vo:
  731|   115k|{
  732|   115k|    struct vo_internal *in = vo->in;
  733|       |
  734|   115k|    if (vo->driver->wait_events) {
  ------------------
  |  Branch (734:9): [True: 0, False: 115k]
  ------------------
  735|      0|        vo->driver->wait_events(vo, until_time);
  736|   115k|    } else {
  737|   115k|        vo_wait_default(vo, until_time);
  738|   115k|    }
  739|   115k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|   115k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  740|   115k|    in->need_wakeup = false;
  741|   115k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|   115k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  742|   115k|}
vo.c:terminate_vo:
  368|  2.78k|{
  369|  2.78k|    struct vo *vo = p;
  370|  2.78k|    struct vo_internal *in = vo->in;
  371|  2.78k|    in->terminate = true;
  372|  2.78k|}
vo.c:dealloc_vo:
  254|  2.78k|{
  255|  2.78k|    forget_frames(vo); // implicitly synchronized
  256|       |
  257|       |    // These must be free'd before vo->in->dispatch.
  258|  2.78k|    talloc_free(vo->opts_cache);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
  259|  2.78k|    talloc_free(vo->gl_opts_cache);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
  260|  2.78k|    talloc_free(vo->eq_opts_cache);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
  261|  2.78k|    mp_mutex_destroy(&vo->params_mutex);
  ------------------
  |  |  130|  2.78k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  262|       |
  263|  2.78k|    mp_mutex_destroy(&vo->in->lock);
  ------------------
  |  |  130|  2.78k|#define mp_mutex_destroy    pthread_mutex_destroy
  ------------------
  264|  2.78k|    mp_cond_destroy(&vo->in->wakeup);
  265|  2.78k|    talloc_free(vo);
  ------------------
  |  |   47|  2.78k|#define talloc_free                     ta_free
  ------------------
  266|  2.78k|}
vo.c:run_reconfig:
  591|  9.26k|{
  592|  9.26k|    void **pp = p;
  593|  9.26k|    struct vo *vo = pp[0];
  594|  9.26k|    struct mp_image *img = pp[1];
  595|  9.26k|    int *ret = pp[2];
  596|       |
  597|  9.26k|    struct mp_image_params *params = &img->params;
  598|       |
  599|  9.26k|    struct vo_internal *in = vo->in;
  600|       |
  601|  9.26k|    MP_VERBOSE(vo, "reconfig to %s\n", mp_image_params_to_str(params));
  ------------------
  |  |   88|  9.26k|#define MP_VERBOSE(obj, ...)    MP_MSG(obj, MSGL_V, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|  9.26k|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  602|       |
  603|  9.26k|    update_opts(vo);
  604|       |
  605|  9.26k|    mp_image_params_get_dsize(params, &vo->dwidth, &vo->dheight);
  606|       |
  607|  9.26k|    mp_mutex_lock(&vo->params_mutex);
  ------------------
  |  |  131|  9.26k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  608|  9.26k|    talloc_free(vo->params);
  ------------------
  |  |   47|  9.26k|#define talloc_free                     ta_free
  ------------------
  609|  9.26k|    vo->params = talloc_dup(vo, params);
  ------------------
  |  |   48|  9.26k|#define talloc_dup                      ta_xdup
  |  |  ------------------
  |  |  |  |  141|  9.26k|#define ta_xdup(...)                    ta_oom_g(ta_dup(__VA_ARGS__))
  |  |  |  |  ------------------
  |  |  |  |  |  |  182|  9.26k|#define ta_oom_g(ptr) (TA_TYPEOF(ptr))ta_oom_p(ptr)
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  610|  9.26k|    vo->has_peak_detect_values = false;
  611|  9.26k|    mp_mutex_unlock(&vo->params_mutex);
  ------------------
  |  |  133|  9.26k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  612|       |
  613|  9.26k|    if (vo->driver->reconfig2) {
  ------------------
  |  Branch (613:9): [True: 0, False: 9.26k]
  ------------------
  614|      0|        *ret = vo->driver->reconfig2(vo, img);
  615|  9.26k|    } else {
  616|  9.26k|        *ret = vo->driver->reconfig(vo, vo->params);
  617|  9.26k|    }
  618|  9.26k|    vo->config_ok = *ret >= 0;
  619|  9.26k|    if (vo->config_ok) {
  ------------------
  |  Branch (619:9): [True: 9.26k, False: 0]
  ------------------
  620|  9.26k|        check_vo_caps(vo);
  621|  9.26k|    } else {
  622|      0|        mp_mutex_lock(&vo->params_mutex);
  ------------------
  |  |  131|      0|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  623|      0|        talloc_free(vo->params);
  ------------------
  |  |   47|      0|#define talloc_free                     ta_free
  ------------------
  624|      0|        vo->params = NULL;
  625|      0|        vo->has_peak_detect_values = false;
  626|      0|        mp_mutex_unlock(&vo->params_mutex);
  ------------------
  |  |  133|      0|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  627|      0|    }
  628|       |
  629|  9.26k|    mp_mutex_lock(&in->lock);
  ------------------
  |  |  131|  9.26k|#define mp_mutex_lock       pthread_mutex_lock
  ------------------
  630|  9.26k|    talloc_free(in->current_frame);
  ------------------
  |  |   47|  9.26k|#define talloc_free                     ta_free
  ------------------
  631|  9.26k|    in->current_frame = NULL;
  632|  9.26k|    forget_frames(vo);
  633|  9.26k|    reset_vsync_timings(vo);
  634|  9.26k|    mp_mutex_unlock(&in->lock);
  ------------------
  |  |  133|  9.26k|#define mp_mutex_unlock     pthread_mutex_unlock
  ------------------
  635|       |
  636|  9.26k|    update_display_fps(vo);
  637|  9.26k|}
vo.c:check_vo_caps:
  576|  9.26k|{
  577|  9.26k|    int rot = vo->params->rotate;
  578|  9.26k|    if (rot) {
  ------------------
  |  Branch (578:9): [True: 0, False: 9.26k]
  ------------------
  579|      0|        bool ok = rot % 90 ? false : (vo->driver->caps & VO_CAP_ROTATE90);
  ------------------
  |  Branch (579:19): [True: 0, False: 0]
  ------------------
  580|      0|        if (!ok) {
  ------------------
  |  Branch (580:13): [True: 0, False: 0]
  ------------------
  581|      0|           MP_WARN(vo, "Video is flagged as rotated by %d degrees, but the "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  582|      0|                   "video output does not support this.\n", rot);
  583|      0|        }
  584|      0|    }
  585|  9.26k|    if (vo->params->vflip && !(vo->driver->caps & VO_CAP_VFLIP))
  ------------------
  |  Branch (585:9): [True: 0, False: 9.26k]
  |  Branch (585:30): [True: 0, False: 0]
  ------------------
  586|  9.26k|        MP_WARN(vo, "Video is flagged as vertically flipped, but the "
  ------------------
  |  |   86|      0|#define MP_WARN(obj, ...)       MP_MSG(obj, MSGL_WARN, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   82|      0|#define MP_MSG(obj, lev, ...)   mp_msg((obj)->log, lev, __VA_ARGS__)
  |  |  ------------------
  ------------------
  587|  9.26k|                    "video output does not support this.\n");
  588|  9.26k|}
vo.c:run_control:
  658|  57.8k|{
  659|  57.8k|    void **pp = p;
  660|  57.8k|    struct vo *vo = pp[0];
  661|  57.8k|    int request = (intptr_t)pp[1];
  662|  57.8k|    void *data = pp[2];
  663|  57.8k|    update_opts(vo);
  664|  57.8k|    int ret = vo->driver->control(vo, request, data);
  665|  57.8k|    if (pp[3])
  ------------------
  |  Branch (665:9): [True: 6.85k, False: 50.9k]
  ------------------
  666|  6.85k|        *(int *)pp[3] = ret;
  667|  57.8k|}
vo.c:wakeup_locked:
  745|   164k|{
  746|   164k|    struct vo_internal *in = vo->in;
  747|       |
  748|   164k|    mp_cond_broadcast(&in->wakeup);
  749|   164k|    if (vo->driver->wakeup)
  ------------------
  |  Branch (749:9): [True: 0, False: 164k]
  ------------------
  750|      0|        vo->driver->wakeup(vo);
  751|   164k|    in->need_wakeup = true;
  752|   164k|}
vo.c:still_displaying:
  789|  10.0k|{
  790|  10.0k|    struct vo_internal *in = vo->in;
  791|  10.0k|    bool working = in->rendering || in->frame_queued;
  ------------------
  |  Branch (791:20): [True: 0, False: 10.0k]
  |  Branch (791:37): [True: 0, False: 10.0k]
  ------------------
  792|  10.0k|    if (working)
  ------------------
  |  Branch (792:9): [True: 0, False: 10.0k]
  ------------------
  793|      0|        goto done;
  794|       |
  795|  10.0k|    int64_t frame_end = get_display_synced_frame_end(vo);
  796|  10.0k|    if (frame_end > 0) {
  ------------------
  |  Branch (796:9): [True: 0, False: 10.0k]
  ------------------
  797|      0|        working = frame_end > in->base_vsync;
  798|      0|        goto done;
  799|      0|    }
  800|       |
  801|  10.0k|    frame_end = get_current_frame_end(vo);
  802|  10.0k|    if (frame_end < 0)
  ------------------
  |  Branch (802:9): [True: 558, False: 9.50k]
  ------------------
  803|    558|        goto done;
  804|  9.50k|    working = mp_time_ns() < frame_end;
  805|       |
  806|  10.0k|done:
  807|  10.0k|    return working && in->hasframe;
  ------------------
  |  Branch (807:12): [True: 0, False: 10.0k]
  |  Branch (807:23): [True: 0, False: 0]
  ------------------
  808|  9.50k|}
vo.c:wakeup_core:
  384|   146k|{
  385|   146k|    vo->extra.wakeup_cb(vo->extra.wakeup_ctx);
  386|   146k|}
vo.c:reset_vsync_timings:
  391|  86.2k|{
  392|  86.2k|    struct vo_internal *in = vo->in;
  393|  86.2k|    in->drop_point = 0;
  394|  86.2k|    in->base_vsync = 0;
  395|  86.2k|    in->expecting_vsync = false;
  396|  86.2k|    in->num_successive_vsyncs = 0;
  397|  86.2k|}
vo.c:forget_frames:
  700|  19.7k|{
  701|  19.7k|    struct vo_internal *in = vo->in;
  702|  19.7k|    in->hasframe = false;
  703|  19.7k|    in->hasframe_rendered = false;
  704|  19.7k|    in->drop_count = 0;
  705|  19.7k|    in->delayed_count = 0;
  706|  19.7k|    talloc_free(in->frame_queued);
  ------------------
  |  |   47|  19.7k|#define talloc_free                     ta_free
  ------------------
  707|  19.7k|    in->frame_queued = NULL;
  708|  19.7k|    in->current_frame_id += VO_MAX_REQ_FRAMES + 1;
  ------------------
  |  |  218|  19.7k|#define VO_MAX_REQ_FRAMES 10
  ------------------
  709|       |    // don't unref current_frame; we always want to be able to redraw it
  710|  19.7k|    if (in->current_frame) {
  ------------------
  |  Branch (710:9): [True: 1.12k, False: 18.6k]
  ------------------
  711|  1.12k|        in->current_frame->num_vsyncs = 0; // but reset future repeats
  712|  1.12k|        in->current_frame->display_synced = false; // mark discontinuity
  713|  1.12k|    }
  714|  19.7k|}
vo.c:run_query_format:
 1295|  14.2k|{
 1296|  14.2k|    void **pp = p;
 1297|  14.2k|    struct vo *vo = pp[0];
 1298|  14.2k|    uint8_t *list = pp[1];
 1299|  7.93M|    for (int format = IMGFMT_START; format < IMGFMT_END; format++)
  ------------------
  |  Branch (1299:37): [True: 7.92M, False: 14.2k]
  ------------------
 1300|  7.92M|        list[format - IMGFMT_START] = vo->driver->query_format(vo, format);
 1301|  14.2k|}
vo.c:get_display_synced_frame_end:
  774|  10.0k|{
  775|  10.0k|    struct vo_internal *in = vo->in;
  776|  10.0k|    mp_assert(!in->frame_queued);
  ------------------
  |  |   41|  10.0k|#define mp_assert assert
  ------------------
  777|  10.0k|    int64_t res = 0;
  778|  10.0k|    if (in->base_vsync && in->vsync_interval > 1 && in->current_frame) {
  ------------------
  |  Branch (778:9): [True: 0, False: 10.0k]
  |  Branch (778:27): [True: 0, False: 0]
  |  Branch (778:53): [True: 0, False: 0]
  ------------------
  779|      0|        res = in->base_vsync;
  780|      0|        int extra = !!in->rendering;
  781|      0|        res += (in->current_frame->num_vsyncs + extra) * in->vsync_interval;
  782|      0|        if (!in->current_frame->display_synced)
  ------------------
  |  Branch (782:13): [True: 0, False: 0]
  ------------------
  783|      0|            res = 0;
  784|      0|    }
  785|  10.0k|    return res;
  786|  10.0k|}
vo.c:destroy_frame:
 1478|   144k|{
 1479|   144k|    struct vo_frame *frame = p;
 1480|   288k|    for (int n = 0; n < frame->num_frames; n++)
  ------------------
  |  Branch (1480:21): [True: 144k, False: 144k]
  ------------------
 1481|   144k|        talloc_free(frame->frames[n]);
  ------------------
  |  |   47|   144k|#define talloc_free                     ta_free
  ------------------
 1482|   144k|}

vo_null.c:preinit:
   71|  2.78k|{
   72|  2.78k|    return 0;
   73|  2.78k|}
vo_null.c:query_format:
   57|  7.92M|{
   58|  7.92M|    return 1;
   59|  7.92M|}
vo_null.c:reconfig:
   62|  9.26k|{
   63|  9.26k|    return 0;
   64|  9.26k|}
vo_null.c:control:
   76|   181k|{
   77|   181k|    struct priv *p = vo->priv;
   78|   181k|    switch (request) {
  ------------------
  |  Branch (78:13): [True: 179k, False: 2.78k]
  ------------------
   79|  2.78k|    case VOCTRL_GET_DISPLAY_FPS:
  ------------------
  |  Branch (79:5): [True: 2.78k, False: 179k]
  ------------------
   80|  2.78k|        if (!p->cfg_fps)
  ------------------
  |  Branch (80:13): [True: 2.78k, False: 0]
  ------------------
   81|  2.78k|            break;
   82|      0|        *(double *)data = p->cfg_fps;
   83|      0|        return VO_TRUE;
  ------------------
  |  |  148|      0|#define VO_TRUE         true
  ------------------
   84|   181k|    }
   85|   181k|    return VO_NOTIMPL;
  ------------------
  |  |  152|   181k|#define VO_NOTIMPL      -3
  ------------------
   86|   181k|}
vo_null.c:draw_frame:
   36|  72.5k|{
   37|  72.5k|    return VO_TRUE;
  ------------------
  |  |  148|  72.5k|#define VO_TRUE         true
  ------------------
   38|  72.5k|}
vo_null.c:flip_page:
   41|  72.5k|{
   42|  72.5k|    struct priv *p = vo->priv;
   43|  72.5k|    if (p->cfg_fps) {
  ------------------
  |  Branch (43:9): [True: 0, False: 72.5k]
  ------------------
   44|      0|        int64_t ft = 1e9 / p->cfg_fps;
   45|      0|        int64_t prev_vsync = mp_time_ns() / ft;
   46|      0|        int64_t target_time = (prev_vsync + 1) * ft;
   47|      0|        for (;;) {
   48|      0|            int64_t now = mp_time_ns();
   49|      0|            if (now >= target_time)
  ------------------
  |  Branch (49:17): [True: 0, False: 0]
  ------------------
   50|      0|                break;
   51|      0|            mp_sleep_ns(target_time - now);
   52|      0|        }
   53|      0|    }
   54|  72.5k|}
vo_null.c:uninit:
   67|  2.78k|{
   68|  2.78k|}

mp_img_swap_to_native:
  455|  71.9k|{
  456|  71.9k|    int avfmt = imgfmt2pixfmt(img->imgfmt);
  457|  71.9k|    int to = AV_PIX_FMT_NONE;
  458|   359k|    for (int n = 0; endian_swaps[n][0] != AV_PIX_FMT_NONE; n++) {
  ------------------
  |  Branch (458:21): [True: 287k, False: 71.9k]
  ------------------
  459|   287k|        if (endian_swaps[n][0] == avfmt)
  ------------------
  |  Branch (459:13): [True: 0, False: 287k]
  ------------------
  460|      0|            to = endian_swaps[n][1];
  461|   287k|    }
  462|  71.9k|    if (to == AV_PIX_FMT_NONE || !mp_image_make_writeable(img))
  ------------------
  |  Branch (462:9): [True: 71.9k, False: 0]
  |  Branch (462:34): [True: 0, False: 0]
  ------------------
  463|  71.9k|        return img;
  464|      0|    int elems = img->fmt.bpp[0] / 8 / 2 * img->w;
  465|      0|    for (int y = 0; y < img->h; y++) {
  ------------------
  |  Branch (465:21): [True: 0, False: 0]
  ------------------
  466|      0|        uint16_t *p = (uint16_t *)(img->planes[0] + y * img->stride[0]);
  467|      0|        for (int i = 0; i < elems; i++)
  ------------------
  |  Branch (467:25): [True: 0, False: 0]
  ------------------
  468|      0|            p[i] = av_be2ne16(p[i]);
  469|      0|    }
  470|      0|    mp_image_setfmt(img, pixfmt2imgfmt(to));
  471|      0|    return img;
  472|  71.9k|}

