FFmpeg
Loading...
Searching...
No Matches
dts2pts.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 James Almer
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * Derive PTS by reordering DTS from supported streams
24 */
25
26#include <stdbool.h>
27
29#include "libavutil/avassert.h"
30#include "libavutil/fifo.h"
31#include "libavutil/mem.h"
32#include "libavutil/tree.h"
33#include "libavutil/refstruct.h"
34
35#include "libavcodec/bsf.h"
37#include "libavcodec/cbs.h"
38#include "libavcodec/cbs_h264.h"
39#include "libavcodec/cbs_h265.h"
41#include "libavcodec/h264_ps.h"
42#include "libavcodec/hevc/ps.h"
43
44// Damaged frames leave their up to 2 timestamp nodes behind unconsumed.
45// This many damaged frames are tolerated before the oldest leftovers are
46// evicted; no timestamp of a valid frame is lost below this.
47#define MAX_DAMAGED_FRAMES 32
48
49typedef struct DTS2PTSNode {
52 int poc;
53 int gop;
54 int64_t serial; // insertion order, evicting the stalest node first
55 struct DTS2PTSNode *next; // valid only during same-gop re-keying
57
58typedef struct DTS2PTSFrame {
60 int poc;
62 int gop;
64
73
79
106
107// AVTreeNode callbacks
108static int cmp_insert(const void *key, const void *node)
109{
110 int ret = ((const DTS2PTSNode *)key)->poc - ((const DTS2PTSNode *)node)->poc;
111 if (!ret)
112 ret = ((const DTS2PTSNode *)key)->gop - ((const DTS2PTSNode *)node)->gop;
113 return ret;
114}
115
116static int cmp_find(const void *key, const void *node)
117{
118 const DTS2PTSFrame * key1 = key;
119 const DTS2PTSNode *node1 = node;
120 int ret = FFDIFFSIGN(key1->poc, node1->poc);
121 if (!ret)
122 ret = key1->gop - node1->gop;
123 return ret;
124}
125
126static int dec_poc(void *opaque, void *elem)
127{
128 DTS2PTSNode *node = elem;
129 int dec = *(int *)opaque;
130 node->poc -= dec;
131 return 0;
132}
133
134static int free_node(void *opaque, void *elem)
135{
136 DTS2PTSNode *node = elem;
137 av_refstruct_unref(&node);
138 return 0;
139}
140
141static int find_stalest(void *opaque, void *elem)
142{
143 DTS2PTSNode **stalest = opaque;
144 DTS2PTSNode *node = elem;
145 if (!*stalest || node->serial < (*stalest)->serial)
146 *stalest = node;
147 return 0;
148}
149
150// Shared functions
152 int poc, int poc_diff, int gop)
153{
154 DTS2PTSContext *s = ctx->priv_data;
155
156 for (int i = 0; i < poc_diff; i++) {
157 struct AVTreeNode *node = av_tree_node_alloc();
158 DTS2PTSNode *poc_node, *ret;
159 if (!node)
160 return AVERROR(ENOMEM);
161 poc_node = av_refstruct_pool_get(s->node_pool);
162 if (!poc_node) {
163 av_free(node);
164 return AVERROR(ENOMEM);
165 }
166 if (i && ts != AV_NOPTS_VALUE)
167 ts += duration / poc_diff;
168 *poc_node = (DTS2PTSNode) { ts, duration, poc++, gop, s->serial++ };
169 ret = av_tree_insert(&s->root, poc_node, cmp_insert, &node);
170 if (ret && ret != poc_node) {
171 *ret = *poc_node;
172 av_refstruct_unref(&poc_node);
173 av_free(node);
174 } else
175 s->nb_nodes++;
176 }
177 return 0;
178}
179
180// H.264
187
189{
190 DTS2PTSContext *s = ctx->priv_data;
191 DTS2PTSH264Context *h264 = &s->u.h264;
192
193 s->cbc->decompose_unit_types = h264_decompose_unit_types;
194 s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(h264_decompose_unit_types);
195
196 s->nb_frame = -(ctx->par_in->video_delay << 1);
197 h264->last_poc = h264->highest_poc = INT_MIN;
198
199 return 0;
200}
201
203{
204 if (header->nal_unit_header.nal_ref_idc == 0 ||
205 !header->adaptive_ref_pic_marking_mode_flag)
206 return 0;
207
208 for (int i = 0; i < H264_MAX_MMCO_COUNT; i++) {
209 if (header->mmco[i].memory_management_control_operation == 0)
210 return 0;
211 else if (header->mmco[i].memory_management_control_operation == 5)
212 return 1;
213 }
214
215 return 0;
216}
217
218static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
219{
220 DTS2PTSContext *s = ctx->priv_data;
221 DTS2PTSH264Context *h264 = &s->u.h264;
223 int poc_diff, ret;
224
225 poc_diff = (h264->picture_structure == 3) + 1;
226 if (h264->sps.frame_mbs_only_flag && h264->poc_diff)
227 poc_diff = FFMIN(poc_diff, h264->poc_diff);
228 if (poc < 0) {
229 av_tree_enumerate(s->root, &poc_diff, NULL, dec_poc);
230 s->nb_frame -= poc_diff;
231 }
232 // Check if there was a POC reset (Like an IDR slice)
233 if (s->nb_frame > h264->highest_poc) {
234 s->nb_frame = 0;
235 s->gop = (s->gop + 1) % s->fifo_size;
236 h264->highest_poc = h264->last_poc;
237 }
238
239 ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, poc_diff, s->gop);
240 if (ret < 0)
241 return ret;
242 av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, dts %"PRId64"\n",
243 poc, s->gop, pkt->dts);
244 s->nb_frame += poc_diff;
245
246 // Add frame to output FIFO only once
247 if (*queued)
248 return 0;
249
250 frame = (DTS2PTSFrame) { pkt, poc, poc_diff, s->gop };
251 ret = av_fifo_write(s->fifo, &frame, 1);
252 av_assert2(ret >= 0);
253 s->nb_pending += poc_diff;
254 *queued = 1;
255
256 return 0;
257}
258
260{
261 DTS2PTSContext *s = ctx->priv_data;
262 DTS2PTSH264Context *h264 = &s->u.h264;
263 CodedBitstreamFragment *au = &s->au;
264 AVPacket *in;
265 int output_picture_number = INT_MIN;
266 int field_poc[2];
267 int queued = 0, ret;
268
269 ret = ff_bsf_get_packet(ctx, &in);
270 if (ret < 0)
271 return ret;
272
273 ret = ff_cbs_read_packet(s->cbc, au, in);
274 if (ret < 0) {
275 av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
276 goto fail;
277 }
278
279 for (int i = 0; i < au->nb_units; i++) {
280 CodedBitstreamUnit *unit = &au->units[i];
281
282 switch (unit->type) {
284 h264->poc.prev_frame_num = 0;
285 h264->poc.prev_frame_num_offset = 0;
286 h264->poc.prev_poc_msb =
287 h264->poc.prev_poc_lsb = 0;
289 case H264_NAL_SLICE: {
290 const H264RawSlice *slice = unit->content;
291 const H264RawSliceHeader *header = &slice->header;
292 const CodedBitstreamH264Context *cbs_h264 = s->cbc->priv_data;
293 const H264RawSPS *sps = cbs_h264->active_sps;
294 int got_reset;
295
296 if (!sps) {
297 av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
299 goto fail;
300 }
301 // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
302 h264->sps.frame_mbs_only_flag = sps->frame_mbs_only_flag;
303 h264->sps.log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
304 h264->sps.poc_type = sps->pic_order_cnt_type;
305 h264->sps.log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
306 h264->sps.offset_for_non_ref_pic = sps->offset_for_non_ref_pic;
307 h264->sps.offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field;
308 h264->sps.poc_cycle_length = sps->num_ref_frames_in_pic_order_cnt_cycle;
309 for (int j = 0; j < h264->sps.poc_cycle_length; j++)
310 h264->sps.offset_for_ref_frame[j] = sps->offset_for_ref_frame[j];
311
312 h264->picture_structure = sps->frame_mbs_only_flag ? 3 :
313 (header->field_pic_flag ?
314 header->field_pic_flag + header->bottom_field_flag : 3);
315
316 h264->poc.frame_num = header->frame_num;
317 h264->poc.poc_lsb = header->pic_order_cnt_lsb;
318 h264->poc.delta_poc_bottom = header->delta_pic_order_cnt_bottom;
319 h264->poc.delta_poc[0] = header->delta_pic_order_cnt[0];
320 h264->poc.delta_poc[1] = header->delta_pic_order_cnt[1];
321
322 field_poc[0] = field_poc[1] = INT_MAX;
323 ret = ff_h264_init_poc(field_poc, &output_picture_number, &h264->sps,
324 &h264->poc, h264->picture_structure,
325 header->nal_unit_header.nal_ref_idc);
326 if (ret < 0) {
327 av_log(ctx, AV_LOG_ERROR, "ff_h264_init_poc() failure\n");
328 goto fail;
329 }
330
331 got_reset = get_mmco_reset(header);
332 h264->poc.prev_frame_num = got_reset ? 0 : h264->poc.frame_num;
333 h264->poc.prev_frame_num_offset = got_reset ? 0 : h264->poc.frame_num_offset;
334 if (header->nal_unit_header.nal_ref_idc != 0) {
335 h264->poc.prev_poc_msb = got_reset ? 0 : h264->poc.poc_msb;
336 if (got_reset)
337 h264->poc.prev_poc_lsb = h264->picture_structure == 2 ? 0 : field_poc[0];
338 else
339 h264->poc.prev_poc_lsb = h264->poc.poc_lsb;
340 }
341
342 if (output_picture_number != h264->last_poc) {
343 if (h264->last_poc != INT_MIN) {
344 int64_t diff = FFABS(h264->last_poc - (int64_t)output_picture_number);
345
346 if ((output_picture_number < 0) && !h264->last_poc)
347 h264->poc_diff = 0;
348 else if (FFABS((int64_t)output_picture_number) < h264->poc_diff) {
349 diff = FFABS(output_picture_number);
350 h264->poc_diff = 0;
351 }
352 if ((!h264->poc_diff || (h264->poc_diff > diff)) && diff <= INT_MAX) {
353 h264->poc_diff = diff;
354 if (h264->poc_diff == 1 && h264->sps.frame_mbs_only_flag) {
355 av_tree_enumerate(s->root, &h264->poc_diff, NULL, dec_poc);
356 s->nb_frame -= 2;
357 }
358 }
359 }
360 h264->last_poc = output_picture_number;
361 h264->highest_poc = FFMAX(h264->highest_poc, output_picture_number);
362
363 ret = h264_queue_frame(ctx, in, output_picture_number, &queued);
364 if (ret < 0)
365 goto fail;
366 }
367 break;
368 }
369 default:
370 break;
371 }
372 }
373
374 if (output_picture_number == INT_MIN) {
375 av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
377 goto fail;
378 }
379
380 ret = 0;
381fail:
382 ff_cbs_fragment_reset(au);
383 if (!queued)
384 av_packet_free(&in);
385
386 return ret;
387}
388
390{
391 DTS2PTSContext *s = ctx->priv_data;
392 DTS2PTSH264Context *h264 = &s->u.h264;
393
394 memset(&h264->sps, 0, sizeof(h264->sps));
395 memset(&h264->poc, 0, sizeof(h264->poc));
396 s->nb_frame = -(ctx->par_in->video_delay << 1);
397 h264->last_poc = h264->highest_poc = INT_MIN;
398}
399
401{
402 DTS2PTSContext *s = ctx->priv_data;
403 DTS2PTSHEVCContext *hevc = &s->u.hevc;
404
405 hevc->gop = -1;
406 hevc->poc_tid0 = 0;
407 hevc->highest_poc = INT_MIN;
408 s->nb_frame = -ctx->par_in->video_delay;
409
410 return 0;
411}
412
414{
415 hevc_init(ctx);
416}
417
419{
420 DTS2PTSContext *s = ctx->priv_data;
421 const CodedBitstreamH265Context *cbs_hevc = s->cbc->priv_data;
422 const H265RawVPS *vps = cbs_hevc->active_vps;
423
424 if (!vps)
425 return AVERROR_INVALIDDATA;
426
427 int latency = vps->vps_max_num_reorder_pics[0];
428 if (vps->vps_max_latency_increase_plus1[0])
429 latency += vps->vps_max_latency_increase_plus1[0] - 1;
430
431 s->nb_frame = poc - latency;
432 av_log(ctx, AV_LOG_DEBUG, "Latency %d, poc %d, nb_frame %d\n",
433 latency, poc, s->nb_frame);
434
435 return 0;
436}
437
442
443static int collect_same_gop(void *opaque, void *elem)
444{
445 DTS2PTSCollect *c = opaque;
446 DTS2PTSNode *node = elem;
447 if (node->gop == c->gop) {
448 if (c->tail)
449 c->tail->next = node;
450 else
451 c->head = node;
452 c->tail = node;
453 node->next = NULL;
454 }
455 return 0;
456}
457
458static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued)
459{
460 DTS2PTSContext *s = ctx->priv_data;
461 DTS2PTSHEVCContext *hevc = &s->u.hevc;
462 int ret;
463
464 if (hevc->gop == -1) {
465 ret = hevc_init_nb_frame(ctx, poc);
466 if (ret < 0)
467 return ret;
468 hevc->gop = s->gop;
469 }
470
471 hevc->highest_poc = FFMAX(hevc->highest_poc, poc);
472 if (s->nb_frame > hevc->highest_poc) {
473 s->nb_frame = 0;
474 s->gop = (s->gop + 1) % s->fifo_size;
475 hevc->highest_poc = poc;
476 }
477
478 if (poc < s->nb_frame && hevc->gop == s->gop) {
479 int dec = s->nb_frame - poc;
480 DTS2PTSCollect c = { s->gop, NULL, NULL };
481
482 s->nb_frame -= dec;
483
484 // Crafted streams can exceed any DPB-based estimate of the node count,
485 // so chain the matching nodes through their next pointers instead of
486 // collecting them into a fixed size array. The chain is in ascending
487 // poc order; processing it in this order keeps the new keys collision
488 // free as any potential collision partner is re-keyed first.
490 while (c.head) {
491 struct AVTreeNode *tnode = NULL;
492 DTS2PTSNode *node = c.head, *r;
493 c.head = node->next;
494 av_tree_insert(&s->root, node, cmp_insert, &tnode);
495 node->poc -= dec;
496 r = av_tree_insert(&s->root, node, cmp_insert, &tnode);
497 if (r && r != node) {
498 *r = *node;
499 av_refstruct_unref(&node);
500 av_free(tnode);
501 s->nb_nodes--;
502 }
503 }
504 }
505
506 ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, 1, s->gop);
507 if (ret < 0)
508 return ret;
509
510 av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, nb_frame %d, dts %"PRId64"\n",
511 poc, s->gop, s->nb_frame, pkt->dts);
512 s->nb_frame++;
513
515 .pkt = pkt,
516 .poc = poc,
517 .poc_diff = 1,
518 .gop = s->gop,
519 };
520 ret = av_fifo_write(s->fifo, &frame, 1);
521 if (ret < 0)
522 return ret;
523 s->nb_pending += frame.poc_diff;
524
525 *queued = true;
526
527 return 0;
528}
529
531{
532 DTS2PTSContext *s = ctx->priv_data;
533 DTS2PTSHEVCContext *hevc = &s->u.hevc;
534 CodedBitstreamFragment *au = &s->au;
535 AVPacket *in;
536 bool queued = 0;
537 int ret = ff_bsf_get_packet(ctx, &in);
538 if (ret < 0)
539 return ret;
540
541 ret = ff_cbs_read_packet(s->cbc, au, in);
542 if (ret < 0) {
543 av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
544 goto fail;
545 }
546
547 for (int i = 0; i < au->nb_units; i++) {
548 CodedBitstreamUnit *unit = &au->units[i];
550
551 bool is_slice = type <= HEVC_NAL_RASL_R || (type >= HEVC_NAL_BLA_W_LP &&
553 if (!is_slice)
554 continue;
555
556 const H265RawSliceHeader *slice = unit->content;
558 continue;
559
560 const CodedBitstreamH265Context *cbs_hevc = s->cbc->priv_data;
561 const H265RawSPS *sps = cbs_hevc->active_sps;
562 if (!sps) {
563 av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
565 goto fail;
566 }
567
568 int poc;
570 poc = 0;
571 hevc->gop = (hevc->gop + 1) % s->fifo_size;
572 } else {
573 unsigned log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
574 int poc_lsb = slice->slice_pic_order_cnt_lsb;
575
576 poc = ff_hevc_compute_poc2(log2_max_poc_lsb, hevc->poc_tid0, poc_lsb, type);
577 }
578
579 if (slice->nal_unit_header.nuh_temporal_id_plus1 == 1 &&
584 hevc->poc_tid0 = poc;
585 }
586
587 ret = hevc_queue_frame(ctx, in, poc, &queued);
588 if (ret < 0)
589 goto fail;
590 break;
591 }
592
593 if (!queued) {
594 av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
596 }
597
598fail:
599 ff_cbs_fragment_reset(au);
600 if (!queued)
601 av_packet_free(&in);
602 return ret;
603}
604
605// Core functions
606static const struct {
611 size_t fifo_size;
612} func_tab[] = {
616
618{
619 DTS2PTSContext *s = ctx->priv_data;
620 CodedBitstreamFragment *au = &s->au;
621 int i, ret;
622
623 for (i = 0; i < FF_ARRAY_ELEMS(func_tab); i++) {
624 if (func_tab[i].id == ctx->par_in->codec_id) {
625 s->init = func_tab[i].init;
626 s->filter = func_tab[i].filter;
627 s->flush = func_tab[i].flush;
628 s->fifo_size = func_tab[i].fifo_size;
629 break;
630 }
631 }
632 if (i == FF_ARRAY_ELEMS(func_tab))
633 return AVERROR_BUG;
634 av_assert0(s->filter && s->fifo_size);
635
636 s->fifo = av_fifo_alloc2(s->fifo_size, sizeof(DTS2PTSFrame), 0);
637 if (!s->fifo)
638 return AVERROR(ENOMEM);
639
640 s->node_pool = av_refstruct_pool_alloc(sizeof(DTS2PTSNode),
642
643 if (!s->node_pool)
644 return AVERROR(ENOMEM);
645
646 ret = ff_cbs_init(&s->cbc, ctx->par_in->codec_id, ctx);
647 if (ret < 0)
648 return ret;
649
650 if (s->init) {
651 ret = s->init(ctx);
652 if (ret < 0)
653 return ret;
654 }
655
656 if (!ctx->par_in->extradata_size)
657 return 0;
658
659 ret = ff_cbs_read_extradata(s->cbc, au, ctx->par_in);
660 if (ret < 0)
661 av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
662
663 ff_cbs_fragment_reset(au);
664
665 return 0;
666}
667
669{
670 DTS2PTSContext *s = ctx->priv_data;
671 DTS2PTSNode *poc_node = NULL, *next[2] = { NULL, NULL };
673 int ret;
674
675 // Fill up the FIFO and POC tree
676 while (!s->eof && av_fifo_can_write(s->fifo)) {
677 ret = s->filter(ctx);
678 if (ret < 0) {
679 if (ret != AVERROR_EOF)
680 return ret;
681 s->eof = 1;
682 }
683 }
684
685 if (!av_fifo_can_read(s->fifo))
686 return AVERROR_EOF;
687
688 // Fetch a packet from the FIFO
689 ret = av_fifo_read(s->fifo, &frame, 1);
690 av_assert2(ret >= 0);
691 s->nb_pending -= frame.poc_diff;
693 av_packet_free(&frame.pkt);
694
695 // Search the timestamp for the requested POC and set PTS
696 poc_node = av_tree_find(s->root, &frame, cmp_find, (void **)next);
697 if (!poc_node) {
698 poc_node = next[1];
699 if (!poc_node || poc_node->poc != frame.poc)
700 poc_node = next[0];
701 }
702 if (poc_node && poc_node->poc == frame.poc) {
703 out->pts = poc_node->dts;
704 if (!s->eof) {
705 // Remove the found entry from the tree
706 DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc + 1, frame.poc_diff, frame.gop };
707 int64_t dts = out->pts;
708 for (; dup.poc_diff > 0; dup.poc++, dup.poc_diff--) {
709 struct AVTreeNode *node = NULL;
710 if (!poc_node || poc_node->dts != dts)
711 continue;
712 // 2nd field nodes were inserted with this offset added
713 if (dts != AV_NOPTS_VALUE)
714 dts += poc_node->duration / frame.poc_diff;
715 av_tree_insert(&s->root, poc_node, cmp_insert, &node);
716 av_refstruct_unref(&poc_node);
717 av_free(node);
718 s->nb_nodes--;
719 poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
720 }
721 }
722 } else if (s->eof && frame.poc > INT_MIN) {
723 DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc - 1, frame.poc_diff, frame.gop };
724 poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
725 if (poc_node && poc_node->poc == dup.poc) {
726 out->pts = poc_node->dts;
727 if (out->pts != AV_NOPTS_VALUE)
728 out->pts += poc_node->duration;
729 ret = alloc_and_insert_node(ctx, out->pts, out->duration,
730 frame.poc, frame.poc_diff, frame.gop);
731 if (ret < 0) {
733 return ret;
734 }
735 av_log(ctx, AV_LOG_DEBUG, "Queueing frame for POC %d, GOP %d, dts %"PRId64", "
736 "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
737 frame.poc, frame.gop, out->pts,
738 poc_node->poc, poc_node->gop, poc_node->dts, poc_node->duration);
739 } else
740 av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
741 } else
742 av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
743
744 // The pending packets consume nb_pending nodes; frames whose lookup above
745 // missed leave nodes behind which nothing consumes anymore. Keep the
746 // leftovers of up to MAX_DAMAGED_FRAMES frames, then evict the nodes
747 // unconsumed the longest.
748 // At EOF nodes are deliberately kept to regenerate timestamps from.
749 while (!s->eof && s->nb_nodes > s->nb_pending + 2 * MAX_DAMAGED_FRAMES) {
750 DTS2PTSNode *stale = NULL;
751 struct AVTreeNode *tnode = NULL;
752 av_tree_enumerate(s->root, &stale, NULL, find_stalest);
753 av_log(ctx, AV_LOG_WARNING, "Evicting unconsumed POC %d, GOP %d\n",
754 stale->poc, stale->gop);
755 av_tree_insert(&s->root, stale, cmp_insert, &tnode);
756 av_refstruct_unref(&stale);
757 av_free(tnode);
758 s->nb_nodes--;
759 }
760
761 av_log(ctx, AV_LOG_DEBUG, "Returning frame for POC %d, GOP %d, dts %"PRId64", pts %"PRId64"\n",
762 frame.poc, frame.gop, out->dts, out->pts);
763
764 return 0;
765}
766
768{
769 DTS2PTSContext *s = ctx->priv_data;
771
772 if (s->flush)
773 s->flush(ctx);
774 s->eof = 0;
775 s->gop = 0;
776
777 while (s->fifo && av_fifo_read(s->fifo, &frame, 1) >= 0)
778 av_packet_free(&frame.pkt);
779
781 av_tree_destroy(s->root);
782 s->root = NULL;
783 s->nb_nodes = 0;
784 s->nb_pending = 0;
785
786 ff_cbs_fragment_reset(&s->au);
787 if (s->cbc)
788 ff_cbs_flush(s->cbc);
789}
790
792{
793 DTS2PTSContext *s = ctx->priv_data;
794
796
797 av_fifo_freep2(&s->fifo);
798 av_refstruct_pool_uninit(&s->node_pool);
799 ff_cbs_fragment_free(&s->au);
800 ff_cbs_close(&s->cbc);
801}
802
808
810 .p.name = "dts2pts",
811 .p.codec_ids = dts2pts_codec_ids,
812 .priv_data_size = sizeof(DTS2PTSContext),
817};
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition avassert.h:68
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
const FFBitStreamFilter ff_dts2pts_bsf
Definition dts2pts.c:809
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
Definition bsf.c:233
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
#define s(width, name)
Definition cbs_vp9.c:198
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
static AVFrame * frame
static int h264_filter(AVBSFContext *ctx)
Definition dts2pts.c:259
static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued)
Definition dts2pts.c:458
size_t fifo_size
Definition dts2pts.c:611
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
static int cmp_find(const void *key, const void *node)
Definition dts2pts.c:116
static enum AVCodecID dts2pts_codec_ids[]
Definition dts2pts.c:803
static void hevc_flush(AVBSFContext *ctx)
Definition dts2pts.c:413
static void dts2pts_close(AVBSFContext *ctx)
Definition dts2pts.c:791
static int hevc_init_nb_frame(AVBSFContext *ctx, int poc)
Definition dts2pts.c:418
static int dec_poc(void *opaque, void *elem)
Definition dts2pts.c:126
static const CodedBitstreamUnitType h264_decompose_unit_types[]
Definition dts2pts.c:181
static int h264_init(AVBSFContext *ctx)
Definition dts2pts.c:188
enum AVCodecID id
Definition dts2pts.c:607
static int get_mmco_reset(const H264RawSliceHeader *header)
Definition dts2pts.c:202
static int cmp_insert(const void *key, const void *node)
Definition dts2pts.c:108
static void h264_flush(AVBSFContext *ctx)
Definition dts2pts.c:389
static int hevc_init(AVBSFContext *ctx)
Definition dts2pts.c:400
static const struct @213162273235257122266207155164174051374107224106 func_tab[]
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static int free_node(void *opaque, void *elem)
Definition dts2pts.c:134
static int dts2pts_init(AVBSFContext *ctx)
Definition dts2pts.c:617
static int find_stalest(void *opaque, void *elem)
Definition dts2pts.c:141
static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
Definition dts2pts.c:218
static int alloc_and_insert_node(AVBSFContext *ctx, int64_t ts, int64_t duration, int poc, int poc_diff, int gop)
Definition dts2pts.c:151
static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
Definition dts2pts.c:668
static void dts2pts_flush(AVBSFContext *ctx)
Definition dts2pts.c:767
#define MAX_DAMAGED_FRAMES
Definition dts2pts.c:47
static int collect_same_gop(void *opaque, void *elem)
Definition dts2pts.c:443
static int hevc_filter(AVBSFContext *ctx)
Definition dts2pts.c:530
const char * key
static int64_t duration
Definition ffplay.c:330
A generic FIFO API.
#define fail
Definition test.h:479
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition packet.c:491
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
size_t av_fifo_can_write(const AVFifo *f)
Definition fifo.c:94
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
void av_tree_enumerate(AVTreeNode *t, void *opaque, int(*cmp)(void *opaque, void *elem), int(*enu)(void *opaque, void *elem))
Apply enu(opaque, &elem) to all the elements in the tree in a given range.
Definition tree.c:155
void * av_tree_insert(AVTreeNode **tp, void *key, int(*cmp)(const void *key, const void *b), AVTreeNode **next)
Insert or remove an element.
Definition tree.c:59
void av_tree_destroy(AVTreeNode *t)
Definition tree.c:146
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
Definition tree.c:34
@ H264_MAX_DPB_FRAMES
Definition h264.h:76
@ H264_MAX_MMCO_COUNT
Definition h264.h:92
@ H264_NAL_PPS
Definition h264.h:42
@ H264_NAL_SPS
Definition h264.h:41
@ H264_NAL_SLICE
Definition h264.h:35
@ H264_NAL_IDR_SLICE
Definition h264.h:39
int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc, const SPS *sps, H264POCContext *pc, int picture_structure, int nal_ref_idc)
Definition h264_parse.c:280
H.264 decoder/parser shared code.
H.264 parameter set handling.
int ff_hevc_compute_poc2(unsigned log2_max_poc_lsb, int pocTid0, int poc_lsb, int nal_unit_type)
Compute POC of the current frame and return it.
Definition ps.c:2485
cl_device_type type
#define r
Definition input.c:42
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition cbs.h:66
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
@ HEVC_NAL_RASL_N
Definition hevc.h:37
@ HEVC_NAL_CRA_NUT
Definition hevc.h:50
@ HEVC_NAL_TRAIL_N
Definition hevc.h:29
@ HEVC_NAL_BLA_W_LP
Definition hevc.h:45
@ HEVC_NAL_IDR_W_RADL
Definition hevc.h:48
@ HEVC_NAL_IDR_N_LP
Definition hevc.h:49
@ HEVC_NAL_TSA_N
Definition hevc.h:31
@ HEVC_NAL_STSA_N
Definition hevc.h:33
@ HEVC_NAL_RASL_R
Definition hevc.h:38
@ HEVC_NAL_RADL_R
Definition hevc.h:36
@ HEVC_NAL_RADL_N
Definition hevc.h:35
@ HEVC_MAX_DPB_SIZE
Definition hevc.h:120
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFDIFFSIGN(x, y)
Comparator.
Definition macros.h:45
Memory handling functions.
AVRefStructPool * av_refstruct_pool_alloc(size_t size, unsigned flags)
Equivalent to av_refstruct_pool_alloc(size, flags, NULL, NULL, NULL, NULL, NULL)
Definition refstruct.c:335
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:120
void * av_refstruct_pool_get(AVRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition refstruct.c:297
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
#define AV_REFSTRUCT_POOL_FLAG_NO_ZEROING
If this flag is not set, every object in the pool will be zeroed before the init callback is called o...
Definition refstruct.h:196
static const uint8_t header[24]
Definition sdr2.c:68
#define FF_ARRAY_ELEMS(a)
The bitstream filter state.
Definition bsf.h:68
Definition fifo.c:35
This structure stores compressed data.
Definition packet.h:580
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:183
Context structure for coded bitstream operations.
Definition cbs.h:226
Coded bitstream fragment structure, combining one or more units.
Definition cbs.h:129
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition cbs.h:175
int nb_units
Number of units in this fragment.
Definition cbs.h:160
const H264RawSPS * active_sps
Definition cbs_h264.h:436
const H265RawVPS * active_vps
Definition cbs_h265.h:764
const H265RawSPS * active_sps
Definition cbs_h265.h:765
Coded bitstream unit structure.
Definition cbs.h:77
void * content
Pointer to the decomposed form of this unit.
Definition cbs.h:114
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition cbs.h:81
DTS2PTSNode * tail
Definition dts2pts.c:440
DTS2PTSNode * head
Definition dts2pts.c:440
DTS2PTSHEVCContext hevc
Definition dts2pts.c:96
CodedBitstreamContext * cbc
Definition dts2pts.c:91
AVRefStructPool * node_pool
Definition dts2pts.c:83
CodedBitstreamFragment au
Definition dts2pts.c:92
AVFifo * fifo
Definition dts2pts.c:82
int64_t serial
Definition dts2pts.c:101
size_t fifo_size
Definition dts2pts.c:89
struct AVTreeNode * root
Definition dts2pts.c:81
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:86
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:88
int(* filter)(AVBSFContext *ctx)
Definition dts2pts.c:87
DTS2PTSH264Context h264
Definition dts2pts.c:95
AVPacket * pkt
Definition dts2pts.c:59
int poc_diff
Definition dts2pts.c:61
H264POCContext poc
Definition dts2pts.c:66
int64_t dts
Definition dts2pts.c:50
struct DTS2PTSNode * next
Definition dts2pts.c:55
int64_t duration
Definition dts2pts.c:51
int64_t serial
Definition dts2pts.c:54
int frame_num_offset
for POC type 2
Definition h264_parse.h:90
int prev_frame_num_offset
for POC type 2
Definition h264_parse.h:91
int prev_frame_num
frame_num of the last pic for POC type 1/2
Definition h264_parse.h:92
int prev_poc_msb
poc_msb of the last reference pic for POC type 0
Definition h264_parse.h:88
int delta_poc[2]
Definition h264_parse.h:86
int prev_poc_lsb
poc_lsb of the last reference pic for POC type 0
Definition h264_parse.h:89
H264RawSliceHeader header
Definition cbs_h264.h:409
uint8_t nuh_temporal_id_plus1
Definition cbs_h265.h:33
uint16_t slice_pic_order_cnt_lsb
Definition cbs_h265.h:510
uint8_t first_slice_segment_in_pic_flag
Definition cbs_h265.h:497
H265RawNALUnitHeader nal_unit_header
Definition cbs_h265.h:495
Sequence parameter set.
Definition h264_ps.h:44
int poc_cycle_length
num_ref_frames_in_pic_order_cnt_cycle
Definition h264_ps.h:56
int log2_max_poc_lsb
log2_max_pic_order_cnt_lsb_minus4
Definition h264_ps.h:52
int32_t offset_for_ref_frame[256]
Definition h264_ps.h:79
int frame_mbs_only_flag
Definition h264_ps.h:62
int offset_for_top_to_bottom_field
Definition h264_ps.h:55
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
Definition h264_ps.h:50
int offset_for_non_ref_pic
Definition h264_ps.h:54
int poc_type
pic_order_cnt_type
Definition h264_ps.h:51
#define av_free(p)
#define av_log(a,...)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(const void *key, const void *b), void *next[2])
Definition tree.c:39
A tree container.
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
static double c[64]