| 2716 | } |
| 2717 | |
| 2718 | int sch_stop(Scheduler *sch, int64_t *finish_ts) |
| 2719 | { |
| 2720 | int ret = 0, err; |
| 2721 | |
| 2722 | if (sch->state != SCH_STATE_STARTED) |
| 2723 | return 0; |
| 2724 | |
| 2725 | atomic_store(&sch->terminate, 1); |
| 2726 | |
| 2727 | for (unsigned type = 0; type < 2; type++) |
| 2728 | for (unsigned i = 0; i < (type ? sch->nb_demux : sch->nb_filters); i++) { |
| 2729 | SchWaiter *w = type ? &sch->demux[i].waiter : &sch->filters[i].waiter; |
| 2730 | waiter_set(w, 1); |
| 2731 | if (type) |
| 2732 | choke_demux(sch, i, 0); // unfreeze to allow draining |
| 2733 | } |
| 2734 | |
| 2735 | for (unsigned i = 0; i < sch->nb_demux; i++) { |
| 2736 | SchDemux *d = &sch->demux[i]; |
| 2737 | |
| 2738 | err = task_stop(sch, &d->task); |
| 2739 | ret = err_merge(ret, err); |
| 2740 | } |
| 2741 | |
| 2742 | for (unsigned i = 0; i < sch->nb_dec; i++) { |
| 2743 | SchDec *dec = &sch->dec[i]; |
| 2744 | |
| 2745 | err = task_stop(sch, &dec->task); |
| 2746 | ret = err_merge(ret, err); |
| 2747 | } |
| 2748 | |
| 2749 | for (unsigned i = 0; i < sch->nb_filters; i++) { |
| 2750 | SchFilterGraph *fg = &sch->filters[i]; |
| 2751 | |
| 2752 | err = task_stop(sch, &fg->task); |
| 2753 | ret = err_merge(ret, err); |
| 2754 | } |
| 2755 | |
| 2756 | for (unsigned i = 0; i < sch->nb_enc; i++) { |
| 2757 | SchEnc *enc = &sch->enc[i]; |
| 2758 | |
| 2759 | err = task_stop(sch, &enc->task); |
| 2760 | ret = err_merge(ret, err); |
| 2761 | } |
| 2762 | |
| 2763 | for (unsigned i = 0; i < sch->nb_mux; i++) { |
| 2764 | SchMux *mux = &sch->mux[i]; |
| 2765 | |
| 2766 | err = task_stop(sch, &mux->task); |
| 2767 | ret = err_merge(ret, err); |
| 2768 | } |
| 2769 | |
| 2770 | if (finish_ts) |
| 2771 | *finish_ts = trailing_dts(sch, 1); |
| 2772 | |
| 2773 | sch->state = SCH_STATE_STOPPED; |
| 2774 | |
| 2775 | return ret; |
no test coverage detected