2 * Copyright (c) 2007 Benoit Fouet <benoit.fouet@purplelabs.com>
4 * This file is part of FFmpeg.
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.
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.
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
23 typedef struct H264BSFContext
{
26 uint8_t *sps_pps_data
;
30 static void alloc_and_copy(uint8_t **poutbuf
, int *poutbuf_size
,
31 const uint8_t *sps_pps
, uint32_t sps_pps_size
,
32 const uint8_t *in
, uint32_t in_size
) {
33 uint32_t offset
= *poutbuf_size
;
34 uint8_t nal_header_size
= offset
? 3 : 4;
36 *poutbuf_size
+= sps_pps_size
+in_size
+nal_header_size
;
37 *poutbuf
= av_realloc(*poutbuf
, *poutbuf_size
);
39 memcpy(*poutbuf
+offset
, sps_pps
, sps_pps_size
);
40 memcpy(*poutbuf
+sps_pps_size
+nal_header_size
+offset
, in
, in_size
);
42 AV_WB32(*poutbuf
+sps_pps_size
, 1);
44 (*poutbuf
+offset
+sps_pps_size
)[0] = (*poutbuf
+offset
+sps_pps_size
)[1] = 0;
45 (*poutbuf
+offset
+sps_pps_size
)[2] = 1;
49 static int h264_mp4toannexb_filter(AVBitStreamFilterContext
*bsfc
,
50 AVCodecContext
*avctx
, const char *args
,
51 uint8_t **poutbuf
, int *poutbuf_size
,
52 const uint8_t *buf
, int buf_size
,
54 H264BSFContext
*ctx
= bsfc
->priv_data
;
56 uint32_t nal_size
, cumul_size
= 0;
58 /* nothing to filter */
59 if (!avctx
->extradata
|| avctx
->extradata_size
< 6) {
60 *poutbuf
= (uint8_t*) buf
;
61 *poutbuf_size
= buf_size
;
65 /* retrieve sps and pps NAL units from extradata */
66 if (!ctx
->sps_pps_data
) {
68 uint32_t total_size
= 0;
69 uint8_t *out
= NULL
, unit_nb
, sps_done
= 0;
70 const uint8_t *extradata
= avctx
->extradata
+4;
71 static const uint8_t nalu_header
[4] = {0, 0, 0, 1};
73 /* retrieve length coded size */
74 ctx
->length_size
= (*extradata
++ & 0x3) + 1;
75 if (ctx
->length_size
== 3)
76 return AVERROR(EINVAL
);
78 /* retrieve sps and pps unit(s) */
79 unit_nb
= *extradata
++ & 0x1f; /* number of sps unit(s) */
81 unit_nb
= *extradata
++; /* number of pps unit(s) */
85 unit_size
= AV_RB16(extradata
);
86 total_size
+= unit_size
+4;
87 if (extradata
+2+unit_size
> avctx
->extradata
+avctx
->extradata_size
) {
89 return AVERROR(EINVAL
);
91 out
= av_realloc(out
, total_size
);
93 return AVERROR(ENOMEM
);
94 memcpy(out
+total_size
-unit_size
-4, nalu_header
, 4);
95 memcpy(out
+total_size
-unit_size
, extradata
+2, unit_size
);
96 extradata
+= 2+unit_size
;
98 if (!unit_nb
&& !sps_done
++)
99 unit_nb
= *extradata
++; /* number of pps unit(s) */
102 ctx
->sps_pps_data
= out
;
103 ctx
->size
= total_size
;
110 if (ctx
->length_size
== 1)
112 else if (ctx
->length_size
== 2)
113 nal_size
= AV_RB16(buf
);
115 nal_size
= AV_RB32(buf
);
117 buf
+= ctx
->length_size
;
118 unit_type
= *buf
& 0x1f;
120 /* prepend only to the first type 5 NAL unit of an IDR picture */
121 if (ctx
->first_idr
&& unit_type
== 5) {
122 alloc_and_copy(poutbuf
, poutbuf_size
,
123 ctx
->sps_pps_data
, ctx
->size
,
128 alloc_and_copy(poutbuf
, poutbuf_size
,
131 if (!ctx
->first_idr
&& unit_type
== 1)
136 cumul_size
+= nal_size
+ ctx
->length_size
;
137 } while (cumul_size
< buf_size
);
142 static void h264_mp4toannexb_close(AVBitStreamFilterContext
*bsfc
)
144 H264BSFContext
*ctx
= bsfc
->priv_data
;
145 av_freep(&ctx
->sps_pps_data
);
148 AVBitStreamFilter h264_mp4toannexb_bsf
= {
150 sizeof(H264BSFContext
),
151 h264_mp4toannexb_filter
,
152 h264_mp4toannexb_close
,