FFmpeg
remove_extradata.c
Go to the documentation of this file.
1 /*
2  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
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 "libavutil/log.h"
22 #include "libavutil/opt.h"
23 
24 #include "av1_parse.h"
25 #include "bsf.h"
26 #include "bsf_internal.h"
27 #include "h264.h"
28 #include "hevc.h"
29 #include "startcode.h"
30 #include "vc1_common.h"
31 
32 enum RemoveFreq {
36 };
37 
38 #define START_CODE 0x000001
39 
40 typedef struct RemoveExtradataContext {
41  const AVClass *class;
42  int freq;
44 
45 static int av1_split(const uint8_t *buf, int buf_size, void *logctx)
46 {
47  AV1OBU obu;
48  const uint8_t *ptr = buf, *end = buf + buf_size;
49 
50  while (ptr < end) {
51  int len = ff_av1_extract_obu(&obu, ptr, buf_size, logctx);
52  if (len < 0)
53  break;
54 
55  if (obu.type == AV1_OBU_FRAME_HEADER ||
56  obu.type == AV1_OBU_FRAME) {
57  return ptr - buf;
58  }
59  ptr += len;
60  buf_size -= len;
61  }
62 
63  return 0;
64 }
65 
66 static int h264_split(const uint8_t *buf, int buf_size)
67 {
68  const uint8_t *ptr = buf, *end = buf + buf_size;
69  uint32_t state = -1;
70  int has_sps = 0;
71  int has_pps = 0;
72  int nalu_type;
73 
74  while (ptr < end) {
75  ptr = avpriv_find_start_code(ptr, end, &state);
76  if ((state & 0xFFFFFF00) != 0x100)
77  break;
78  nalu_type = state & 0x1F;
79  if (nalu_type == H264_NAL_SPS) {
80  has_sps = 1;
81  } else if (nalu_type == H264_NAL_PPS)
82  has_pps = 1;
83  /* else if (nalu_type == 0x01 ||
84  * nalu_type == 0x02 ||
85  * nalu_type == 0x05) {
86  * }
87  */
88  else if ((nalu_type != H264_NAL_SEI || has_pps) &&
89  nalu_type != H264_NAL_AUD && nalu_type != H264_NAL_SPS_EXT &&
90  nalu_type != 0x0f) {
91  if (has_sps) {
92  while (ptr - 4 > buf && ptr[-5] == 0)
93  ptr--;
94  return ptr - 4 - buf;
95  }
96  }
97  }
98 
99  return 0;
100 }
101 
102 // Split after the parameter sets at the beginning of the stream if they exist.
103 static int hevc_split(const uint8_t *buf, int buf_size)
104 {
105  const uint8_t *ptr = buf, *end = buf + buf_size;
106  uint32_t state = -1;
107  int has_vps = 0;
108  int has_sps = 0;
109  int has_pps = 0;
110  int nut;
111 
112  while (ptr < end) {
113  ptr = avpriv_find_start_code(ptr, end, &state);
114  if ((state >> 8) != START_CODE)
115  break;
116  nut = (state >> 1) & 0x3F;
117  if (nut == HEVC_NAL_VPS)
118  has_vps = 1;
119  else if (nut == HEVC_NAL_SPS)
120  has_sps = 1;
121  else if (nut == HEVC_NAL_PPS)
122  has_pps = 1;
123  else if ((nut != HEVC_NAL_SEI_PREFIX || has_pps) &&
124  nut != HEVC_NAL_AUD) {
125  if (has_vps && has_sps) {
126  while (ptr - 4 > buf && ptr[-5] == 0)
127  ptr--;
128  return ptr - 4 - buf;
129  }
130  }
131  }
132  return 0;
133 }
134 
135 static int mpegvideo_split(const uint8_t *buf, int buf_size)
136 {
137  uint32_t state = -1;
138  int found = 0;
139 
140  for (int i = 0; i < buf_size; i++) {
141  state = (state << 8) | buf[i];
142  if (state == 0x1B3) {
143  found = 1;
144  } else if (found && state != 0x1B5 && state < 0x200 && state >= 0x100)
145  return i - 3;
146  }
147  return 0;
148 }
149 
150 static int mpeg4video_split(const uint8_t *buf, int buf_size)
151 {
152  const uint8_t *ptr = buf, *end = buf + buf_size;
153  uint32_t state = -1;
154 
155  while (ptr < end) {
156  ptr = avpriv_find_start_code(ptr, end, &state);
157  if (state == 0x1B3 || state == 0x1B6)
158  return ptr - 4 - buf;
159  }
160 
161  return 0;
162 }
163 
164 static int vc1_split(const uint8_t *buf, int buf_size)
165 {
166  const uint8_t *ptr = buf, *end = buf + buf_size;
167  uint32_t state = -1;
168  int charged = 0;
169 
170  while (ptr < end) {
171  ptr = avpriv_find_start_code(ptr, end, &state);
173  charged = 1;
174  } else if (charged && IS_MARKER(state))
175  return ptr - 4 - buf;
176  }
177 
178  return 0;
179 }
180 
182 {
184 
185  int ret;
186 
188  if (ret < 0)
189  return ret;
190 
191  if (s->freq == REMOVE_FREQ_ALL ||
192  (s->freq == REMOVE_FREQ_NONKEYFRAME && !(pkt->flags & AV_PKT_FLAG_KEY)) ||
193  (s->freq == REMOVE_FREQ_KEYFRAME && pkt->flags & AV_PKT_FLAG_KEY)) {
194  int i;
195 
196  switch (ctx->par_in->codec_id) {
197  case AV_CODEC_ID_AV1:
198  i = av1_split(pkt->data, pkt->size, ctx);
199  break;
200  case AV_CODEC_ID_AVS2:
201  case AV_CODEC_ID_AVS3:
202  case AV_CODEC_ID_CAVS:
203  case AV_CODEC_ID_MPEG4:
205  break;
206  case AV_CODEC_ID_H264:
207  i = h264_split(pkt->data, pkt->size);
208  break;
209  case AV_CODEC_ID_HEVC:
210  i = hevc_split(pkt->data, pkt->size);
211  break;
215  break;
216  case AV_CODEC_ID_VC1:
217  i = vc1_split(pkt->data, pkt->size);
218  break;
219  default:
220  i = 0;
221  }
222 
223  pkt->data += i;
224  pkt->size -= i;
225  }
226 
227  return 0;
228 }
229 
230 #define OFFSET(x) offsetof(RemoveExtradataContext, x)
231 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
232 static const AVOption options[] = {
233  { "freq", NULL, OFFSET(freq), AV_OPT_TYPE_INT, { .i64 = REMOVE_FREQ_KEYFRAME }, REMOVE_FREQ_KEYFRAME, REMOVE_FREQ_NONKEYFRAME, FLAGS, .unit = "freq" },
234  { "k", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = REMOVE_FREQ_NONKEYFRAME }, .flags = FLAGS, .unit = "freq" },
235  { "keyframe", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = REMOVE_FREQ_KEYFRAME }, .flags = FLAGS, .unit = "freq" },
236  { "e", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = REMOVE_FREQ_ALL }, .flags = FLAGS, .unit = "freq" },
237  { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = REMOVE_FREQ_ALL }, .flags = FLAGS, .unit = "freq" },
238  { NULL },
239 };
240 
242  .class_name = "remove_extradata",
243  .item_name = av_default_item_name,
244  .option = options,
245  .version = LIBAVUTIL_VERSION_INT,
246 };
247 
249  .p.name = "remove_extra",
250  .p.priv_class = &remove_extradata_class,
251  .priv_data_size = sizeof(RemoveExtradataContext),
253 };
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
bsf_internal.h
opt.h
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
av1_split
static int av1_split(const uint8_t *buf, int buf_size, void *logctx)
Definition: remove_extradata.c:45
AVPacket::data
uint8_t * data
Definition: packet.h:522
AVOption
AVOption.
Definition: opt.h:346
AV_CODEC_ID_AVS2
@ AV_CODEC_ID_AVS2
Definition: codec_id.h:246
AV1OBU
Definition: av1_parse.h:38
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
RemoveExtradataContext
Definition: remove_extradata.c:40
ff_remove_extradata_bsf
const FFBitStreamFilter ff_remove_extradata_bsf
Definition: remove_extradata.c:248
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
remove_extradata_class
static const AVClass remove_extradata_class
Definition: remove_extradata.c:241
av1_parse.h
bsf.h
AV1_OBU_FRAME_HEADER
@ AV1_OBU_FRAME_HEADER
Definition: av1.h:32
OFFSET
#define OFFSET(x)
Definition: remove_extradata.c:230
ff_av1_extract_obu
int ff_av1_extract_obu(AV1OBU *obu, const uint8_t *buf, int length, void *logctx)
Extract an OBU from a raw bitstream.
Definition: av1_parse.c:29
pkt
AVPacket * pkt
Definition: movenc.c:59
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
s
#define s(width, name)
Definition: cbs_vp9.c:198
vc1_split
static int vc1_split(const uint8_t *buf, int buf_size)
Definition: remove_extradata.c:164
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
REMOVE_FREQ_ALL
@ REMOVE_FREQ_ALL
Definition: remove_extradata.c:34
AV_CODEC_ID_AVS3
@ AV_CODEC_ID_AVS3
Definition: codec_id.h:248
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
FFBitStreamFilter
Definition: bsf_internal.h:27
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
HEVC_NAL_PPS
@ HEVC_NAL_PPS
Definition: hevc.h:63
h264_split
static int h264_split(const uint8_t *buf, int buf_size)
Definition: remove_extradata.c:66
VC1_CODE_SEQHDR
@ VC1_CODE_SEQHDR
Definition: vc1_common.h:40
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
IS_MARKER
#define IS_MARKER(state)
Definition: dca_parser.c:51
VC1_CODE_ENTRYPOINT
@ VC1_CODE_ENTRYPOINT
Definition: vc1_common.h:39
avpriv_find_start_code
const uint8_t * avpriv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state)
state
static struct @385 state
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
AV1_OBU_FRAME
@ AV1_OBU_FRAME
Definition: av1.h:35
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
REMOVE_FREQ_NONKEYFRAME
@ REMOVE_FREQ_NONKEYFRAME
Definition: remove_extradata.c:35
AVPacket::size
int size
Definition: packet.h:523
FLAGS
#define FLAGS
Definition: remove_extradata.c:231
mpegvideo_split
static int mpegvideo_split(const uint8_t *buf, int buf_size)
Definition: remove_extradata.c:135
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:528
vc1_common.h
RemoveFreq
RemoveFreq
Definition: remove_extradata.c:32
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
H264_NAL_AUD
@ H264_NAL_AUD
Definition: h264.h:43
AV_CODEC_ID_CAVS
@ AV_CODEC_ID_CAVS
Definition: codec_id.h:139
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
len
int len
Definition: vorbis_enc_data.h:426
HEVC_NAL_VPS
@ HEVC_NAL_VPS
Definition: hevc.h:61
ret
ret
Definition: filter_design.txt:187
H264_NAL_SEI
@ H264_NAL_SEI
Definition: h264.h:40
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
HEVC_NAL_AUD
@ HEVC_NAL_AUD
Definition: hevc.h:64
options
static const AVOption options[]
Definition: remove_extradata.c:232
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
mpeg4video_split
static int mpeg4video_split(const uint8_t *buf, int buf_size)
Definition: remove_extradata.c:150
RemoveExtradataContext::freq
int freq
Definition: remove_extradata.c:42
AV1OBU::type
int type
Definition: av1_parse.h:53
hevc_split
static int hevc_split(const uint8_t *buf, int buf_size)
Definition: remove_extradata.c:103
HEVC_NAL_SPS
@ HEVC_NAL_SPS
Definition: hevc.h:62
AVPacket
This structure stores compressed data.
Definition: packet.h:499
h264.h
ff_bsf_get_packet_ref
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:256
H264_NAL_SPS_EXT
@ H264_NAL_SPS_EXT
Definition: h264.h:47
REMOVE_FREQ_KEYFRAME
@ REMOVE_FREQ_KEYFRAME
Definition: remove_extradata.c:33
START_CODE
#define START_CODE
Definition: remove_extradata.c:38
HEVC_NAL_SEI_PREFIX
@ HEVC_NAL_SEI_PREFIX
Definition: hevc.h:68
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1283
remove_extradata
static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt)
Definition: remove_extradata.c:181