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 "libavutil/avassert.h"
27 #include "libavutil/fifo.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/tree.h"
30 
31 #include "bsf.h"
32 #include "bsf_internal.h"
33 #include "cbs.h"
34 #include "cbs_h264.h"
35 #include "h264_parse.h"
36 #include "h264_ps.h"
37 #include "refstruct.h"
38 
39 typedef struct DTS2PTSNode {
42  int poc;
43  int gop;
44 } DTS2PTSNode;
45 
46 typedef struct DTS2PTSFrame {
48  int poc;
49  int poc_diff;
50  int gop;
51 } DTS2PTSFrame;
52 
53 typedef struct DTS2PTSH264Context {
56  int poc_diff;
57  int last_poc;
61 
62 typedef struct DTS2PTSContext {
63  struct AVTreeNode *root;
66 
67  // Codec specific function pointers and constants
68  int (*init)(AVBSFContext *ctx);
70  void (*flush)(AVBSFContext *ctx);
71  size_t fifo_size;
72 
75 
76  union {
78  } u;
79 
80  int nb_frame;
81  int gop;
82  int eof;
84 
85 // AVTreeNode callbacks
86 static int cmp_insert(const void *key, const void *node)
87 {
88  int ret = ((const DTS2PTSNode *)key)->poc - ((const DTS2PTSNode *)node)->poc;
89  if (!ret)
90  ret = ((const DTS2PTSNode *)key)->gop - ((const DTS2PTSNode *)node)->gop;
91  return ret;
92 }
93 
94 static int cmp_find(const void *key, const void *node)
95 {
96  const DTS2PTSFrame * key1 = key;
97  const DTS2PTSNode *node1 = node;
98  int ret = FFDIFFSIGN(key1->poc, node1->poc);
99  if (!ret)
100  ret = key1->gop - node1->gop;
101  return ret;
102 }
103 
104 static int dec_poc(void *opaque, void *elem)
105 {
106  DTS2PTSNode *node = elem;
107  int dec = *(int *)opaque;
108  node->poc -= dec;
109  return 0;
110 }
111 
112 static int free_node(void *opaque, void *elem)
113 {
114  DTS2PTSNode *node = elem;
115  ff_refstruct_unref(&node);
116  return 0;
117 }
118 
119 // Shared functions
121  int poc, int poc_diff, int gop)
122 {
124  for (int i = 0; i < poc_diff; i++) {
125  struct AVTreeNode *node = av_tree_node_alloc();
126  DTS2PTSNode *poc_node, *ret;
127  if (!node)
128  return AVERROR(ENOMEM);
129  poc_node = ff_refstruct_pool_get(s->node_pool);
130  if (!poc_node) {
131  av_free(node);
132  return AVERROR(ENOMEM);
133  }
134  if (i && ts != AV_NOPTS_VALUE)
135  ts += duration / poc_diff;
136  *poc_node = (DTS2PTSNode) { ts, duration, poc++, gop };
137  ret = av_tree_insert(&s->root, poc_node, cmp_insert, &node);
138  if (ret && ret != poc_node) {
139  *ret = *poc_node;
140  ff_refstruct_unref(&poc_node);
141  av_free(node);
142  }
143  }
144  return 0;
145 }
146 
147 // H.264
149  H264_NAL_SPS,
150  H264_NAL_PPS,
153 };
154 
156 {
158  DTS2PTSH264Context *h264 = &s->u.h264;
159 
160  s->cbc->decompose_unit_types = h264_decompose_unit_types;
161  s->cbc->nb_decompose_unit_types = FF_ARRAY_ELEMS(h264_decompose_unit_types);
162 
163  s->nb_frame = -(ctx->par_in->video_delay << 1);
164  h264->last_poc = h264->highest_poc = INT_MIN;
165 
166  return 0;
167 }
168 
170 {
171  if (header->nal_unit_header.nal_ref_idc == 0 ||
172  !header->adaptive_ref_pic_marking_mode_flag)
173  return 0;
174 
175  for (int i = 0; i < H264_MAX_MMCO_COUNT; i++) {
176  if (header->mmco[i].memory_management_control_operation == 0)
177  return 0;
178  else if (header->mmco[i].memory_management_control_operation == 5)
179  return 1;
180  }
181 
182  return 0;
183 }
184 
185 static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
186 {
188  DTS2PTSH264Context *h264 = &s->u.h264;
190  int poc_diff, ret;
191 
192  poc_diff = (h264->picture_structure == 3) + 1;
193  if (h264->sps.frame_mbs_only_flag && h264->poc_diff)
194  poc_diff = FFMIN(poc_diff, h264->poc_diff);
195  if (poc < 0) {
196  av_tree_enumerate(s->root, &poc_diff, NULL, dec_poc);
197  s->nb_frame -= poc_diff;
198  }
199  // Check if there was a POC reset (Like an IDR slice)
200  if (s->nb_frame > h264->highest_poc) {
201  s->nb_frame = 0;
202  s->gop = (s->gop + 1) % s->fifo_size;
203  h264->highest_poc = h264->last_poc;
204  }
205 
206  ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, poc_diff, s->gop);
207  if (ret < 0)
208  return ret;
209  av_log(ctx, AV_LOG_DEBUG, "Queueing frame with POC %d, GOP %d, dts %"PRId64"\n",
210  poc, s->gop, pkt->dts);
211  s->nb_frame += poc_diff;
212 
213  // Add frame to output FIFO only once
214  if (*queued)
215  return 0;
216 
217  frame = (DTS2PTSFrame) { pkt, poc, poc_diff, s->gop };
218  ret = av_fifo_write(s->fifo, &frame, 1);
219  av_assert2(ret >= 0);
220  *queued = 1;
221 
222  return 0;
223 }
224 
226 {
228  DTS2PTSH264Context *h264 = &s->u.h264;
229  CodedBitstreamFragment *au = &s->au;
230  AVPacket *in;
231  int output_picture_number = INT_MIN;
232  int field_poc[2];
233  int queued = 0, ret;
234 
235  ret = ff_bsf_get_packet(ctx, &in);
236  if (ret < 0)
237  return ret;
238 
239  ret = ff_cbs_read_packet(s->cbc, au, in);
240  if (ret < 0) {
241  av_log(ctx, AV_LOG_WARNING, "Failed to parse access unit.\n");
242  goto fail;
243  }
244 
245  for (int i = 0; i < au->nb_units; i++) {
246  CodedBitstreamUnit *unit = &au->units[i];
247 
248  switch (unit->type) {
249  case H264_NAL_IDR_SLICE:
250  h264->poc.prev_frame_num = 0;
251  h264->poc.prev_frame_num_offset = 0;
252  h264->poc.prev_poc_msb =
253  h264->poc.prev_poc_lsb = 0;
254  // fall-through
255  case H264_NAL_SLICE: {
256  const H264RawSlice *slice = unit->content;
257  const H264RawSliceHeader *header = &slice->header;
258  const CodedBitstreamH264Context *cbs_h264 = s->cbc->priv_data;
259  const H264RawSPS *sps = cbs_h264->active_sps;
260  int got_reset;
261 
262  if (!sps) {
263  av_log(ctx, AV_LOG_ERROR, "No active SPS for a slice\n");
264  goto fail;
265  }
266  // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
267  h264->sps.frame_mbs_only_flag = sps->frame_mbs_only_flag;
268  h264->sps.log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
269  h264->sps.poc_type = sps->pic_order_cnt_type;
270  h264->sps.log2_max_poc_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
271  h264->sps.offset_for_non_ref_pic = sps->offset_for_non_ref_pic;
272  h264->sps.offset_for_top_to_bottom_field = sps->offset_for_top_to_bottom_field;
273  h264->sps.poc_cycle_length = sps->num_ref_frames_in_pic_order_cnt_cycle;
274  for (int j = 0; j < h264->sps.poc_cycle_length; j++)
275  h264->sps.offset_for_ref_frame[j] = sps->offset_for_ref_frame[j];
276 
277  h264->picture_structure = sps->frame_mbs_only_flag ? 3 :
278  (header->field_pic_flag ?
279  header->field_pic_flag + header->bottom_field_flag : 3);
280 
281  h264->poc.frame_num = header->frame_num;
282  h264->poc.poc_lsb = header->pic_order_cnt_lsb;
283  h264->poc.delta_poc_bottom = header->delta_pic_order_cnt_bottom;
284  h264->poc.delta_poc[0] = header->delta_pic_order_cnt[0];
285  h264->poc.delta_poc[1] = header->delta_pic_order_cnt[1];
286 
287  field_poc[0] = field_poc[1] = INT_MAX;
288  ret = ff_h264_init_poc(field_poc, &output_picture_number, &h264->sps,
289  &h264->poc, h264->picture_structure,
290  header->nal_unit_header.nal_ref_idc);
291  if (ret < 0) {
292  av_log(ctx, AV_LOG_ERROR, "ff_h264_init_poc() failure\n");
293  goto fail;
294  }
295 
296  got_reset = get_mmco_reset(header);
297  h264->poc.prev_frame_num = got_reset ? 0 : h264->poc.frame_num;
298  h264->poc.prev_frame_num_offset = got_reset ? 0 : h264->poc.frame_num_offset;
299  if (header->nal_unit_header.nal_ref_idc != 0) {
300  h264->poc.prev_poc_msb = got_reset ? 0 : h264->poc.poc_msb;
301  if (got_reset)
302  h264->poc.prev_poc_lsb = h264->picture_structure == 2 ? 0 : field_poc[0];
303  else
304  h264->poc.prev_poc_lsb = h264->poc.poc_lsb;
305  }
306 
307  if (output_picture_number != h264->last_poc) {
308  if (h264->last_poc != INT_MIN) {
309  int64_t diff = FFABS(h264->last_poc - (int64_t)output_picture_number);
310 
311  if ((output_picture_number < 0) && !h264->last_poc)
312  h264->poc_diff = 0;
313  else if (FFABS((int64_t)output_picture_number) < h264->poc_diff) {
314  diff = FFABS(output_picture_number);
315  h264->poc_diff = 0;
316  }
317  if ((!h264->poc_diff || (h264->poc_diff > diff)) && diff <= INT_MAX) {
318  h264->poc_diff = diff;
319  if (h264->poc_diff == 1 && h264->sps.frame_mbs_only_flag) {
320  av_tree_enumerate(s->root, &h264->poc_diff, NULL, dec_poc);
321  s->nb_frame -= 2;
322  }
323  }
324  }
325  h264->last_poc = output_picture_number;
326  h264->highest_poc = FFMAX(h264->highest_poc, output_picture_number);
327 
328  ret = h264_queue_frame(ctx, in, output_picture_number, &queued);
329  if (ret < 0)
330  goto fail;
331  }
332  break;
333  }
334  default:
335  break;
336  }
337  }
338 
339  if (output_picture_number == INT_MIN) {
340  av_log(ctx, AV_LOG_ERROR, "No slices in access unit\n");
342  goto fail;
343  }
344 
345  ret = 0;
346 fail:
348  if (!queued)
349  av_packet_free(&in);
350 
351  return ret;
352 }
353 
355 {
357  DTS2PTSH264Context *h264 = &s->u.h264;
358 
359  memset(&h264->sps, 0, sizeof(h264->sps));
360  memset(&h264->poc, 0, sizeof(h264->poc));
361  s->nb_frame = -(ctx->par_in->video_delay << 1);
362  h264->last_poc = h264->highest_poc = INT_MIN;
363 }
364 
365 // Core functions
366 static const struct {
367  enum AVCodecID id;
370  void (*flush)(AVBSFContext *ctx);
371  size_t fifo_size;
372 } func_tab[] = {
374 };
375 
377 {
379  CodedBitstreamFragment *au = &s->au;
380  int i, ret;
381 
382  for (i = 0; i < FF_ARRAY_ELEMS(func_tab); i++) {
383  if (func_tab[i].id == ctx->par_in->codec_id) {
384  s->init = func_tab[i].init;
385  s->filter = func_tab[i].filter;
386  s->flush = func_tab[i].flush;
387  s->fifo_size = func_tab[i].fifo_size;
388  break;
389  }
390  }
391  if (i == FF_ARRAY_ELEMS(func_tab))
392  return AVERROR_BUG;
393  av_assert0(s->filter && s->fifo_size);
394 
395  s->fifo = av_fifo_alloc2(s->fifo_size, sizeof(DTS2PTSFrame), 0);
396  if (!s->fifo)
397  return AVERROR(ENOMEM);
398 
399  s->node_pool = ff_refstruct_pool_alloc(sizeof(DTS2PTSNode), 0);
400 
401  if (!s->node_pool)
402  return AVERROR(ENOMEM);
403 
404  ret = ff_cbs_init(&s->cbc, ctx->par_in->codec_id, ctx);
405  if (ret < 0)
406  return ret;
407 
408  if (s->init) {
409  ret = s->init(ctx);
410  if (ret < 0)
411  return ret;
412  }
413 
414  if (!ctx->par_in->extradata_size)
415  return 0;
416 
417  ret = ff_cbs_read_extradata(s->cbc, au, ctx->par_in);
418  if (ret < 0)
419  av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n");
420 
422 
423  return 0;
424 }
425 
427 {
429  DTS2PTSNode *poc_node = NULL, *next[2] = { NULL, NULL };
431  int ret;
432 
433  // Fill up the FIFO and POC tree
434  while (!s->eof && av_fifo_can_write(s->fifo)) {
435  ret = s->filter(ctx);
436  if (ret < 0) {
437  if (ret != AVERROR_EOF)
438  return ret;
439  s->eof = 1;
440  }
441  }
442 
443  if (!av_fifo_can_read(s->fifo))
444  return AVERROR_EOF;
445 
446  // Fetch a packet from the FIFO
447  ret = av_fifo_read(s->fifo, &frame, 1);
448  av_assert2(ret >= 0);
450  av_packet_free(&frame.pkt);
451 
452  // Search the timestamp for the requested POC and set PTS
453  poc_node = av_tree_find(s->root, &frame, cmp_find, (void **)next);
454  if (!poc_node) {
455  poc_node = next[1];
456  if (!poc_node || poc_node->poc != frame.poc)
457  poc_node = next[0];
458  }
459  if (poc_node && poc_node->poc == frame.poc) {
460  out->pts = poc_node->dts;
461  if (!s->eof) {
462  // Remove the found entry from the tree
463  DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc + 1, frame.poc_diff, frame.gop };
464  for (; dup.poc_diff > 0; dup.poc++, dup.poc_diff--) {
465  struct AVTreeNode *node = NULL;
466  if (!poc_node || poc_node->dts != out->pts)
467  continue;
468  av_tree_insert(&s->root, poc_node, cmp_insert, &node);
469  ff_refstruct_unref(&poc_node);
470  av_free(node);
471  poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
472  }
473  }
474  } else if (s->eof && frame.poc > INT_MIN) {
475  DTS2PTSFrame dup = (DTS2PTSFrame) { NULL, frame.poc - 1, frame.poc_diff, frame.gop };
476  poc_node = av_tree_find(s->root, &dup, cmp_find, NULL);
477  if (poc_node && poc_node->poc == dup.poc) {
478  out->pts = poc_node->dts;
479  if (out->pts != AV_NOPTS_VALUE)
480  out->pts += poc_node->duration;
481  ret = alloc_and_insert_node(ctx, out->pts, out->duration,
482  frame.poc, frame.poc_diff, frame.gop);
483  if (ret < 0) {
485  return ret;
486  }
487  if (!ret)
488  av_log(ctx, AV_LOG_DEBUG, "Queueing frame for POC %d, GOP %d, dts %"PRId64", "
489  "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
490  frame.poc, frame.gop, out->pts,
491  poc_node->poc, poc_node->gop, poc_node->dts, poc_node->duration);
492  } else
493  av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
494  } else
495  av_log(ctx, AV_LOG_WARNING, "No timestamp for POC %d in tree\n", frame.poc);
496  av_log(ctx, AV_LOG_DEBUG, "Returning frame for POC %d, GOP %d, dts %"PRId64", pts %"PRId64"\n",
497  frame.poc, frame.gop, out->dts, out->pts);
498 
499  return 0;
500 }
501 
503 {
506 
507  if (s->flush)
508  s->flush(ctx);
509  s->eof = 0;
510  s->gop = 0;
511 
512  while (s->fifo && av_fifo_read(s->fifo, &frame, 1) >= 0)
513  av_packet_free(&frame.pkt);
514 
516  av_tree_destroy(s->root);
517  s->root = NULL;
518 
519  ff_cbs_fragment_reset(&s->au);
520  if (s->cbc)
521  ff_cbs_flush(s->cbc);
522 }
523 
525 {
527 
529 
530  av_fifo_freep2(&s->fifo);
531  ff_refstruct_pool_uninit(&s->node_pool);
532  ff_cbs_fragment_free(&s->au);
533  ff_cbs_close(&s->cbc);
534 }
535 
536 static const enum AVCodecID dts2pts_codec_ids[] = {
539 };
540 
542  .p.name = "dts2pts",
543  .p.codec_ids = dts2pts_codec_ids,
544  .priv_data_size = sizeof(DTS2PTSContext),
545  .init = dts2pts_init,
546  .flush = dts2pts_flush,
547  .close = dts2pts_close,
549 };
SPS::offset_for_ref_frame
int32_t offset_for_ref_frame[256]
Definition: h264_ps.h:79
H264_NAL_IDR_SLICE
@ H264_NAL_IDR_SLICE
Definition: h264.h:39
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:428
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
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:94
H264POCContext::frame_num_offset
int frame_num_offset
for POC type 2
Definition: h264_parse.h:90
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:502
DTS2PTSContext::fifo_size
size_t fifo_size
Definition: dts2pts.c:71
ff_refstruct_pool_alloc
FFRefStructPool * ff_refstruct_pool_alloc(size_t size, unsigned flags)
Equivalent to ff_refstruct_pool_alloc(size, flags, NULL, NULL, NULL, NULL, NULL)
Definition: refstruct.c:335
out
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:50
ff_cbs_fragment_free
av_cold void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:186
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:48
ff_cbs_read_extradata
int ff_cbs_read_extradata(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecParameters *par)
Read the extradata bitstream found in codec parameters into a fragment, then split into units and dec...
Definition: cbs.c:286
cbs_h264.h
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:107
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
int64_t
long long int64_t
Definition: coverity.c:34
DTS2PTSH264Context
Definition: dts2pts.c:53
h264_parse.h
ff_cbs_fragment_reset
void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment's own data buffer, but not the units a...
Definition: cbs.c:172
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:219
DTS2PTSContext
Definition: dts2pts.c:62
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:74
dts2pts_filter
static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
Definition: dts2pts.c:426
cbs.h
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:551
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:120
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
h264_init
static int h264_init(AVBSFContext *ctx)
Definition: dts2pts.c:155
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
H264_MAX_MMCO_COUNT
@ H264_MAX_MMCO_COUNT
Definition: h264.h:92
DTS2PTSFrame::pkt
AVPacket * pkt
Definition: dts2pts.c:47
SPS::frame_mbs_only_flag
int frame_mbs_only_flag
Definition: h264_ps.h:62
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
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:54
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:70
ff_cbs_close
av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:142
DTS2PTSH264Context::poc_diff
int poc_diff
Definition: dts2pts.c:56
H264POCContext::delta_poc
int delta_poc[2]
Definition: h264_parse.h:86
SPS::poc_type
int poc_type
pic_order_cnt_type
Definition: h264_ps.h:51
DTS2PTSContext::fifo
AVFifo * fifo
Definition: dts2pts.c:64
DTS2PTSH264Context::sps
SPS sps
Definition: dts2pts.c:55
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:188
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
ff_refstruct_pool_uninit
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
CodedBitstreamH264Context::active_sps
const H264RawSPS * active_sps
Definition: cbs_h264.h:436
DTS2PTSContext::u
union DTS2PTSContext::@58 u
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:168
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_fifo_read
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition: fifo.c:240
duration
int64_t duration
Definition: movenc.c:65
DTS2PTSContext::cbc
CodedBitstreamContext * cbc
Definition: dts2pts.c:73
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
ff_dts2pts_bsf
const FFBitStreamFilter ff_dts2pts_bsf
Definition: dts2pts.c:541
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
DTS2PTSContext::filter
int(* filter)(AVBSFContext *ctx)
Definition: dts2pts.c:69
DTS2PTSNode::poc
int poc
Definition: dts2pts.c:42
DTS2PTSNode::dts
int64_t dts
Definition: dts2pts.c:40
filter
int(* filter)(AVBSFContext *ctx)
Definition: dts2pts.c:369
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
DTS2PTSContext::nb_frame
int nb_frame
Definition: dts2pts.c:80
ctx
AVFormatContext * ctx
Definition: movenc.c:49
FFRefStructPool
FFRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition: refstruct.c:183
key
const char * key
Definition: hwcontext_opencl.c:189
h264_flush
static void h264_flush(AVBSFContext *ctx)
Definition: dts2pts.c:354
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
FFBitStreamFilter
Definition: bsf_internal.h:27
SPS
Sequence parameter set.
Definition: h264_ps.h:44
DTS2PTSContext::flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:70
DTS2PTSNode
Definition: dts2pts.c:39
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:370
get_mmco_reset
static int get_mmco_reset(const H264RawSliceHeader *header)
Definition: dts2pts.c:169
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:485
av_tree_destroy
void av_tree_destroy(AVTreeNode *t)
Definition: tree.c:146
h264_ps.h
DTS2PTSContext::node_pool
FFRefStructPool * node_pool
Definition: dts2pts.c:65
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:376
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
DTS2PTSFrame::poc_diff
int poc_diff
Definition: dts2pts.c:49
DTS2PTSFrame
Definition: dts2pts.c:46
dts2pts_codec_ids
static enum AVCodecID dts2pts_codec_ids[]
Definition: dts2pts.c:536
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
DTS2PTSContext::h264
DTS2PTSH264Context h264
Definition: dts2pts.c:77
AVFifo
Definition: fifo.c:35
DTS2PTSH264Context::highest_poc
int highest_poc
Definition: dts2pts.c:58
free_node
static int free_node(void *opaque, void *elem)
Definition: dts2pts.c:112
DTS2PTSH264Context::last_poc
int last_poc
Definition: dts2pts.c:57
SPS::poc_cycle_length
int poc_cycle_length
num_ref_frames_in_pic_order_cnt_cycle
Definition: h264_ps.h:56
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
DTS2PTSNode::duration
int64_t duration
Definition: dts2pts.c:41
DTS2PTSContext::init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:68
DTS2PTSContext::gop
int gop
Definition: dts2pts.c:81
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:164
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:532
SPS::offset_for_top_to_bottom_field
int offset_for_top_to_bottom_field
Definition: h264_ps.h:55
func_tab
static const struct @57 func_tab[]
DTS2PTSH264Context::picture_structure
int picture_structure
Definition: dts2pts.c:59
H264POCContext::frame_num
int frame_num
Definition: h264_parse.h:87
H264RawSliceHeader
Definition: cbs_h264.h:330
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:67
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
h264_filter
static int h264_filter(AVBSFContext *ctx)
Definition: dts2pts.c:225
dec_poc
static int dec_poc(void *opaque, void *elem)
Definition: dts2pts.c:104
H264POCContext
Definition: h264_parse.h:82
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
DTS2PTSContext::au
CodedBitstreamFragment au
Definition: dts2pts.c:74
H264_MAX_DPB_FRAMES
@ H264_MAX_DPB_FRAMES
Definition: h264.h:76
cmp_insert
static int cmp_insert(const void *key, const void *node)
Definition: dts2pts.c:86
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:264
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
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:367
H264_NAL_SLICE
@ H264_NAL_SLICE
Definition: h264.h:35
CodedBitstreamUnitType
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition: cbs.h:47
dts2pts_close
static void dts2pts_close(AVBSFContext *ctx)
Definition: dts2pts.c:524
h264_decompose_unit_types
static const CodedBitstreamUnitType h264_decompose_unit_types[]
Definition: dts2pts.c:148
ff_cbs_read_packet
int ff_cbs_read_packet(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt)
Read the data bitstream from a packet into a fragment, then split into units and decompose.
Definition: cbs.c:304
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
mem.h
DTS2PTSContext::eof
int eof
Definition: dts2pts.c:82
ff_cbs_init
av_cold int ff_cbs_init(CodedBitstreamContext **ctx_ptr, enum AVCodecID codec_id, void *log_ctx)
Create and initialise a new context for the given codec.
Definition: cbs.c:90
H264POCContext::poc_lsb
int poc_lsb
Definition: h264_parse.h:83
DTS2PTSContext::root
struct AVTreeNode * root
Definition: dts2pts.c:63
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
DTS2PTSNode::gop
int gop
Definition: dts2pts.c:43
AVPacket
This structure stores compressed data.
Definition: packet.h:510
h264_queue_frame
static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
Definition: dts2pts.c:185
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
ff_cbs_flush
av_cold void ff_cbs_flush(CodedBitstreamContext *ctx)
Reset all internal state in a context.
Definition: cbs.c:136
H264POCContext::prev_poc_msb
int prev_poc_msb
poc_msb of the last reference pic for POC type 0
Definition: h264_parse.h:88
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1288
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
fifo_size
size_t fifo_size
Definition: dts2pts.c:371
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:153
ff_refstruct_pool_get
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
SPS::log2_max_frame_num
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
Definition: h264_ps.h:50
H264RawSlice
Definition: cbs_h264.h:408
H264RawSPS
Definition: cbs_h264.h:102