| 1113 | } |
| 1114 | |
| 1115 | static int mux_task_start(SchMux *mux) |
| 1116 | { |
| 1117 | int ret = 0; |
| 1118 | |
| 1119 | ret = task_start(&mux->task); |
| 1120 | if (ret < 0) |
| 1121 | return ret; |
| 1122 | |
| 1123 | /* flush the pre-muxing queues */ |
| 1124 | while (1) { |
| 1125 | int min_stream = -1; |
| 1126 | Timestamp min_ts = { .ts = AV_NOPTS_VALUE }; |
| 1127 | |
| 1128 | AVPacket *pkt; |
| 1129 | |
| 1130 | // find the stream with the earliest dts or EOF in pre-muxing queue |
| 1131 | for (unsigned i = 0; i < mux->nb_streams; i++) { |
| 1132 | SchMuxStream *ms = &mux->streams[i]; |
| 1133 | |
| 1134 | if (av_fifo_peek(ms->pre_mux_queue.fifo, &pkt, 1, 0) < 0) |
| 1135 | continue; |
| 1136 | |
| 1137 | if (!pkt || pkt->dts == AV_NOPTS_VALUE) { |
| 1138 | min_stream = i; |
| 1139 | break; |
| 1140 | } |
| 1141 | |
| 1142 | if (min_ts.ts == AV_NOPTS_VALUE || |
| 1143 | av_compare_ts(min_ts.ts, min_ts.tb, pkt->dts, pkt->time_base) > 0) { |
| 1144 | min_stream = i; |
| 1145 | min_ts = (Timestamp){ .ts = pkt->dts, .tb = pkt->time_base }; |
| 1146 | } |
| 1147 | } |
| 1148 | |
| 1149 | if (min_stream >= 0) { |
| 1150 | SchMuxStream *ms = &mux->streams[min_stream]; |
| 1151 | |
| 1152 | ret = av_fifo_read(ms->pre_mux_queue.fifo, &pkt, 1); |
| 1153 | av_assert0(ret >= 0); |
| 1154 | |
| 1155 | if (pkt) { |
| 1156 | if (!ms->init_eof) |
| 1157 | ret = tq_send(mux->queue, min_stream, pkt); |
| 1158 | av_packet_free(&pkt); |
| 1159 | if (ret == AVERROR_EOF) |
| 1160 | ms->init_eof = 1; |
| 1161 | else if (ret < 0) |
| 1162 | return ret; |
| 1163 | } else |
| 1164 | tq_send_finish(mux->queue, min_stream); |
| 1165 | |
| 1166 | continue; |
| 1167 | } |
| 1168 | |
| 1169 | break; |
| 1170 | } |
| 1171 | |
| 1172 | atomic_store(&mux->mux_started, 1); |
no test coverage detected