| 98 | } |
| 99 | |
| 100 | static int mov_write_ttml_document_from_queue(AVFormatContext *s, |
| 101 | AVFormatContext *ttml_ctx, |
| 102 | MOVTrack *track, |
| 103 | AVPacket *pkt, |
| 104 | int64_t *out_start_ts, |
| 105 | int64_t *out_duration) |
| 106 | { |
| 107 | int ret = AVERROR_BUG; |
| 108 | int64_t start_ts = track->start_dts == AV_NOPTS_VALUE ? |
| 109 | 0 : (track->start_dts + track->track_duration); |
| 110 | int64_t end_ts = start_ts; |
| 111 | unsigned int time_limited = 0; |
| 112 | PacketList back_to_queue_list = { 0 }; |
| 113 | |
| 114 | if (*out_start_ts != AV_NOPTS_VALUE) { |
| 115 | // we have non-nopts values here, thus we have been given a time range |
| 116 | time_limited = 1; |
| 117 | start_ts = *out_start_ts; |
| 118 | end_ts = *out_start_ts + *out_duration; |
| 119 | } |
| 120 | |
| 121 | if ((ret = avformat_write_header(ttml_ctx, NULL)) < 0) { |
| 122 | return ret; |
| 123 | } |
| 124 | |
| 125 | while (!avpriv_packet_list_get(&track->squashed_packet_queue, pkt)) { |
| 126 | int64_t pts_before = pkt->pts; |
| 127 | int64_t duration_before = pkt->duration; |
| 128 | |
| 129 | if (time_limited) { |
| 130 | // special cases first: |
| 131 | if (pkt->pts + pkt->duration < start_ts) { |
| 132 | // too late for our fragment, unfortunately |
| 133 | // unref and proceed to next packet in queue. |
| 134 | av_log(s, AV_LOG_WARNING, |
| 135 | "Very late TTML packet in queue, dropping packet with " |
| 136 | "pts: %"PRId64", duration: %"PRId64"\n", |
| 137 | pkt->pts, pkt->duration); |
| 138 | av_packet_unref(pkt); |
| 139 | continue; |
| 140 | } else if (pkt->pts >= end_ts) { |
| 141 | // starts after this fragment, put back to original queue |
| 142 | ret = avpriv_packet_list_put(&track->squashed_packet_queue, |
| 143 | pkt, NULL, |
| 144 | FF_PACKETLIST_FLAG_PREPEND); |
| 145 | if (ret < 0) |
| 146 | goto cleanup; |
| 147 | |
| 148 | break; |
| 149 | } |
| 150 | |
| 151 | // limit packet pts to start_ts |
| 152 | if (pkt->pts < start_ts) { |
| 153 | pkt->duration -= start_ts - pkt->pts; |
| 154 | pkt->pts = start_ts; |
| 155 | } |
| 156 | |
| 157 | if (pkt->pts + pkt->duration > end_ts) { |
no test coverage detected