FFmpeg
lcevc_merge.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/opt.h"
20 
21 #include "libavcodec/bsf.h"
24 #include "libavcodec/bytestream.h"
25 #include "libavcodec/h2645_parse.h"
26 #include "libavcodec/packet.h"
28 
29 typedef struct LCEVCMergeContext {
30  AVClass *class;
34 
36  AVPacket *base_pkt, const AVPacket *lcevc_pkt)
37 {
39 
40  if (lcevc->nal_length_size && lcevc_pkt->size > lcevc->nal_length_size) {
41  GetByteContext bc;
42  size_t size = 0;
43 
44  bytestream2_init(&bc, lcevc_pkt->data, lcevc_pkt->size);
45  do {
46  int i = 0;
47  int nal_size = get_nalsize(lcevc->nal_length_size,
49  if (nal_size < 0)
50  return base_pkt;
51  if (nal_size > INT_MAX - 4)
52  return base_pkt;
53  size += nal_size + 4;
54  nal_size += i;
55  if (nal_size > bytestream2_get_bytes_left(&bc))
56  return base_pkt;
57  bytestream2_skip(&bc, nal_size);
58  } while (bytestream2_get_bytes_left(&bc) > 0);
59 
60  uint8_t *buf = av_packet_new_side_data(base_pkt, AV_PKT_DATA_LCEVC, size);
61  if (!buf)
62  return base_pkt;
63 
64  PutByteContext pc;
65  bytestream2_init_writer(&pc, buf, size);
66  bytestream2_init(&bc, lcevc_pkt->data, lcevc_pkt->size);
67  do {
68  int i = 0;
69  int nal_size = get_nalsize(lcevc->nal_length_size,
71  bytestream2_skipu(&bc, i);
72  bytestream2_put_be32u(&pc, 1); // start code
73  bytestream2_put_bufferu(&pc, bc.buffer, nal_size);
74  bytestream2_skipu(&bc, nal_size);
75  } while (bytestream2_get_bytes_left(&bc) > 0);
76  } else {
77  uint8_t *buf = av_packet_new_side_data(base_pkt, AV_PKT_DATA_LCEVC, lcevc_pkt->size);
78  if (buf)
79  memcpy(buf, lcevc_pkt->data, lcevc_pkt->size);
80  }
81 
82  return base_pkt;
83 }
84 
86 {
87  AVBitStreamFilterContext *ctx = fs->parent;
88  AVPacket *base, *enhancement, *out = NULL;
89  int ret;
90 
91  ret = ff_packetsync_dualinput_get(fs, &base, &enhancement);
92  if (ret < 0)
93  return ret;
94  if (!enhancement)
95  return ff_bsf_filter_packet(ctx->outputs[0], base);
96  out = lcevc_merge_packets(ctx, base, enhancement);
97  return ff_bsf_filter_packet(ctx->outputs[0], out);
98 }
99 
101 {
103  LCEVCMergeContext *lcevc = ctx->priv_data;
104 
105  if (inlink->par->extradata_size > 4 && inlink->par->extradata[0])
106  lcevc->nal_length_size = (inlink->par->extradata[4] >> 6) + 1;
107 
108  return 0;
109 }
110 
112 {
113  AVBitStreamFilterContext *ctx = outlink->src;
114  LCEVCMergeContext *lcevc = ctx->priv_data;
115  int ret;
116 
118  if (ret < 0)
119  return ret;
120 
121  ret = ff_packetsync_configure(&lcevc->ps);
122  outlink->time_base = lcevc->ps.time_base;
123 
124  return ret;
125 }
126 
128 {
129  LCEVCMergeContext *lcevc = ctx->priv_data;
130 
131  lcevc->ps.on_event = lcevc_merge;
132  return 0;
133 }
134 
136 {
137  LCEVCMergeContext *lcevc = ctx->priv_data;
138 
139  ff_packetsync_uninit(&lcevc->ps);
140 }
141 
143 
145 {
146  LCEVCMergeContext *lcevc = ctx->priv_data;
147  return ff_packetsync_activate(&lcevc->ps);
148 }
149 
150 static const enum AVCodecID enhancement_codec_ids[] = {
152 };
153 
155  {
156  .name = "base",
157  },
158  {
159  .name = "enhancement",
160  .codec_ids = enhancement_codec_ids,
161  .config_props = config_enhancement,
162  },
163 };
164 
166  {
167  .name = "default",
168  .config_props = config_output,
169  },
170 };
171 
173  .p.name = "lcevc_merge",
174  .p.priv_class = &lcevc_merge_class,
175  .priv_data_size = sizeof(LCEVCMergeContext),
176  .preinit = lcevc_merge_packetsync_preinit,
177  .init2 = init,
178  .uninit = uninit,
179  .activate = activate,
182 };
h2645_parse.h
bsf_internal.h
opt.h
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
out
static FILE * out
Definition: movenc.c:55
lcevc_merge
static int lcevc_merge(FFPacketSync *fs)
Definition: lcevc_merge.c:85
GetByteContext
Definition: bytestream.h:33
bytestream2_skipu
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:174
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
av_cold
#define av_cold
Definition: attributes.h:119
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
AVBitStreamFilterPad
A filter pad used for either input or output.
Definition: filters.h:35
AVPacket::data
uint8_t * data
Definition: packet.h:603
ff_lcevc_merge_bsf
const FFBitStreamFilter ff_lcevc_merge_bsf
Definition: lcevc_merge.c:172
base
uint8_t base
Definition: vp3data.h:128
enhancement_codec_ids
static enum AVCodecID enhancement_codec_ids[]
Definition: lcevc_merge.c:150
ff_packetsync_dualinput_get
int ff_packetsync_dualinput_get(FFPacketSync *fs, AVPacket **f0, AVPacket **f1)
Definition: packetsync.c:384
preinit
static av_cold int preinit(AVBitStreamFilterContext *ctx)
Definition: source.c:137
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
activate
static int activate(AVBitStreamFilterContext *ctx)
Definition: lcevc_merge.c:144
bsf.h
lcevc_merge_outputs
static const AVBitStreamFilterPad lcevc_merge_outputs[]
Definition: lcevc_merge.c:165
LCEVCMergeContext::nal_length_size
int nal_length_size
Definition: lcevc_merge.c:32
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
LCEVCMergeContext::ps
FFPacketSync ps
Definition: lcevc_merge.c:31
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
BSFILTER_INPUTS
#define BSFILTER_INPUTS(array)
Definition: filters.h:145
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
ff_bsf_filter_packet
int ff_bsf_filter_packet(AVBitStreamFilterLink *link, AVPacket *pkt)
Send a packet of data to the next filter.
Definition: bitstreamfilter.c:666
AV_PKT_DATA_LCEVC
@ AV_PKT_DATA_LCEVC
Raw LCEVC payload data, as a uint8_t array, with NAL emulation bytes intact.
Definition: packet.h:346
lcevc_merge_inputs
static const AVBitStreamFilterPad lcevc_merge_inputs[]
Definition: lcevc_merge.c:154
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
FFBitStreamFilter
Definition: bsf_internal.h:29
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
packet_internal.h
PutByteContext
Definition: bytestream.h:37
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:33
AVPacket::size
int size
Definition: packet.h:604
LCEVCMergeContext
Definition: lcevc_merge.c:29
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
AV_CODEC_ID_LCEVC
@ AV_CODEC_ID_LCEVC
Definition: codec_id.h:608
ff_packetsync_configure
int ff_packetsync_configure(FFPacketSync *fs)
Configure a packet sync structure.
Definition: packetsync.c:138
PACKETSYNC_DEFINE_CLASS_EXT
PACKETSYNC_DEFINE_CLASS_EXT(lcevc_merge, LCEVCMergeContext, ps, NULL)
lcevc_merge_packets
static AVPacket * lcevc_merge_packets(AVBitStreamFilterContext *ctx, AVPacket *base_pkt, const AVPacket *lcevc_pkt)
Definition: lcevc_merge.c:35
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
packet.h
config_output
static int config_output(AVBitStreamFilterLink *outlink)
Definition: lcevc_merge.c:111
BSFILTER_OUTPUTS
#define BSFILTER_OUTPUTS(array)
Definition: filters.h:146
uninit
static av_cold void uninit(AVBitStreamFilterContext *ctx)
Definition: lcevc_merge.c:135
packetsync.h
ff_packetsync_uninit
void ff_packetsync_uninit(FFPacketSync *fs)
Free all memory currently allocated.
Definition: packetsync.c:289
FFPacketSync
Packet sync structure.
Definition: packetsync.h:160
ret
ret
Definition: filter_design.txt:187
config_enhancement
static av_cold int config_enhancement(AVBitStreamFilterLink *inlink)
Definition: lcevc_merge.c:100
FFPacketSync::on_event
int(* on_event)(struct FFPacketSync *fs)
Callback called when a packet event is ready.
Definition: packetsync.h:186
ff_packetsync_init_dualinput
int ff_packetsync_init_dualinput(FFPacketSync *fs, AVBitStreamFilterContext *parent)
Initialize a packet sync structure for dualinput.
Definition: packetsync.c:366
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
AVBitStreamFilterPad::name
const char * name
Pad name.
Definition: filters.h:41
ff_packetsync_activate
int ff_packetsync_activate(FFPacketSync *fs)
Examine the packets in the filter's input and try to produce output.
Definition: packetsync.c:340
bytestream2_put_bufferu
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:301
AVPacket
This structure stores compressed data.
Definition: packet.h:580
init
static av_cold int init(AVBitStreamFilterContext *ctx)
Definition: lcevc_merge.c:127
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
get_nalsize
static int get_nalsize(int nal_length_size, const uint8_t *buf, int buf_size, int *buf_index, void *logctx)
Definition: h2645_parse.h:130
FFPacketSync::time_base
AVRational time_base
Time base for the output events.
Definition: packetsync.h:176
AVBitStreamFilterContext
An instance of a filter.
Definition: bsf.h:347
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1342