FFmpeg: libavcodec/dts2pts_bsf.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
29
36
43
50
59
63
64 // Codec specific function pointers and constants
69
72
73 union {
76
81
82 // AVTreeNode callbacks
84 {
89 }
90
92 {
99 }
100
102 {
104 int dec = *(int *)opaque;
106 return 0;
107 }
108
110 {
113 return 0;
114 }
115
116 // Shared functions
118 int poc, int poc_diff, int gop)
119 {
121 for (
int i = 0;
i < poc_diff;
i++) {
124 if (!node)
127 if (!poc_node) {
130 }
135 if (
ret &&
ret != poc_node) {
139 }
140 }
141 return 0;
142 }
143
144 // H.264
150 };
151
153 {
156
159
160 s->nb_frame = -(
ctx->par_in->video_delay << 1);
162
163 return 0;
164 }
165
167 {
168 if (
header->nal_unit_header.nal_ref_idc == 0 ||
169 !
header->adaptive_ref_pic_marking_mode_flag)
170 return 0;
171
173 if (
header->mmco[
i].memory_management_control_operation == 0)
174 return 0;
175 else if (
header->mmco[
i].memory_management_control_operation == 5)
176 return 1;
177 }
178
179 return 0;
180 }
181
183 {
188
192 if (poc < 0) {
194 s->nb_frame -= poc_diff;
195 }
196 // Check if there was a POC reset (Like an IDR slice)
199 s->gop = (
s->gop + 1) %
s->fifo_size;
201 }
202
208 s->nb_frame += poc_diff;
209
210 // Add frame to output FIFO only once
211 if (*queued)
212 return 0;
213
217 *queued = 1;
218
219 return 0;
220 }
221
223 {
228 int output_picture_number = INT_MIN;
229 int field_poc[2];
231
235
240 }
241
244
245 switch (unit->
type) {
251 // fall-through
257 int got_reset;
258
262 }
263 // Initialize the SPS struct with the fields ff_h264_init_poc() cares about
273
276 header->field_pic_flag +
header->bottom_field_flag : 3);
277
283
284 field_poc[0] = field_poc[1] = INT_MAX;
287 header->nal_unit_header.nal_ref_idc);
291 }
292
296 if (
header->nal_unit_header.nal_ref_idc != 0) {
298 if (got_reset)
300 else
302 }
303
304 if (output_picture_number != h264->
last_poc) {
307
308 if ((output_picture_number < 0) && !h264->
last_poc)
310 else if (
FFABS((int64_t)output_picture_number) < h264->
poc_diff) {
313 }
319 }
320 }
321 }
322 h264->
last_poc = output_picture_number;
324
328 }
329 break;
330 }
331 default:
332 break;
333 }
334 }
335
336 if (output_picture_number == INT_MIN) {
340 }
341
345 if (!queued)
347
349 }
350
352 {
355
356 memset(&h264->
sps, 0,
sizeof(h264->
sps));
357 memset(&h264->
poc, 0,
sizeof(h264->
poc));
358 s->nb_frame = -(
ctx->par_in->video_delay << 1);
360 }
361
362 // Core functions
363 static const struct {
371 };
372
374 {
378
385 break;
386 }
387 }
391
395
399
404 }
405
406 if (!
ctx->par_in->extradata_size)
407 return 0;
408
412
414
415 return 0;
416 }
417
419 {
424
425 // Fill up the FIFO and POC tree
432 }
433 }
434
437
438 // Fetch a packet from the FIFO
443
444 // Search the timestamp for the requested POC and set PTS
446 if (!poc_node) {
447 poc_node = next[1];
448 if (!poc_node || poc_node->
poc !=
frame.poc)
449 poc_node = next[0];
450 }
451 if (poc_node && poc_node->
poc ==
frame.poc) {
454 // Remove the found entry from the tree
458 if (!poc_node || poc_node->
dts !=
out->pts)
459 continue;
464 }
465 }
466 }
else if (
s->eof &&
frame.poc > INT_MIN) {
469 if (poc_node && poc_node->
poc == dup.
poc) {
478 }
481 "generated from POC %d, GOP %d, dts %"PRId64", duration %"PRId64"\n",
484 } else
486 } else
490
491 return 0;
492 }
493
495 {
498
503
506
510
514 }
515
517 {
519
521
525 }
526
530 };
531
540 };
int32_t offset_for_ref_frame[256]
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
static int dts2pts_init(AVBSFContext *ctx)
#define AV_LOG_WARNING
Something somehow does not look correct.
size_t av_fifo_can_write(const AVFifo *f)
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
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...
static int dec_poc(void *opaque, void *elem)
Context structure for coded bitstream operations.
CodedBitstreamUnitType type
Codec-specific type of this unit.
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
static int free_node(void *opaque, void *elem)
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
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
static int cmp_insert(const void *key, const void *node)
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
const H264RawSPS * active_sps
static int h264_filter(AVBSFContext *ctx)
static int alloc_and_insert_node(AVBSFContext *ctx, int64_t ts, int64_t duration, int poc, int poc_diff, int gop)
const FFBitStreamFilter ff_dts2pts_bsf
#define FFDIFFSIGN(x, y)
Comparator.
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
static int get_mmco_reset(const H264RawSliceHeader *header)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
static const CodedBitstreamUnitType h264_decompose_unit_types[]
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
static void dts2pts_close(AVBSFContext *ctx)
CodedBitstreamContext * cbc
Coded bitstream fragment structure, combining one or more units.
int prev_frame_num_offset
for POC type 2
int(* filter)(AVBSFContext *ctx)
int(* init)(AVBSFContext *ctx)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
void(* flush)(AVBSFContext *ctx)
union DTS2PTSContext::@65 u
size_t av_fifo_can_read(const AVFifo *f)
static int h264_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, int *queued)
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)
static enum AVCodecID dts2pts_codec_ids[]
AVCodecID
Identify the syntax and semantics of the bitstream.
static void dts2pts_flush(AVBSFContext *ctx)
AVBitStreamFilter p
The public AVBitStreamFilter.
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(* filter)(AVBSFContext *ctx)
int offset_for_top_to_bottom_field
static int cmp_find(const void *key, const void *node)
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)
CodedBitstreamFragment au
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)
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.
static int dts2pts_filter(AVBSFContext *ctx, AVPacket *out)
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
static void h264_flush(AVBSFContext *ctx)
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])
void(* flush)(AVBSFContext *ctx)
static const struct @64 func_tab[]
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.
#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.
int nb_units
Number of units in this fragment.
int log2_max_frame_num
log2_max_frame_num_minus4 + 4
static int h264_init(AVBSFContext *ctx)
Generated on Tue Feb 28 2023 21:33:13 for FFmpeg by
doxygen
1.8.17