FFmpeg
Loading...
Searching...
No Matches
h264_mp4toannexb.c
Go to the documentation of this file.
1/*
2 * H.264 MP4 to Annex B byte stream format filter
3 * Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <string.h>
23
24#include "libavutil/avassert.h"
26#include "libavutil/mem.h"
27
28#include "libavcodec/bsf.h"
31#include "libavcodec/defs.h"
32#include "libavcodec/h264.h"
33#include "libavcodec/sei.h"
34
35typedef struct H264BSFContext {
36 uint8_t *sps;
37 uint8_t *pps;
40 unsigned sps_buf_size;
41 unsigned pps_buf_size;
42 uint8_t length_size;
43 uint8_t new_idr;
44 uint8_t idr_sps_seen;
45 uint8_t idr_pps_seen;
48
54
55static void count_or_copy(uint8_t **out, uint64_t *out_size,
56 const uint8_t *in, int in_size, enum PsSource ps, int copy)
57{
58 uint8_t start_code_size;
59
60 if (ps == PS_OUT_OF_BAND)
61 /* start code already present in out-of-band ps data, so don't need to
62 * add it manually again
63 */
64 start_code_size = 0;
65 else if (ps == PS_IN_BAND || *out_size == 0)
66 start_code_size = 4;
67 else
68 start_code_size = 3;
69
70 if (copy) {
71 memcpy(*out + start_code_size, in, in_size);
72 if (start_code_size == 4) {
73 AV_WB32(*out, 1);
74 } else if (start_code_size) {
75 (*out)[0] =
76 (*out)[1] = 0;
77 (*out)[2] = 1;
78 }
79 *out += start_code_size + in_size;
80 }
81 *out_size += start_code_size + in_size;
82}
83
85 const uint8_t *extradata, int extradata_size,
86 uint8_t **out_extradata, int *out_extradata_size)
87{
88 H264BSFContext *s = ctx->priv_data;
89 GetByteContext ogb, *gb = &ogb;
90 uint16_t unit_size;
91 uint32_t total_size = 0;
92 uint8_t *out = NULL, unit_nb, sps_done = 0;
93 static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
94 const int padding = AV_INPUT_BUFFER_PADDING_SIZE;
95 int length_size, pps_offset = 0;
96
97 if (extradata_size < 7) {
98 av_log(ctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extradata_size);
100 }
101
102 bytestream2_init(gb, extradata, extradata_size);
103
104 bytestream2_skipu(gb, 4);
105
106 /* retrieve length coded size */
107 length_size = (bytestream2_get_byteu(gb) & 0x3) + 1;
108
109 /* retrieve sps and pps unit(s) */
110 unit_nb = bytestream2_get_byteu(gb) & 0x1f; /* number of sps unit(s) */
111 if (!unit_nb) {
112 goto pps;
113 }
114
115 while (unit_nb--) {
116 int err;
117
118 /* possible overread ok due to padding */
119 unit_size = bytestream2_get_be16u(gb);
120 total_size += unit_size + 4;
121 av_assert1(total_size <= INT_MAX - padding);
122 if (bytestream2_get_bytes_left(gb) < unit_size + !sps_done) {
123 av_log(ctx, AV_LOG_ERROR, "Global extradata truncated, "
124 "corrupted stream or invalid MP4/AVCC bitstream\n");
125 av_free(out);
126 return AVERROR_INVALIDDATA;
127 }
128 if ((err = av_reallocp(&out, total_size + padding)) < 0)
129 return err;
130 memcpy(out + total_size - unit_size - 4, nalu_header, 4);
131 bytestream2_get_bufferu(gb, out + total_size - unit_size, unit_size);
132pps:
133 if (!unit_nb && !sps_done++) {
134 unit_nb = bytestream2_get_byteu(gb); /* number of pps unit(s) */
135 pps_offset = total_size;
136 }
137 }
138
139 if (out)
140 memset(out + total_size, 0, padding);
141
142 if (pps_offset) {
143 uint8_t *sps;
144
145 s->sps_size = pps_offset;
146 sps = av_fast_realloc(s->sps, &s->sps_buf_size, s->sps_size);
147 if (!sps) {
148 av_free(out);
149 return AVERROR(ENOMEM);
150 }
151 s->sps = sps;
152 memcpy(s->sps, out, s->sps_size);
153 } else {
155 "Warning: SPS NALU missing or invalid. "
156 "The resulting stream may not play.\n");
157 }
158 if (pps_offset < total_size) {
159 uint8_t *pps;
160
161 s->pps_size = total_size - pps_offset;
162 pps = av_fast_realloc(s->pps, &s->pps_buf_size, s->pps_size);
163 if (!pps) {
164 av_freep(&s->sps);
165 av_free(out);
166 return AVERROR(ENOMEM);
167 }
168 s->pps = pps;
169 memcpy(s->pps, out + pps_offset, s->pps_size);
170 } else {
172 "Warning: PPS NALU missing or invalid. "
173 "The resulting stream may not play.\n");
174 }
175
176 if (out_extradata && out_extradata_size) {
177 av_freep(out_extradata);
178 *out_extradata = out;
179 *out_extradata_size = total_size;
180 } else
181 av_freep(&out);
182
183 s->length_size = length_size;
184 s->new_idr = 1;
185 s->idr_sps_seen = 0;
186 s->idr_pps_seen = 0;
187 s->extradata_parsed = 1;
188
189 return 0;
190}
191
192static int h264_mp4toannexb_save_ps(uint8_t **dst, int *dst_size,
193 unsigned *dst_buf_size,
194 const uint8_t *nal, uint32_t nal_size,
195 int first)
196{
197 static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
198 const int start_code_size = sizeof(nalu_header);
199 uint8_t *ptr;
200 uint32_t size;
201
202 if (first)
203 size = 0;
204 else
205 size = *dst_size;
206
207 ptr = av_fast_realloc(*dst, dst_buf_size, size + nal_size + start_code_size);
208 if (!ptr)
209 return AVERROR(ENOMEM);
210
211 memcpy(ptr + size, nalu_header, start_code_size);
212 size += start_code_size;
213 memcpy(ptr + size, nal, nal_size);
214 size += nal_size;
215
216 *dst = ptr;
217 *dst_size = size;
218 return 0;
219}
220
222 const uint8_t *buf,
223 const uint8_t *buf_end)
224{
225 int sps_count = 0;
226 int pps_count = 0;
227 uint8_t unit_type;
228
229 do {
230 uint32_t nal_size = 0;
231
232 /* possible overread ok due to padding */
233 for (int i = 0; i < s->length_size; i++)
234 nal_size = (nal_size << 8) | buf[i];
235
236 buf += s->length_size;
237
238 /* This check requires the cast as the right side might
239 * otherwise be promoted to an unsigned value. */
240 if ((int64_t)nal_size > buf_end - buf)
241 return AVERROR_INVALIDDATA;
242
243 if (!nal_size)
244 continue;
245
246 unit_type = *buf & 0x1f;
247
248 if (unit_type == H264_NAL_SPS) {
249 h264_mp4toannexb_save_ps(&s->sps, &s->sps_size, &s->sps_buf_size, buf,
250 nal_size, !sps_count);
251 sps_count++;
252 } else if (unit_type == H264_NAL_PPS) {
253 h264_mp4toannexb_save_ps(&s->pps, &s->pps_size, &s->pps_buf_size, buf,
254 nal_size, !pps_count);
255 pps_count++;
256 }
257
258 buf += nal_size;
259 } while (buf < buf_end);
260
261 return 0;
262}
263
265{
266 int extra_size = ctx->par_in->extradata_size;
267
268 /* retrieve sps and pps NAL units from extradata */
269 if (!extra_size ||
270 (extra_size >= 3 && AV_RB24(ctx->par_in->extradata) == 1) ||
271 (extra_size >= 4 && AV_RB32(ctx->par_in->extradata) == 1)) {
273 "The input looks like it is Annex B already\n");
274 return 0;
275 }
277 ctx->par_in->extradata,
278 ctx->par_in->extradata_size,
279 &ctx->par_out->extradata,
280 &ctx->par_out->extradata_size);
281}
282
284{
285 H264BSFContext *s = ctx->priv_data;
286 AVPacket *in;
287 uint8_t unit_type, new_idr, sps_seen, pps_seen;
288 const uint8_t *buf;
289 const uint8_t *buf_end;
290 uint8_t *out;
291 uint64_t out_size;
292 int ret;
293 size_t extradata_size;
294 uint8_t *extradata;
295
296 ret = ff_bsf_get_packet(ctx, &in);
297 if (ret < 0)
298 return ret;
299
301 &extradata_size);
302 if (extradata && extradata[0] == 1) {
303 ret = h264_extradata_to_annexb(ctx, extradata, extradata_size, NULL, NULL);
304 if (ret < 0)
305 goto fail;
308 }
309
310 /* nothing to filter */
311 if (!s->extradata_parsed) {
312 av_packet_move_ref(opkt, in);
313 av_packet_free(&in);
314 return 0;
315 }
316
317 buf_end = in->data + in->size;
318 ret = h264_mp4toannexb_filter_ps(s, in->data, buf_end);
319 if (ret < 0)
320 goto fail;
321
322#define LOG_ONCE(...) \
323 if (j) \
324 av_log(__VA_ARGS__)
325 for (int j = 0; j < 2; j++) {
326 buf = in->data;
327 new_idr = s->new_idr;
328 sps_seen = s->idr_sps_seen;
329 pps_seen = s->idr_pps_seen;
330 out_size = 0;
331
332 do {
333 uint32_t nal_size = 0;
334 enum PsSource ps;
335
336 /* possible overread ok due to padding */
337 for (int i = 0; i < s->length_size; i++)
338 nal_size = (nal_size << 8) | buf[i];
339
340 buf += s->length_size;
341
342 /* This check requires the cast as the right side might
343 * otherwise be promoted to an unsigned value. */
344 if ((int64_t)nal_size > buf_end - buf) {
346 goto fail;
347 }
348
349 if (!nal_size)
350 continue;
351
352 unit_type = *buf & 0x1f;
353
354 if (unit_type == H264_NAL_SPS) {
355 sps_seen = new_idr = 1;
356 } else if (unit_type == H264_NAL_PPS) {
357 pps_seen = new_idr = 1;
358 /* if SPS has not been seen yet, prepend the AVCC one to PPS */
359 if (!sps_seen) {
360 if (!s->sps_size) {
361 LOG_ONCE(ctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n");
362 } else {
363 count_or_copy(&out, &out_size, s->sps, s->sps_size, PS_OUT_OF_BAND, j);
364 sps_seen = 1;
365 }
366 }
367 }
368
369 /* If this is a new IDR picture following an IDR picture, reset the idr flag.
370 * Just check first_mb_in_slice to be 0 as this is the simplest solution.
371 * This could be checking idr_pic_id instead, but would complexify the parsing. */
372 if (!new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
373 new_idr = 1;
374
375 /* If this is a buffering period SEI without a corresponding sps/pps
376 * then prepend any existing sps/pps before the SEI */
377 if (unit_type == H264_NAL_SEI && buf[1] == SEI_TYPE_BUFFERING_PERIOD &&
378 !sps_seen && !pps_seen) {
379 if (s->sps_size) {
380 count_or_copy(&out, &out_size, s->sps, s->sps_size, PS_OUT_OF_BAND, j);
381 sps_seen = 1;
382 }
383 if (s->pps_size) {
384 count_or_copy(&out, &out_size, s->pps, s->pps_size, PS_OUT_OF_BAND, j);
385 pps_seen = 1;
386 }
387 }
388
389 /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
390 if (new_idr && unit_type == H264_NAL_IDR_SLICE && !sps_seen && !pps_seen) {
391 if (s->sps_size)
392 count_or_copy(&out, &out_size, s->sps, s->sps_size, PS_OUT_OF_BAND, j);
393 if (s->pps_size)
394 count_or_copy(&out, &out_size, s->pps, s->pps_size, PS_OUT_OF_BAND, j);
395 new_idr = 0;
396 /* if only SPS has been seen, also insert PPS */
397 } else if (new_idr && unit_type == H264_NAL_IDR_SLICE && sps_seen && !pps_seen) {
398 if (!s->pps_size) {
399 LOG_ONCE(ctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n");
400 } else {
401 count_or_copy(&out, &out_size, s->pps, s->pps_size, PS_OUT_OF_BAND, j);
402 }
403 }
404
405 if (unit_type == H264_NAL_SPS || unit_type == H264_NAL_PPS)
406 ps = PS_IN_BAND;
407 else
408 ps = PS_NONE;
409 count_or_copy(&out, &out_size, buf, nal_size, ps, j);
410 if (unit_type == H264_NAL_SLICE) {
411 new_idr = 1;
412 sps_seen = 0;
413 pps_seen = 0;
414 }
415
416 buf += nal_size;
417 } while (buf < buf_end);
418
419 if (!j) {
420 if (out_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
422 goto fail;
423 }
424 ret = av_new_packet(opkt, out_size);
425 if (ret < 0)
426 goto fail;
427 out = opkt->data;
428 }
429 }
430#undef LOG_ONCE
431
432 av_assert1(out_size == opkt->size);
433
434 s->new_idr = new_idr;
435 s->idr_sps_seen = sps_seen;
436 s->idr_pps_seen = pps_seen;
437
438 ret = av_packet_copy_props(opkt, in);
439 if (ret < 0)
440 goto fail;
441
442fail:
443 if (ret < 0)
444 av_packet_unref(opkt);
445 av_packet_free(&in);
446
447 return ret;
448}
449
451{
452 H264BSFContext *s = ctx->priv_data;
453
454 av_freep(&s->sps);
455 av_freep(&s->pps);
456}
457
459{
460 H264BSFContext *s = ctx->priv_data;
461
462 s->idr_sps_seen = 0;
463 s->idr_pps_seen = 0;
464 s->new_idr = s->extradata_parsed;
465}
466
467static const enum AVCodecID codec_ids[] = {
469};
470
472 .p.name = "h264_mp4toannexb",
473 .p.codec_ids = codec_ids,
474 .priv_data_size = sizeof(H264BSFContext),
479};
static enum AVCodecID codec_ids[]
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static FILE * out
static int out_size
static AVFormatContext * ctx
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
const FFBitStreamFilter ff_h264_mp4toannexb_bsf
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
Definition bsf.c:233
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition bytestream.h:174
static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:277
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC nal(CodedBitstreamContext *ctx, RWContext *rw, LCEVCRawNAL *current, int nal_unit_type)
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Misc types and constants that do not belong anywhere else.
uint64_t pps
Definition dovi_rpuenc.c:36
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define fail
Definition test.h:479
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
void av_packet_side_data_remove(AVPacketSideData *sd, int *pnb_sd, enum AVPacketSideDataType type)
Remove side data of the given type from a side data array.
Definition packet.c:642
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition packet.h:56
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition packet.c:491
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition packet.c:252
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
Copy only "properties" fields from src to dst.
Definition packet.c:397
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:188
H.264 common definitions.
@ H264_NAL_PPS
Definition h264.h:42
@ H264_NAL_SPS
Definition h264.h:41
@ H264_NAL_SLICE
Definition h264.h:35
@ H264_NAL_SEI
Definition h264.h:40
@ H264_NAL_IDR_SLICE
Definition h264.h:39
#define LOG_ONCE(...)
static void h264_mp4toannexb_flush(AVBSFContext *ctx)
static int h264_mp4toannexb_filter_ps(H264BSFContext *s, const uint8_t *buf, const uint8_t *buf_end)
static int h264_extradata_to_annexb(AVBSFContext *ctx, const uint8_t *extradata, int extradata_size, uint8_t **out_extradata, int *out_extradata_size)
@ PS_NONE
@ PS_OUT_OF_BAND
@ PS_IN_BAND
static int h264_mp4toannexb_save_ps(uint8_t **dst, int *dst_size, unsigned *dst_buf_size, const uint8_t *nal, uint32_t nal_size, int first)
static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *opkt)
static void h264_mp4toannexb_close(AVBSFContext *ctx)
static int h264_mp4toannexb_init(AVBSFContext *ctx)
static void count_or_copy(uint8_t **out, uint64_t *out_size, const uint8_t *in, int in_size, enum PsSource ps, int copy)
#define AV_WB32(p, v)
#define AV_RB32(p)
#define AV_RB24(x)
Memory handling functions.
@ SEI_TYPE_BUFFERING_PERIOD
Definition sei.h:30
The bitstream filter state.
Definition bsf.h:68
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
AVPacketSideData * side_data
Additional packet data that can be provided by the container.
Definition packet.h:614
int side_data_elems
Definition packet.h:615
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
int size
static void copy(const float *p1, float *p2, const int length)