2 * H.264 MP4 to Annex B byte stream format filter
3 * Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr>
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
28 typedef struct H264BSFContext {
37 /* When private_spspps is zero then spspps_buf points to global extradata
38 and bsf does replace a global extradata to own-allocated version (default
40 When private_spspps is non-zero the bsf uses a private version of spspps buf.
41 This mode necessary when bsf uses in decoder, else bsf has issues after
42 decoder re-initialization. Use the "private_spspps_buf" argument to
50 static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size,
51 const uint8_t *sps_pps, uint32_t sps_pps_size,
52 const uint8_t *in, uint32_t in_size)
54 uint32_t offset = *poutbuf_size;
55 uint8_t nal_header_size = offset ? 3 : 4;
58 *poutbuf_size += sps_pps_size + in_size + nal_header_size;
59 if ((err = av_reallocp(poutbuf,
60 *poutbuf_size + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
65 memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
66 memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size);
68 AV_WB32(*poutbuf + sps_pps_size, 1);
70 (*poutbuf + offset + sps_pps_size)[0] =
71 (*poutbuf + offset + sps_pps_size)[1] = 0;
72 (*poutbuf + offset + sps_pps_size)[2] = 1;
78 static int h264_extradata_to_annexb(H264BSFContext *ctx, AVCodecContext *avctx, const int padding)
81 uint64_t total_size = 0;
82 uint8_t *out = NULL, unit_nb, sps_done = 0,
83 sps_seen = 0, pps_seen = 0;
84 const uint8_t *extradata = avctx->extradata + 4;
85 static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
86 int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
88 ctx->sps_offset = ctx->pps_offset = -1;
90 /* retrieve sps and pps unit(s) */
91 unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
102 unit_size = AV_RB16(extradata);
103 total_size += unit_size + 4;
104 if (total_size > INT_MAX - padding) {
105 av_log(avctx, AV_LOG_ERROR,
106 "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n");
108 return AVERROR(EINVAL);
110 if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) {
111 av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, "
112 "corrupted stream or invalid MP4/AVCC bitstream\n");
114 return AVERROR(EINVAL);
116 if ((err = av_reallocp(&out, total_size + padding)) < 0)
118 memcpy(out + total_size - unit_size - 4, nalu_header, 4);
119 memcpy(out + total_size - unit_size, extradata + 2, unit_size);
120 extradata += 2 + unit_size;
122 if (!unit_nb && !sps_done++) {
123 unit_nb = *extradata++; /* number of pps unit(s) */
125 ctx->pps_offset = total_size;
132 memset(out + total_size, 0, padding);
135 av_log(avctx, AV_LOG_WARNING,
136 "Warning: SPS NALU missing or invalid. "
137 "The resulting stream may not play.\n");
140 av_log(avctx, AV_LOG_WARNING,
141 "Warning: PPS NALU missing or invalid. "
142 "The resulting stream may not play.\n");
144 if (!ctx->private_spspps) {
145 av_free(avctx->extradata);
146 avctx->extradata = out;
147 avctx->extradata_size = total_size;
149 ctx->spspps_buf = out;
150 ctx->spspps_size = total_size;
155 static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
156 AVCodecContext *avctx, const char *args,
157 uint8_t **poutbuf, int *poutbuf_size,
158 const uint8_t *buf, int buf_size,
161 H264BSFContext *ctx = bsfc->priv_data;
165 uint32_t cumul_size = 0;
166 const uint8_t *buf_end = buf + buf_size;
169 /* nothing to filter */
170 if (!avctx->extradata || avctx->extradata_size < 6) {
171 *poutbuf = (uint8_t *)buf;
172 *poutbuf_size = buf_size;
176 /* retrieve sps and pps NAL units from extradata */
177 if (!ctx->extradata_parsed) {
178 if (args && strstr(args, "private_spspps_buf"))
179 ctx->private_spspps = 1;
181 ret = h264_extradata_to_annexb(ctx, avctx, AV_INPUT_BUFFER_PADDING_SIZE);
184 ctx->length_size = ret;
186 ctx->idr_sps_seen = 0;
187 ctx->idr_pps_seen = 0;
188 ctx->extradata_parsed = 1;
194 ret= AVERROR(EINVAL);
195 if (buf + ctx->length_size > buf_end)
198 for (nal_size = 0, i = 0; i<ctx->length_size; i++)
199 nal_size = (nal_size << 8) | buf[i];
201 buf += ctx->length_size;
202 unit_type = *buf & 0x1f;
204 if (nal_size > buf_end - buf || nal_size < 0)
208 ctx->idr_sps_seen = ctx->new_idr = 1;
209 else if (unit_type == 8) {
210 ctx->idr_pps_seen = ctx->new_idr = 1;
211 /* if SPS has not been seen yet, prepend the AVCC one to PPS */
212 if (!ctx->idr_sps_seen) {
213 if (ctx->sps_offset == -1)
214 av_log(avctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n");
216 if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
217 ctx->spspps_buf + ctx->sps_offset,
218 ctx->pps_offset != -1 ? ctx->pps_offset : ctx->spspps_size - ctx->sps_offset,
221 ctx->idr_sps_seen = 1;
227 /* if this is a new IDR picture following an IDR picture, reset the idr flag.
228 * Just check first_mb_in_slice to be 0 as this is the simplest solution.
229 * This could be checking idr_pic_id instead, but would complexify the parsing. */
230 if (!ctx->new_idr && unit_type == 5 && (buf[1] & 0x80))
233 /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
234 if (ctx->new_idr && unit_type == 5 && !ctx->idr_sps_seen && !ctx->idr_pps_seen) {
235 if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
236 ctx->spspps_buf, ctx->spspps_size,
240 /* if only SPS has been seen, also insert PPS */
241 } else if (ctx->new_idr && unit_type == 5 && ctx->idr_sps_seen && !ctx->idr_pps_seen) {
242 if (ctx->pps_offset == -1) {
243 av_log(avctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n");
244 if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
245 NULL, 0, buf, nal_size)) < 0)
247 } else if ((ret = alloc_and_copy(poutbuf, poutbuf_size,
248 ctx->spspps_buf + ctx->pps_offset, ctx->spspps_size - ctx->pps_offset,
252 if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
253 NULL, 0, buf, nal_size)) < 0)
255 if (!ctx->new_idr && unit_type == 1) {
257 ctx->idr_sps_seen = 0;
258 ctx->idr_pps_seen = 0;
264 cumul_size += nal_size + ctx->length_size;
265 } while (cumul_size < buf_size);
275 static void h264_mp4toannexb_filter_close(AVBitStreamFilterContext *bsfc)
277 H264BSFContext *ctx = bsfc->priv_data;
278 if (ctx->private_spspps)
279 av_freep(&ctx->spspps_buf);
282 AVBitStreamFilter ff_h264_mp4toannexb_bsf = {
283 .name = "h264_mp4toannexb",
284 .priv_data_size = sizeof(H264BSFContext),
285 .filter = h264_mp4toannexb_filter,
286 .close = h264_mp4toannexb_filter_close,