| 210 | } |
| 211 | |
| 212 | static int webm_chunk_write_packet(AVFormatContext *s, AVPacket *pkt) |
| 213 | { |
| 214 | WebMChunkContext *wc = s->priv_data; |
| 215 | AVFormatContext *oc = wc->avf; |
| 216 | AVStream *st = s->streams[pkt->stream_index]; |
| 217 | int ret; |
| 218 | |
| 219 | if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { |
| 220 | if (wc->prev_pts != AV_NOPTS_VALUE) |
| 221 | wc->duration_written += av_rescale_q(pkt->pts - wc->prev_pts, |
| 222 | st->time_base, |
| 223 | (AVRational) {1, 1000}); |
| 224 | wc->prev_pts = pkt->pts; |
| 225 | } |
| 226 | |
| 227 | // For video, a new chunk is started only on key frames. For audio, a new |
| 228 | // chunk is started based on chunk_duration. Also, a new chunk is started |
| 229 | // unconditionally if there is no currently open chunk. |
| 230 | if (!oc->pb || (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && |
| 231 | (pkt->flags & AV_PKT_FLAG_KEY)) || |
| 232 | (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && |
| 233 | wc->duration_written >= wc->chunk_duration)) { |
| 234 | wc->duration_written = 0; |
| 235 | if ((ret = chunk_end(s, 1)) < 0 || (ret = chunk_start(s)) < 0) { |
| 236 | return ret; |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | // We only have one stream, so use the non-interleaving av_write_frame. |
| 241 | return av_write_frame(oc, pkt); |
| 242 | } |
| 243 | |
| 244 | static int webm_chunk_write_trailer(AVFormatContext *s) |
| 245 | { |
nothing calls this directly
no test coverage detected