FFmpeg: libavcodec/bsf/dts2pts.c Source File
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
30
38
45
52
61
66
67 // Codec specific function pointers and constants
72
75
76 union {
79
84
85 // AVTreeNode callbacks
87 {
92 }
93
95 {
102 }
103
105 {
107 int dec = *(int *)opaque;
109 return 0;
110 }
111
113 {
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++) {
127 if (!node)
130 if (!poc_node) {
133 }
138 if (
ret &&
ret != poc_node) {
142 }
143 }
144 return 0;
145 }
146
147 // H.264
153 };
154
156 {
159
162
163 s->nb_frame = -(
ctx->par_in->video_delay << 1);
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
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
186 {
191
195 if (poc < 0) {
197 s->nb_frame -= poc_diff;
198 }
199 // Check if there was a POC reset (Like an IDR slice)
202 s->gop = (
s->gop + 1) %
s->fifo_size;
204 }
205
211 s->nb_frame += poc_diff;
212
213 // Add frame to output FIFO only once
214 if (*queued)
215 return 0;
216
220 *queued = 1;
221
222 return 0;
223 }
224
226 {
231 int output_picture_number = INT_MIN;
232 int field_poc[2];
234
238
243 }
244
247
248 switch (unit->
type) {
254 // fall-through
260 int got_reset;
261
265 }
266 // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
276
279 header->field_pic_flag +
header->bottom_field_flag : 3);
280
286
287 field_poc[0] = field_poc[1] = INT_MAX;
290 header->nal_unit_header.nal_ref_idc);
294 }
295
299 if (
header->nal_unit_header.nal_ref_idc != 0) {
301 if (got_reset)
303 else
305 }
306
307 if (output_picture_number != h264->
last_poc) {
310
311 if ((output_picture_number < 0) && !h264->
last_poc)
316 }
322 }
323 }
324 }
325 h264->
last_poc = output_picture_number;
327
331 }
332 break;
333 }
334 default:
335 break;
336 }
337 }
338
339 if (output_picture_number == INT_MIN) {
343 }
344
348 if (!queued)
350
352 }
353
355 {
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);
363 }
364
365 // Core functions
366 static const struct {
374 };
375
377 {
381
388 break;
389 }
390 }
394
398
401
404
408
413 }
414
415 if (!
ctx->par_in->extradata_size)
416 return 0;
417
421
423
424 return 0;
425 }
426
428 {
433
434 // Fill up the FIFO and POC tree
441 }
442 }
443
446
447 // Fetch a packet from the FIFO
452
453 // Search the timestamp for the requested POC and set PTS
455 if (!poc_node) {
456 poc_node = next[1];
457 if (!poc_node || poc_node->
poc !=
frame.poc)
458 poc_node = next[0];
459 }
460 if (poc_node && poc_node->
poc ==
frame.poc) {
463 // Remove the found entry from the tree
467 if (!poc_node || poc_node->
dts !=
out->pts)
468 continue;
473 }
474 }
475 }
else if (
s->eof &&
frame.poc > INT_MIN) {
478 if (poc_node && poc_node->
poc == dup.
poc) {
487 }
490 "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
493 } else
495 } else
499
500 return 0;
501 }
502
504 {
507
512
515
519
523 }
524
526 {
528
530
535 }
536
540 };
541
550 };
int32_t offset_for_ref_frame[256]
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
#define AV_LOG_WARNING
Something somehow does not look correct.
size_t av_fifo_can_write(const AVFifo *f)
static int cmp_find(const void *key, const void *node)
int frame_num_offset
for POC type 2
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
static void dts2pts_flush(AVBSFContext *ctx)
FFRefStructPool * ff_refstruct_pool_alloc(size_t size, unsigned flags)
Equivalent to ff_refstruct_pool_alloc(size, flags, NULL, NULL, NULL, NULL, NULL)
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.
int offset_for_non_ref_pic
#define AVERROR_EOF
End of file.
void * av_tree_insert(AVTreeNode **tp, void *key, int(*cmp)(const void *key, const void *b), AVTreeNode **next)
Insert or remove an element.
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...
void * content
Pointer to the decomposed form of this unit.
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...
Context structure for coded bitstream operations.
CodedBitstreamUnitType type
Codec-specific type of this unit.
static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
static int alloc_and_insert_node(AVBSFContext *ctx, int64_t ts, int64_t duration, int poc, int poc_diff, int gop)
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
static int h264_init(AVBSFContext *ctx)
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
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.
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
The bitstream filter state.
int prev_poc_lsb
poc_lsb of the last reference pic for POC type 0
Coded bitstream unit structure.
av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
int poc_type
pic_order_cnt_type
int prev_frame_num
frame_num of the last pic for POC type 1/2
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
const H264RawSPS * active_sps
#define FFDIFFSIGN(x, y)
Comparator.
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
CodedBitstreamContext * cbc
Coded bitstream fragment structure, combining one or more units.
const FFBitStreamFilter ff_dts2pts_bsf
int prev_frame_num_offset
for POC type 2
int(* filter)(AVBSFContext *ctx)
int(* filter)(AVBSFContext *ctx)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
FFRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
static void h264_flush(AVBSFContext *ctx)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
void(* flush)(AVBSFContext *ctx)
size_t av_fifo_can_read(const AVFifo *f)
void(* flush)(AVBSFContext *ctx)
static int get_mmco_reset(const H264RawSliceHeader *header)
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
void av_tree_destroy(AVTreeNode *t)
FFRefStructPool * node_pool
AVCodecID
Identify the syntax and semantics of the bitstream.
#define FF_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...
static int dts2pts_init(AVBSFContext *ctx)
AVBitStreamFilter p
The public AVBitStreamFilter.
static enum AVCodecID dts2pts_codec_ids[]
int(* init)(AVBSFContext *ctx)
static int free_node(void *opaque, void *elem)
int poc_cycle_length
num_ref_frames_in_pic_order_cnt_cycle
#define AV_NOPTS_VALUE
Undefined timestamp value.
int(* init)(AVBSFContext *ctx)
static const uint8_t header[24]
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
int offset_for_top_to_bottom_field
H264RawSliceHeader header
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
int log2_max_poc_lsb
log2_max_pic_order_cnt_lsb_minus4
#define i(width, name, range_min, range_max)
static int h264_filter(AVBSFContext *ctx)
static int dec_poc(void *opaque, void *elem)
CodedBitstreamFragment au
static int cmp_insert(const void *key, const void *node)
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)
union DTS2PTSContext::@60 u
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
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
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.
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
static const struct @59 func_tab[]
static void dts2pts_close(AVBSFContext *ctx)
static const CodedBitstreamUnitType h264_decompose_unit_types[]
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.
void * av_tree_find(const AVTreeNode *t, void *key, int(*cmp)(const void *key, const void *b), void *next[2])
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.
This structure stores compressed data.
static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
av_cold void ff_cbs_flush(CodedBitstreamContext *ctx)
Reset all internal state in a context.
int prev_poc_msb
poc_msb of the last reference pic for POC type 0
void * priv_data
Format private data.
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
int nb_units
Number of units in this fragment.
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
Generated on Fri Aug 22 2025 13:58:12 for FFmpeg by
doxygen
1.8.17