FFmpeg  4.3.8
av1_frame_merge_bsf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 James Almer <jamrial@gmail.com>
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 #include "bsf.h"
22 #include "bsf_internal.h"
23 #include "cbs.h"
24 #include "cbs_av1.h"
25 
26 typedef struct AV1FMergeContext {
30  int idx;
32 
34 {
36 
37  ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[0]);
38  ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[1]);
39  av_packet_unref(ctx->in);
40  av_packet_unref(ctx->pkt);
41 }
42 
44 {
46  CodedBitstreamFragment *frag = &ctx->frag[ctx->idx], *tu = &ctx->frag[!ctx->idx];
47  AVPacket *in = ctx->in, *buffer_pkt = ctx->pkt;
48  int err, i;
49 
50  err = ff_bsf_get_packet_ref(bsf, in);
51  if (err < 0) {
52  if (err == AVERROR_EOF && tu->nb_units > 0)
53  goto eof;
54  return err;
55  }
56 
57  err = ff_cbs_read_packet(ctx->cbc, frag, in);
58  if (err < 0) {
59  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
60  goto fail;
61  }
62 
63  if (frag->nb_units == 0) {
64  av_log(bsf, AV_LOG_ERROR, "No OBU in packet.\n");
65  err = AVERROR_INVALIDDATA;
66  goto fail;
67  }
68 
69  if (tu->nb_units == 0 && frag->units[0].type != AV1_OBU_TEMPORAL_DELIMITER) {
70  av_log(bsf, AV_LOG_ERROR, "Missing Temporal Delimiter.\n");
71  err = AVERROR_INVALIDDATA;
72  goto fail;
73  }
74 
75  for (i = 1; i < frag->nb_units; i++) {
76  if (frag->units[i].type == AV1_OBU_TEMPORAL_DELIMITER) {
77  av_log(bsf, AV_LOG_ERROR, "Temporal Delimiter in the middle of a packet.\n");
78  err = AVERROR_INVALIDDATA;
79  goto fail;
80  }
81  }
82 
83  if (tu->nb_units > 0 && frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
84 eof:
85  err = ff_cbs_write_packet(ctx->cbc, buffer_pkt, tu);
86  if (err < 0) {
87  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
88  goto fail;
89  }
90  av_packet_move_ref(out, buffer_pkt);
91 
92  // Swap fragment index, to avoid copying fragment references.
93  ctx->idx = !ctx->idx;
94  } else {
95  for (i = 0; i < frag->nb_units; i++) {
96  err = ff_cbs_insert_unit_content(ctx->cbc, tu, -1, frag->units[i].type,
97  frag->units[i].content, frag->units[i].content_ref);
98  if (err < 0)
99  goto fail;
100  }
101 
102  err = AVERROR(EAGAIN);
103  }
104 
105  // Buffer packets with timestamps. There should be at most one per TU, be it split or not.
106  if (!buffer_pkt->data && in->pts != AV_NOPTS_VALUE)
107  av_packet_move_ref(buffer_pkt, in);
108  else
109  av_packet_unref(in);
110 
111  ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[ctx->idx]);
112 
113 fail:
114  if (err < 0 && err != AVERROR(EAGAIN))
116 
117  return err;
118 }
119 
121 {
123 
124  ctx->in = av_packet_alloc();
125  ctx->pkt = av_packet_alloc();
126  if (!ctx->in || !ctx->pkt)
127  return AVERROR(ENOMEM);
128 
129  return ff_cbs_init(&ctx->cbc, AV_CODEC_ID_AV1, bsf);
130 }
131 
133 {
135 
136  ff_cbs_fragment_free(ctx->cbc, &ctx->frag[0]);
137  ff_cbs_fragment_free(ctx->cbc, &ctx->frag[1]);
138  av_packet_free(&ctx->in);
139  av_packet_free(&ctx->pkt);
140  ff_cbs_close(&ctx->cbc);
141 }
142 
143 static const enum AVCodecID av1_frame_merge_codec_ids[] = {
145 };
146 
148  .name = "av1_frame_merge",
149  .priv_data_size = sizeof(AV1FMergeContext),
152  .close = av1_frame_merge_close,
155 };
static int av1_frame_merge_filter(AVBSFContext *bsf, AVPacket *out)
int nb_units
Number of units in this fragment.
Definition: cbs.h:147
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static void flush(AVCodecContext *avctx)
static void av1_frame_merge_close(AVBSFContext *bsf)
int ff_cbs_write_packet(CodedBitstreamContext *ctx, AVPacket *pkt, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to a packet.
Definition: cbs.c:401
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
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:74
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:68
The bitstream filter state.
Definition: bsf.h:49
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, AVBufferRef *content_buf)
Insert a new unit into a fragment with the given content.
Definition: cbs.c:722
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:70
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhd.c:196
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:64
static enum AVCodecID av1_frame_merge_codec_ids[]
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:242
const char * name
Definition: bsf.h:99
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:663
#define AVERROR_EOF
End of file.
Definition: error.h:55
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:101
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:162
#define av_log(a,...)
void ff_cbs_fragment_free(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:157
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define fail()
Definition: checkasm.h:123
AVFormatContext * ctx
Definition: movenc.c:48
static void av1_frame_merge_flush(AVBSFContext *bsf)
CodedBitstreamContext * cbc
const AVBitStreamFilter ff_av1_frame_merge_bsf
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:116
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment&#39;s own data buffer, but not the units a...
Definition: cbs.c:142
Context structure for coded bitstream operations.
Definition: cbs.h:168
AVBufferRef * content_ref
If content is reference counted, a reference to the buffer containing content.
Definition: cbs.h:106
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:115
static int av1_frame_merge_init(AVBSFContext *bsf)
static enum AVCodecID codec_ids[]
CodedBitstreamFragment frag[2]
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:53
FILE * out
Definition: movenc.c:54
This structure stores compressed data.
Definition: packet.h:332
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:249
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:348
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248