FFmpeg
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 
28 #include "libavutil/avassert.h"
29 #include "libavutil/fifo.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/tree.h"
32 
33 #include "bsf.h"
34 #include "bsf_internal.h"
35 #include "cbs.h"
36 #include "cbs_h264.h"
37 #include "cbs_h265.h"
38 #include "h264_parse.h"
39 #include "h264_ps.h"
40 #include "hevc/ps.h"
41 #include "libavutil/refstruct.h"
42 
43 typedef struct DTS2PTSNode {
46  int poc;
47  int gop;
48 } DTS2PTSNode;
49 
50 typedef struct DTS2PTSFrame {
52  int poc;
53  int poc_diff;
54  int gop;
55 } DTS2PTSFrame;
56 
57 typedef struct DTS2PTSH264Context {
60  int poc_diff;
61  int last_poc;
65 
66 typedef struct DTS2PTSHEVCContext {
67  int gop;
68  int poc_tid0;
71 
72 typedef struct DTS2PTSContext {
73  struct AVTreeNode *root;
76 
77  // Codec specific function pointers and constants
78  int (*init)(AVBSFContext *ctx);
80  void (*flush)(AVBSFContext *ctx);
81  size_t fifo_size;
82 
85 
86  union {
89  } u;
90 
91  int nb_frame;
92  int gop;
93  int eof;
95 
96 // AVTreeNode callbacks
97 static int cmp_insert(const void *key, const void *node)
98 {
99  int ret = ((const DTS2PTSNode *)key)->poc - ((const DTS2PTSNode *)node)->poc;
100  if (!ret)
101  ret = ((const DTS2PTSNode *)key)->gop - ((const DTS2PTSNode *)node)->gop;
102  return ret;
103 }
104 
105 static int cmp_find(const void *key, const void *node)
106 {
107  const DTS2PTSFrame * key1 = key;
108  const DTS2PTSNode *node1 = node;
109  int ret = FFDIFFSIGN(key1->poc, node1->poc);
110  if (!ret)
111  ret = key1->gop - node1->gop;
112  return ret;
113 }
114 
115 static int dec_poc(void *opaque, void *elem)
116 {
117  DTS2PTSNode *node = elem;
118  int dec = *(int *)opaque;
119  node->poc -= dec;
120  return 0;
121 }
122 
123 static int free_node(void *opaque, void *elem)
124 {
125  DTS2PTSNode *node = elem;
126  av_refstruct_unref(&node);
127  return 0;
128 }
129 
130 // Shared functions
132  int poc, int poc_diff, int gop)
133 {
135  for (int i = 0; i < poc_diff; i++) {
136  struct AVTreeNode *node = av_tree_node_alloc();
137  DTS2PTSNode *poc_node, *ret;
138  if (!node)
139  return AVERROR(ENOMEM);
140  poc_node = av_refstruct_pool_get(s->node_pool);
141  if (!poc_node) {
142  av_free(node);
143  return AVERROR(ENOMEM);
144  }
145  if (i && ts != AV_NOPTS_VALUE)
146  ts += duration / poc_diff;
147  *poc_node = (DTS2PTSNode) { ts, duration, poc++, gop };
148  ret = av_tree_insert(&s->root, poc_node, cmp_insert, &node);
149  if (ret && ret != poc_node) {
150  *ret = *poc_node;
151  av_refstruct_unref(&poc_node);
152  av_free(node);
153  }
154  }
155  return 0;
156 }
157 
158 // H.264
160  H264_NAL_SPS,
161  H264_NAL_PPS,
164 };
165 
167 {
169  DTS2PTSH264Context *h264 = &s->u.h264;
170 
171  s->cbc->decompose_unit_types = h264_decompose_unit_types;
172  s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(h264_decompose_unit_types);
173 
174  s->nb_frame = -(ctx->par_in->video_delay << 1);
175  h264->last_poc = h264->highest_poc = INT_MIN;
176 
177  return 0;
178 }
179 
181 {
182  if (header->nal_unit_header.nal_ref_idc == 0 ||
183  !header->adaptive_ref_pic_marking_mode_flag)
184  return 0;
185 
186  for (int i = 0; i < H264_MAX_MMCO_COUNT; i++) {
187  if (header->mmco[i].memory_management_control_operation == 0)
188  return 0;
189  else if (header->mmco[i].memory_management_control_operation == 5)
190  return 1;
191  }
192 
193  return 0;
194 }
195 
196 static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
197 {
199  DTS2PTSH264Context *h264 = &s->u.h264;
201  int poc_diff, ret;
202 
203  poc_diff = (h264->picture_structure == 3) + 1;
204  if (h264->sps.frame_mbs_only_flag && h264->poc_diff)
205  poc_diff = FFMIN(poc_diff, h264->poc_diff);
206  if (poc < 0) {
207  av_tree_enumerate(s->root, &poc_diff, NULL, dec_poc);
208  s->nb_frame -= poc_diff;
209  }
210  // Check if there was a POC reset (Like an IDR slice)
211  if (s->nb_frame > h264->highest_poc) {
212  s->nb_frame = 0;
213  s->gop = (s->gop + 1) % s->fifo_size;
214  h264->highest_poc = h264->last_poc;
215  }
216 
217  ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, poc_diff, s->gop);
218  if (ret < 0)
219  return ret;
220  av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, dts %"PRId64"\n",
221  poc, s->gop, pkt->dts);
222  s->nb_frame += poc_diff;
223 
224  // Add frame to output FIFO only once
225  if (*queued)
226  return 0;
227 
228  frame = (DTS2PTSFrame) { pkt, poc, poc_diff, s->gop };
229  ret = av_fifo_write(s->fifo, &frame, 1);
230  av_assert2(ret >= 0);
231  *queued = 1;
232 
233  return 0;
234 }
235 
237 {
239  DTS2PTSH264Context *h264 = &s->u.h264;
240  CodedBitstreamFragment *au = &s->au;
241  AVPacket *in;
242  int output_picture_number = INT_MIN;
243  int field_poc[2];
244  int queued = 0, ret;
245 
246  ret = ff_bsf_get_packet(ctx, &in);
247  if (ret < 0)
248  return ret;
249 
250  ret = ff_cbs_read_packet(s->cbc, au, in);
251  if (ret < 0) {
252  av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
253  goto fail;
254  }
255 
256  for (int i = 0; i < au->nb_units; i++) {
257  CodedBitstreamUnit *unit = &au->units[i];
258 
259  switch (unit->type) {
260  case H264_NAL_IDR_SLICE:
261  h264->poc.prev_frame_num = 0;
262  h264->poc.prev_frame_num_offset = 0;
263  h264->poc.prev_poc_msb =
264  h264->poc.prev_poc_lsb = 0;
265  // fall-through
266  case H264_NAL_SLICE: {
267  const H264RawSlice *slice = unit->content;
268  const H264RawSliceHeader *header = &slice->header;
269  const CodedBitstreamH264Context *cbs_h264 = s->cbc->priv_data;
270  const H264RawSPS *sps = cbs_h264->active_sps;
271  int got_reset;
272 
273  if (!sps) {
274  av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
276  goto fail;
277  }
278  // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
279  h264->sps.frame_mbs_only_flag = sps->frame_mbs_only_flag;
280  h264->sps.log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
281  h264->sps.poc_type = sps->pic_order_cnt_type;
282  h264->sps.log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
283  h264->sps.offset_for_non_ref_pic = sps->offset_for_non_ref_pic;
284  h264->sps.offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field;
285  h264->sps.poc_cycle_length = sps->num_ref_frames_in_pic_order_cnt_cycle;
286  for (int j = 0; j < h264->sps.poc_cycle_length; j++)
287  h264->sps.offset_for_ref_frame[j] = sps->offset_for_ref_frame[j];
288 
289  h264->picture_structure = sps->frame_mbs_only_flag ? 3 :
290  (header->field_pic_flag ?
291  header->field_pic_flag + header->bottom_field_flag : 3);
292 
293  h264->poc.frame_num = header->frame_num;
294  h264->poc.poc_lsb = header->pic_order_cnt_lsb;
295  h264->poc.delta_poc_bottom = header->delta_pic_order_cnt_bottom;
296  h264->poc.delta_poc[0] = header->delta_pic_order_cnt[0];
297  h264->poc.delta_poc[1] = header->delta_pic_order_cnt[1];
298 
299  field_poc[0] = field_poc[1] = INT_MAX;
300  ret = ff_h264_init_poc(field_poc, &output_picture_number, &h264->sps,
301  &h264->poc, h264->picture_structure,
302  header->nal_unit_header.nal_ref_idc);
303  if (ret < 0) {
304  av_log(ctx, AV_LOG_ERROR, "ff_h264_init_poc() failure\n");
305  goto fail;
306  }
307 
308  got_reset = get_mmco_reset(header);
309  h264->poc.prev_frame_num = got_reset ? 0 : h264->poc.frame_num;
310  h264->poc.prev_frame_num_offset = got_reset ? 0 : h264->poc.frame_num_offset;
311  if (header->nal_unit_header.nal_ref_idc != 0) {
312  h264->poc.prev_poc_msb = got_reset ? 0 : h264->poc.poc_msb;
313  if (got_reset)
314  h264->poc.prev_poc_lsb = h264->picture_structure == 2 ? 0 : field_poc[0];
315  else
316  h264->poc.prev_poc_lsb = h264->poc.poc_lsb;
317  }
318 
319  if (output_picture_number != h264->last_poc) {
320  if (h264->last_poc != INT_MIN) {
321  int64_t diff = FFABS(h264->last_poc - (int64_t)output_picture_number);
322 
323  if ((output_picture_number < 0) && !h264->last_poc)
324  h264->poc_diff = 0;
325  else if (FFABS((int64_t)output_picture_number) < h264->poc_diff) {
326  diff = FFABS(output_picture_number);
327  h264->poc_diff = 0;
328  }
329  if ((!h264->poc_diff || (h264->poc_diff > diff)) && diff <= INT_MAX) {
330  h264->poc_diff = diff;
331  if (h264->poc_diff == 1 && h264->sps.frame_mbs_only_flag) {
332  av_tree_enumerate(s->root, &h264->poc_diff, NULL, dec_poc);
333  s->nb_frame -= 2;
334  }
335  }
336  }
337  h264->last_poc = output_picture_number;
338  h264->highest_poc = FFMAX(h264->highest_poc, output_picture_number);
339 
340  ret = h264_queue_frame(ctx, in, output_picture_number, &queued);
341  if (ret < 0)
342  goto fail;
343  }
344  break;
345  }
346  default:
347  break;
348  }
349  }
350 
351  if (output_picture_number == INT_MIN) {
352  av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
354  goto fail;
355  }
356 
357  ret = 0;
358 fail:
359  ff_cbs_fragment_reset(au);
360  if (!queued)
361  av_packet_free(&in);
362 
363  return ret;
364 }
365 
367 {
369  DTS2PTSH264Context *h264 = &s->u.h264;
370 
371  memset(&h264->sps, 0, sizeof(h264->sps));
372  memset(&h264->poc, 0, sizeof(h264->poc));
373  s->nb_frame = -(ctx->par_in->video_delay << 1);
374  h264->last_poc = h264->highest_poc = INT_MIN;
375 }
376 
378 {
380  DTS2PTSHEVCContext *hevc = &s->u.hevc;
381 
382  hevc->gop = -1;
383  hevc->poc_tid0 = 0;
384  hevc->highest_poc = INT_MIN;
385  s->nb_frame = -ctx->par_in->video_delay;
386 
387  return 0;
388 }
389 
391 {
392  hevc_init(ctx);
393 }
394 
395 static int hevc_init_nb_frame(AVBSFContext *ctx, int poc)
396 {
398  const CodedBitstreamH265Context *cbs_hevc = s->cbc->priv_data;
399  const H265RawVPS *vps = cbs_hevc->active_vps;
400 
401  if (!vps)
402  return AVERROR_INVALIDDATA;
403 
404  int latency = vps->vps_max_num_reorder_pics[0];
405  if (vps->vps_max_latency_increase_plus1[0])
406  latency += vps->vps_max_latency_increase_plus1[0] - 1;
407 
408  s->nb_frame = poc - latency;
409  av_log(ctx, AV_LOG_DEBUG, "Latency %d, poc %d, nb_frame %d\n",
410  latency, poc, s->nb_frame);
411 
412  return 0;
413 }
414 
415 typedef struct DTS2PTSCollect {
416  int gop;
418  int count;
419  int max;
421 
422 static int collect_same_gop(void *opaque, void *elem)
423 {
424  DTS2PTSCollect *c = opaque;
425  DTS2PTSNode *node = elem;
426  if (node->gop == c->gop) {
427  if (c->count < c->max)
428  c->out[c->count] = node;
429  c->count++;
430  }
431  return 0;
432 }
433 
434 static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued)
435 {
437  DTS2PTSHEVCContext *hevc = &s->u.hevc;
438  int ret;
439 
440  if (hevc->gop == -1) {
441  ret = hevc_init_nb_frame(ctx, poc);
442  if (ret < 0)
443  return ret;
444  hevc->gop = s->gop;
445  }
446 
447  hevc->highest_poc = FFMAX(hevc->highest_poc, poc);
448  if (s->nb_frame > hevc->highest_poc) {
449  s->nb_frame = 0;
450  s->gop = (s->gop + 1) % s->fifo_size;
451  hevc->highest_poc = poc;
452  }
453 
454  if (poc < s->nb_frame && hevc->gop == s->gop) {
455  int dec = s->nb_frame - poc;
456  DTS2PTSNode *nodes[HEVC_MAX_DPB_SIZE * 2];
457  DTS2PTSCollect c = { s->gop, nodes, 0, FF_ARRAY_ELEMS(nodes) };
458 
459  s->nb_frame -= dec;
460 
462  av_assert0(c.count <= c.max);
463  for (int i = 0; i < c.count; i++) {
464  struct AVTreeNode *tnode = NULL;
465  DTS2PTSNode *r;
466  av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode);
467  nodes[i]->poc -= dec;
468  r = av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode);
469  if (r && r != nodes[i]) {
470  *r = *nodes[i];
471  av_refstruct_unref(&nodes[i]);
472  av_free(tnode);
473  }
474  }
475  }
476 
477  ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, 1, s->gop);
478  if (ret < 0)
479  return ret;
480 
481  av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, nb_frame %d, dts %"PRId64"\n",
482  poc, s->gop, s->nb_frame, pkt->dts);
483  s->nb_frame++;
484 
485  DTS2PTSFrame frame = {
486  .pkt = pkt,
487  .poc = poc,
488  .poc_diff = 1,
489  .gop = s->gop,
490  };
491  ret = av_fifo_write(s->fifo, &frame, 1);
492  if (ret < 0)
493  return ret;
494 
495  *queued = true;
496 
497  return 0;
498 }
499 
501 {
503  DTS2PTSHEVCContext *hevc = &s->u.hevc;
504  CodedBitstreamFragment *au = &s->au;
505  AVPacket *in;
506  bool queued = 0;
507  int ret = ff_bsf_get_packet(ctx, &in);
508  if (ret < 0)
509  return ret;
510 
511  ret = ff_cbs_read_packet(s->cbc, au, in);
512  if (ret < 0) {
513  av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
514  goto fail;
515  }
516 
517  for (int i = 0; i < au->nb_units; i++) {
518  CodedBitstreamUnit *unit = &au->units[i];
520 
521  bool is_slice = type <= HEVC_NAL_RASL_R || (type >= HEVC_NAL_BLA_W_LP &&
523  if (!is_slice)
524  continue;
525 
526  const H265RawSliceHeader *slice = unit->content;
528  continue;
529 
530  const CodedBitstreamH265Context *cbs_hevc = s->cbc->priv_data;
531  const H265RawSPS *sps = cbs_hevc->active_sps;
532  if (!sps) {
533  av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
535  goto fail;
536  }
537 
538  int poc;
540  poc = 0;
541  hevc->gop = (hevc->gop + 1) % s->fifo_size;
542  } else {
543  unsigned log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
544  int poc_lsb = slice->slice_pic_order_cnt_lsb;
545 
546  poc = ff_hevc_compute_poc2(log2_max_poc_lsb, hevc->poc_tid0, poc_lsb, type);
547  }
548 
549  if (slice->nal_unit_header.nuh_temporal_id_plus1 == 1 &&
553  type != HEVC_NAL_RASL_R) {
554  hevc->poc_tid0 = poc;
555  }
556 
557  ret = hevc_queue_frame(ctx, in, poc, &queued);
558  if (ret < 0)
559  goto fail;
560  break;
561  }
562 
563  if (!queued) {
564  av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
566  }
567 
568 fail:
569  ff_cbs_fragment_reset(au);
570  if (!queued)
571  av_packet_free(&in);
572  return ret;
573 }
574 
575 // Core functions
576 static const struct {
577  enum AVCodecID id;
580  void (*flush)(AVBSFContext *ctx);
581  size_t fifo_size;
582 } func_tab[] = {
585 };
586 
588 {
590  CodedBitstreamFragment *au = &s->au;
591  int i, ret;
592 
593  for (i = 0; i < FF_ARRAY_ELEMS(func_tab); i++) {
594  if (func_tab[i].id == ctx->par_in->codec_id) {
595  s->init = func_tab[i].init;
596  s->filter = func_tab[i].filter;
597  s->flush = func_tab[i].flush;
598  s->fifo_size = func_tab[i].fifo_size;
599  break;
600  }
601  }
602  if (i == FF_ARRAY_ELEMS(func_tab))
603  return AVERROR_BUG;
604  av_assert0(s->filter && s->fifo_size);
605 
606  s->fifo = av_fifo_alloc2(s->fifo_size, sizeof(DTS2PTSFrame), 0);
607  if (!s->fifo)
608  return AVERROR(ENOMEM);
609 
610  s->node_pool = av_refstruct_pool_alloc(sizeof(DTS2PTSNode),
612 
613  if (!s->node_pool)
614  return AVERROR(ENOMEM);
615 
616  ret = ff_cbs_init(&s->cbc, ctx->par_in->codec_id, ctx);
617  if (ret < 0)
618  return ret;
619 
620  if (s->init) {
621  ret = s->init(ctx);
622  if (ret < 0)
623  return ret;
624  }
625 
626  if (!ctx->par_in->extradata_size)
627  return 0;
628 
629  ret = ff_cbs_read_extradata(s->cbc, au, ctx->par_in);
630  if (ret < 0)
631  av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
632 
633  ff_cbs_fragment_reset(au);
634 
635  return 0;
636 }
637 
639 {
641  DTS2PTSNode *poc_node = NULL, *next[2] = { NULL, NULL };
643  int ret;
644 
645  // Fill up the FIFO and POC tree
646  while (!s->eof && av_fifo_can_write(s->fifo)) {
647  ret = s->filter(ctx);
648  if (ret < 0) {
649  if (ret != AVERROR_EOF)
650  return ret;
651  s->eof = 1;
652  }
653  }
654 
655  if (!av_fifo_can_read(s->fifo))
656  return AVERROR_EOF;
657 
658  // Fetch a packet from the FIFO
659  ret = av_fifo_read(s->fifo, &frame, 1);
660  av_assert2(ret >= 0);
662  av_packet_free(&frame.pkt);
663 
664  // Search the timestamp for the requested POC and set PTS
665  poc_node = av_tree_find(s->root, &frame, cmp_find, (void **)next);
666  if (!poc_node) {
667  poc_node = next[1];
668  if (!poc_node || poc_node->poc != frame.poc)
669  poc_node = next[0];
670  }
671  if (poc_node && poc_node->poc == frame.poc) {
672  out->pts = poc_node->dts;
673  if (!s->eof) {
674  // Remove the found entry from the tree
675  DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc + 1, frame.poc_diff, frame.gop };
676  for (; dup.poc_diff > 0; dup.poc++, dup.poc_diff--) {
677  struct AVTreeNode *node = NULL;
678  if (!poc_node || poc_node->dts != out->pts)
679  continue;
680  av_tree_insert(&s->root, poc_node, cmp_insert, &node);
681  av_refstruct_unref(&poc_node);
682  av_free(node);
683  poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
684  }
685  }
686  } else if (s->eof && frame.poc > INT_MIN) {
687  DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc - 1, frame.poc_diff, frame.gop };
688  poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
689  if (poc_node && poc_node->poc == dup.poc) {
690  out->pts = poc_node->dts;
691  if (out->pts != AV_NOPTS_VALUE)
692  out->pts += poc_node->duration;
693  ret = alloc_and_insert_node(ctx, out->pts, out->duration,
694  frame.poc, frame.poc_diff, frame.gop);
695  if (ret < 0) {
697  return ret;
698  }
699  av_log(ctx, AV_LOG_DEBUG, "Queueing frame for POC %d, GOP %d, dts %"PRId64", "
700  "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
701  frame.poc, frame.gop, out->pts,
702  poc_node->poc, poc_node->gop, poc_node->dts, poc_node->duration);
703  } else
704  av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
705  } else
706  av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
707  av_log(ctx, AV_LOG_DEBUG, "Returning frame for POC %d, GOP %d, dts %"PRId64", pts %"PRId64"\n",
708  frame.poc, frame.gop, out->dts, out->pts);
709 
710  return 0;
711 }
712 
714 {
717 
718  if (s->flush)
719  s->flush(ctx);
720  s->eof = 0;
721  s->gop = 0;
722 
723  while (s->fifo && av_fifo_read(s->fifo, &frame, 1) >= 0)
724  av_packet_free(&frame.pkt);
725 
727  av_tree_destroy(s->root);
728  s->root = NULL;
729 
730  ff_cbs_fragment_reset(&s->au);
731  if (s->cbc)
732  ff_cbs_flush(s->cbc);
733 }
734 
736 {
738 
740 
741  av_fifo_freep2(&s->fifo);
742  av_refstruct_pool_uninit(&s->node_pool);
743  ff_cbs_fragment_free(&s->au);
744  ff_cbs_close(&s->cbc);
745 }
746 
747 static const enum AVCodecID dts2pts_codec_ids[] = {
751 };
752 
754  .p.name = "dts2pts",
755  .p.codec_ids = dts2pts_codec_ids,
756  .priv_data_size = sizeof(DTS2PTSContext),
757  .init = dts2pts_init,
758  .flush = dts2pts_flush,
759  .close = dts2pts_close,
761 };
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
SPS::offset_for_ref_frame
int32_t offset_for_ref_frame[256]
Definition: h264_ps.h:79
hevc_init
static int hevc_init(AVBSFContext *ctx)
Definition: dts2pts.c:377
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
DTS2PTSContext::u
union DTS2PTSContext::@72 u
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
H265RawSliceHeader::first_slice_segment_in_pic_flag
uint8_t first_slice_segment_in_pic_flag
Definition: cbs_h265.h:496
DTS2PTSContext::node_pool
AVRefStructPool * node_pool
Definition: dts2pts.c:75
av_fifo_can_write
size_t av_fifo_can_write(const AVFifo *f)
Definition: fifo.c:94
cmp_find
static int cmp_find(const void *key, const void *node)
Definition: dts2pts.c:105
H264POCContext::frame_num_offset
int frame_num_offset
for POC type 2
Definition: h264_parse.h:90
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
bsf_internal.h
dts2pts_flush
static void dts2pts_flush(AVBSFContext *ctx)
Definition: dts2pts.c:713
DTS2PTSContext::fifo_size
size_t fifo_size
Definition: dts2pts.c:81
func_tab
static const struct @71 func_tab[]
out
static FILE * out
Definition: movenc.c:55
H264POCContext::delta_poc_bottom
int delta_poc_bottom
Definition: h264_parse.h:85
DTS2PTSFrame::gop
int gop
Definition: dts2pts.c:54
DTS2PTSHEVCContext::highest_poc
int highest_poc
Definition: dts2pts.c:69
SPS::offset_for_non_ref_pic
int offset_for_non_ref_pic
Definition: h264_ps.h:54
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
av_tree_insert
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
DTS2PTSFrame::poc
int poc
Definition: dts2pts.c:52
cbs_h264.h
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:114
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
int64_t
long long int64_t
Definition: coverity.c:34
DTS2PTSH264Context
Definition: dts2pts.c:57
h264_parse.h
DTS2PTSCollect
Definition: dts2pts.c:415
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:226
H265RawNALUnitHeader::nuh_temporal_id_plus1
uint8_t nuh_temporal_id_plus1
Definition: cbs_h265.h:33
HEVC_NAL_TSA_N
@ HEVC_NAL_TSA_N
Definition: hevc.h:31
DTS2PTSContext
Definition: dts2pts.c:72
HEVC_NAL_IDR_N_LP
@ HEVC_NAL_IDR_N_LP
Definition: hevc.h:49
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:81
dts2pts_filter
static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
Definition: dts2pts.c:638
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:606
alloc_and_insert_node
static int alloc_and_insert_node(AVBSFContext *ctx, int64_t ts, int64_t duration, int poc, int poc_diff, int gop)
Definition: dts2pts.c:131
cbs_h265.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_tree_node_alloc
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
Definition: tree.c:34
HEVC_NAL_IDR_W_RADL
@ HEVC_NAL_IDR_W_RADL
Definition: hevc.h:48
h264_init
static int h264_init(AVBSFContext *ctx)
Definition: dts2pts.c:166
ff_bsf_get_packet
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
Definition: bsf.c:235
DTS2PTSFrame::pkt
AVPacket * pkt
Definition: dts2pts.c:51
SPS::frame_mbs_only_flag
int frame_mbs_only_flag
Definition: h264_ps.h:62
av_tree_enumerate
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
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
H264POCContext::prev_poc_lsb
int prev_poc_lsb
poc_lsb of the last reference pic for POC type 0
Definition: h264_parse.h:89
DTS2PTSH264Context::poc
H264POCContext poc
Definition: dts2pts.c:58
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:77
DTS2PTSH264Context::poc_diff
int poc_diff
Definition: dts2pts.c:60
H264POCContext::delta_poc
int delta_poc[2]
Definition: h264_parse.h:86
H265RawSPS
Definition: cbs_h265.h:245
SPS::poc_type
int poc_type
pic_order_cnt_type
Definition: h264_ps.h:51
H265RawVPS
Definition: cbs_h265.h:184
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
DTS2PTSContext::fifo
AVFifo * fifo
Definition: dts2pts.c:74
DTS2PTSH264Context::sps
SPS sps
Definition: dts2pts.c:59
fifo.h
H264POCContext::prev_frame_num
int prev_frame_num
frame_num of the last pic for POC type 1/2
Definition: h264_parse.h:92
bsf.h
fail
#define fail()
Definition: checkasm.h:219
av_fifo_write
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition: fifo.c:188
CodedBitstreamH264Context::active_sps
const H264RawSPS * active_sps
Definition: cbs_h264.h:436
H264_MAX_MMCO_COUNT
@ H264_MAX_MMCO_COUNT
Definition: h264.h:92
DTS2PTSHEVCContext
Definition: dts2pts.c:66
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
H264_MAX_DPB_FRAMES
@ H264_MAX_DPB_FRAMES
Definition: h264.h:76
refstruct.h
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:175
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
H265RawSliceHeader::slice_pic_order_cnt_lsb
uint16_t slice_pic_order_cnt_lsb
Definition: cbs_h265.h:509
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
DTS2PTSContext::cbc
CodedBitstreamContext * cbc
Definition: dts2pts.c:83
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:129
ff_dts2pts_bsf
const FFBitStreamFilter ff_dts2pts_bsf
Definition: dts2pts.c:753
HEVC_MAX_DPB_SIZE
@ HEVC_MAX_DPB_SIZE
Definition: hevc.h:120
s
#define s(width, name)
Definition: cbs_vp9.c:198
H264POCContext::prev_frame_num_offset
int prev_frame_num_offset
for POC type 2
Definition: h264_parse.h:91
DTS2PTSCollect::count
int count
Definition: dts2pts.c:418
DTS2PTSContext::filter
int(* filter)(AVBSFContext *ctx)
Definition: dts2pts.c:79
DTS2PTSNode::poc
int poc
Definition: dts2pts.c:46
DTS2PTSNode::dts
int64_t dts
Definition: dts2pts.c:44
filter
int(* filter)(AVBSFContext *ctx)
Definition: dts2pts.c:579
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
CodedBitstreamUnitType
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition: cbs.h:54
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
DTS2PTSContext::nb_frame
int nb_frame
Definition: dts2pts.c:91
AVRefStructPool
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition: refstruct.c:183
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
key
const char * key
Definition: hwcontext_opencl.c:189
h264_flush
static void h264_flush(AVBSFContext *ctx)
Definition: dts2pts.c:366
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
NULL
#define NULL
Definition: coverity.c:32
DTS2PTSCollect::max
int max
Definition: dts2pts.c:419
FFBitStreamFilter
Definition: bsf_internal.h:27
SPS
Sequence parameter set.
Definition: h264_ps.h:44
DTS2PTSContext::flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:80
H264_NAL_IDR_SLICE
@ H264_NAL_IDR_SLICE
Definition: h264.h:39
HEVC_NAL_STSA_N
@ HEVC_NAL_STSA_N
Definition: hevc.h:33
DTS2PTSNode
Definition: dts2pts.c:43
av_fifo_can_read
size_t av_fifo_can_read(const AVFifo *f)
Definition: fifo.c:87
AVTreeNode
Definition: tree.c:26
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:580
av_refstruct_pool_get
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
DTS2PTSHEVCContext::gop
int gop
Definition: dts2pts.c:67
vps
static int FUNC() vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
Definition: cbs_h265_syntax_template.c:423
get_mmco_reset
static int get_mmco_reset(const H264RawSliceHeader *header)
Definition: dts2pts.c:180
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: packet.c:489
av_tree_destroy
void av_tree_destroy(AVTreeNode *t)
Definition: tree.c:146
h264_ps.h
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
CodedBitstreamH264Context
Definition: cbs_h264.h:424
dts2pts_init
static int dts2pts_init(AVBSFContext *ctx)
Definition: dts2pts.c:587
HEVC_NAL_RASL_R
@ HEVC_NAL_RASL_R
Definition: hevc.h:38
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
DTS2PTSFrame::poc_diff
int poc_diff
Definition: dts2pts.c:53
DTS2PTSFrame
Definition: dts2pts.c:50
dts2pts_codec_ids
static enum AVCodecID dts2pts_codec_ids[]
Definition: dts2pts.c:747
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:578
DTS2PTSContext::h264
DTS2PTSH264Context h264
Definition: dts2pts.c:87
AVFifo
Definition: fifo.c:35
hevc_filter
static int hevc_filter(AVBSFContext *ctx)
Definition: dts2pts.c:500
DTS2PTSH264Context::highest_poc
int highest_poc
Definition: dts2pts.c:62
HEVC_NAL_RASL_N
@ HEVC_NAL_RASL_N
Definition: hevc.h:37
free_node
static int free_node(void *opaque, void *elem)
Definition: dts2pts.c:123
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
DTS2PTSH264Context::last_poc
int last_poc
Definition: dts2pts.c:61
SPS::poc_cycle_length
int poc_cycle_length
num_ref_frames_in_pic_order_cnt_cycle
Definition: h264_ps.h:56
DTS2PTSCollect::out
DTS2PTSNode ** out
Definition: dts2pts.c:417
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
DTS2PTSNode::duration
int64_t duration
Definition: dts2pts.c:45
DTS2PTSContext::init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:78
DTS2PTSContext::gop
int gop
Definition: dts2pts.c:92
ps.h
DTS2PTSContext::hevc
DTS2PTSHEVCContext hevc
Definition: dts2pts.c:88
tree.h
header
static const uint8_t header[24]
Definition: sdr2.c:68
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:587
SPS::offset_for_top_to_bottom_field
int offset_for_top_to_bottom_field
Definition: h264_ps.h:55
DTS2PTSH264Context::picture_structure
int picture_structure
Definition: dts2pts.c:63
collect_same_gop
static int collect_same_gop(void *opaque, void *elem)
Definition: dts2pts.c:422
H264POCContext::frame_num
int frame_num
Definition: h264_parse.h:87
av_refstruct_unref
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
H264RawSliceHeader
Definition: cbs_h264.h:330
H265RawSliceHeader
Definition: cbs_h265.h:493
H264RawSlice::header
H264RawSliceHeader header
Definition: cbs_h264.h:409
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
SPS::log2_max_poc_lsb
int log2_max_poc_lsb
log2_max_pic_order_cnt_lsb_minus4
Definition: h264_ps.h:52
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
h264_filter
static int h264_filter(AVBSFContext *ctx)
Definition: dts2pts.c:236
dec_poc
static int dec_poc(void *opaque, void *elem)
Definition: dts2pts.c:115
H264POCContext
Definition: h264_parse.h:82
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
H265RawSliceHeader::nal_unit_header
H265RawNALUnitHeader nal_unit_header
Definition: cbs_h265.h:494
DTS2PTSContext::au
CodedBitstreamFragment au
Definition: dts2pts.c:84
ff_hevc_compute_poc2
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:2466
CodedBitstreamH265Context::active_sps
const H265RawSPS * active_sps
Definition: cbs_h265.h:764
cmp_insert
static int cmp_insert(const void *key, const void *node)
Definition: dts2pts.c:97
hevc_flush
static void hevc_flush(AVBSFContext *ctx)
Definition: dts2pts.c:390
ret
ret
Definition: filter_design.txt:187
ff_h264_init_poc
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
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
H264_NAL_SLICE
@ H264_NAL_SLICE
Definition: h264.h:35
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
av_refstruct_pool_alloc
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
av_fifo_alloc2
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
id
enum AVCodecID id
Definition: dts2pts.c:577
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
DTS2PTSCollect::gop
int gop
Definition: dts2pts.c:416
HEVC_NAL_CRA_NUT
@ HEVC_NAL_CRA_NUT
Definition: hevc.h:50
AV_REFSTRUCT_POOL_FLAG_NO_ZEROING
#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
dts2pts_close
static void dts2pts_close(AVBSFContext *ctx)
Definition: dts2pts.c:735
CodedBitstreamH265Context::active_vps
const H265RawVPS * active_vps
Definition: cbs_h265.h:763
h264_decompose_unit_types
static const CodedBitstreamUnitType h264_decompose_unit_types[]
Definition: dts2pts.c:159
av_tree_find
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(const void *key, const void *b), void *next[2])
Definition: tree.c:39
hevc_queue_frame
static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued)
Definition: dts2pts.c:434
mem.h
DTS2PTSContext::eof
int eof
Definition: dts2pts.c:93
H264POCContext::poc_lsb
int poc_lsb
Definition: h264_parse.h:83
DTS2PTSContext::root
struct AVTreeNode * root
Definition: dts2pts.c:73
HEVC_NAL_RADL_R
@ HEVC_NAL_RADL_R
Definition: hevc.h:36
av_refstruct_pool_uninit
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
DTS2PTSNode::gop
int gop
Definition: dts2pts.c:47
AVPacket
This structure stores compressed data.
Definition: packet.h:565
hevc_init_nb_frame
static int hevc_init_nb_frame(AVBSFContext *ctx, int poc)
Definition: dts2pts.c:395
h264_queue_frame
static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
Definition: dts2pts.c:196
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fifo_freep2
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition: fifo.c:286
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
H264POCContext::poc_msb
int poc_msb
Definition: h264_parse.h:84
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
H264POCContext::prev_poc_msb
int prev_poc_msb
poc_msb of the last reference pic for POC type 0
Definition: h264_parse.h:88
HEVC_NAL_RADL_N
@ HEVC_NAL_RADL_N
Definition: hevc.h:35
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1291
fifo_size
size_t fifo_size
Definition: dts2pts.c:581
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:160
duration
static int64_t duration
Definition: ffplay.c:329
SPS::log2_max_frame_num
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
Definition: h264_ps.h:50
CodedBitstreamH265Context
Definition: cbs_h265.h:750
DTS2PTSHEVCContext::poc_tid0
int poc_tid0
Definition: dts2pts.c:68
HEVC_NAL_TRAIL_N
@ HEVC_NAL_TRAIL_N
Definition: hevc.h:29
H264RawSlice
Definition: cbs_h264.h:408
HEVC_NAL_BLA_W_LP
@ HEVC_NAL_BLA_W_LP
Definition: hevc.h:45
H264RawSPS
Definition: cbs_h264.h:102