FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
h264_mp4toannexb_bsf.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/intreadwrite.h"
25 #include "libavutil/mem.h"
26 
27 #include "avcodec.h"
28 #include "bsf.h"
29 #include "h264.h"
30 
31 typedef struct H264BSFContext {
40 
42  const uint8_t *sps_pps, uint32_t sps_pps_size,
43  const uint8_t *in, uint32_t in_size, int ps)
44 {
45  uint32_t offset = out->size;
46  uint8_t start_code_size = offset == 0 || ps ? 4 : 3;
47  int err;
48 
49  err = av_grow_packet(out, sps_pps_size + in_size + start_code_size);
50  if (err < 0)
51  return err;
52 
53  if (sps_pps)
54  memcpy(out->data + offset, sps_pps, sps_pps_size);
55  memcpy(out->data + sps_pps_size + start_code_size + offset, in, in_size);
56  if (start_code_size == 4) {
57  AV_WB32(out->data + offset + sps_pps_size, 1);
58  } else {
59  (out->data + offset + sps_pps_size)[0] =
60  (out->data + offset + sps_pps_size)[1] = 0;
61  (out->data + offset + sps_pps_size)[2] = 1;
62  }
63 
64  return 0;
65 }
66 
67 static int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding)
68 {
69  H264BSFContext *s = ctx->priv_data;
70  uint16_t unit_size;
71  uint64_t total_size = 0;
72  uint8_t *out = NULL, unit_nb, sps_done = 0,
73  sps_seen = 0, pps_seen = 0;
74  const uint8_t *extradata = ctx->par_in->extradata + 4;
75  static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
76  int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
77 
78  s->sps_offset = s->pps_offset = -1;
79 
80  /* retrieve sps and pps unit(s) */
81  unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
82  if (!unit_nb) {
83  goto pps;
84  } else {
85  s->sps_offset = 0;
86  sps_seen = 1;
87  }
88 
89  while (unit_nb--) {
90  int err;
91 
92  unit_size = AV_RB16(extradata);
93  total_size += unit_size + 4;
94  if (total_size > INT_MAX - padding) {
95  av_log(ctx, AV_LOG_ERROR,
96  "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n");
97  av_free(out);
98  return AVERROR(EINVAL);
99  }
100  if (extradata + 2 + unit_size > ctx->par_in->extradata + ctx->par_in->extradata_size) {
101  av_log(ctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, "
102  "corrupted stream or invalid MP4/AVCC bitstream\n");
103  av_free(out);
104  return AVERROR(EINVAL);
105  }
106  if ((err = av_reallocp(&out, total_size + padding)) < 0)
107  return err;
108  memcpy(out + total_size - unit_size - 4, nalu_header, 4);
109  memcpy(out + total_size - unit_size, extradata + 2, unit_size);
110  extradata += 2 + unit_size;
111 pps:
112  if (!unit_nb && !sps_done++) {
113  unit_nb = *extradata++; /* number of pps unit(s) */
114  if (unit_nb) {
115  s->pps_offset = total_size;
116  pps_seen = 1;
117  }
118  }
119  }
120 
121  if (out)
122  memset(out + total_size, 0, padding);
123 
124  if (!sps_seen)
125  av_log(ctx, AV_LOG_WARNING,
126  "Warning: SPS NALU missing or invalid. "
127  "The resulting stream may not play.\n");
128 
129  if (!pps_seen)
130  av_log(ctx, AV_LOG_WARNING,
131  "Warning: PPS NALU missing or invalid. "
132  "The resulting stream may not play.\n");
133 
134  av_freep(&ctx->par_out->extradata);
135  ctx->par_out->extradata = out;
136  ctx->par_out->extradata_size = total_size;
137 
138  return length_size;
139 }
140 
142 {
143  H264BSFContext *s = ctx->priv_data;
144  int extra_size = ctx->par_in->extradata_size;
145  int ret;
146 
147  /* retrieve sps and pps NAL units from extradata */
148  if (!extra_size ||
149  (extra_size >= 3 && AV_RB24(ctx->par_in->extradata) == 1) ||
150  (extra_size >= 4 && AV_RB32(ctx->par_in->extradata) == 1)) {
151  av_log(ctx, AV_LOG_VERBOSE,
152  "The input looks like it is Annex B already\n");
153  } else if (extra_size >= 6) {
155  if (ret < 0)
156  return ret;
157 
158  s->length_size = ret;
159  s->new_idr = 1;
160  s->idr_sps_seen = 0;
161  s->idr_pps_seen = 0;
162  s->extradata_parsed = 1;
163  } else {
164  av_log(ctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extra_size);
165  return AVERROR_INVALIDDATA;
166  }
167 
168  return 0;
169 }
170 
172 {
173  H264BSFContext *s = ctx->priv_data;
174 
175  AVPacket *in;
176  uint8_t unit_type;
177  int32_t nal_size;
178  uint32_t cumul_size = 0;
179  const uint8_t *buf;
180  const uint8_t *buf_end;
181  int buf_size;
182  int ret = 0, i;
183 
184  ret = ff_bsf_get_packet(ctx, &in);
185  if (ret < 0)
186  return ret;
187 
188  /* nothing to filter */
189  if (!s->extradata_parsed) {
190  av_packet_move_ref(out, in);
191  av_packet_free(&in);
192  return 0;
193  }
194 
195  buf = in->data;
196  buf_size = in->size;
197  buf_end = in->data + in->size;
198 
199  do {
200  ret= AVERROR(EINVAL);
201  if (buf + s->length_size > buf_end)
202  goto fail;
203 
204  for (nal_size = 0, i = 0; i<s->length_size; i++)
205  nal_size = (nal_size << 8) | buf[i];
206 
207  buf += s->length_size;
208  unit_type = *buf & 0x1f;
209 
210  if (nal_size > buf_end - buf || nal_size < 0)
211  goto fail;
212 
213  if (unit_type == H264_NAL_SPS)
214  s->idr_sps_seen = s->new_idr = 1;
215  else if (unit_type == H264_NAL_PPS) {
216  s->idr_pps_seen = s->new_idr = 1;
217  /* if SPS has not been seen yet, prepend the AVCC one to PPS */
218  if (!s->idr_sps_seen) {
219  if (s->sps_offset == -1)
220  av_log(ctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n");
221  else {
222  if ((ret = alloc_and_copy(out,
223  ctx->par_out->extradata + s->sps_offset,
224  s->pps_offset != -1 ? s->pps_offset : ctx->par_out->extradata_size - s->sps_offset,
225  buf, nal_size, 1)) < 0)
226  goto fail;
227  s->idr_sps_seen = 1;
228  goto next_nal;
229  }
230  }
231  }
232 
233  /* if this is a new IDR picture following an IDR picture, reset the idr flag.
234  * Just check first_mb_in_slice to be 0 as this is the simplest solution.
235  * This could be checking idr_pic_id instead, but would complexify the parsing. */
236  if (!s->new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
237  s->new_idr = 1;
238 
239  /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */
240  if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && !s->idr_sps_seen && !s->idr_pps_seen) {
241  if ((ret=alloc_and_copy(out,
243  buf, nal_size, 1)) < 0)
244  goto fail;
245  s->new_idr = 0;
246  /* if only SPS has been seen, also insert PPS */
247  } else if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && s->idr_sps_seen && !s->idr_pps_seen) {
248  if (s->pps_offset == -1) {
249  av_log(ctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n");
250  if ((ret = alloc_and_copy(out, NULL, 0, buf, nal_size, 0)) < 0)
251  goto fail;
252  } else if ((ret = alloc_and_copy(out,
254  buf, nal_size, 1)) < 0)
255  goto fail;
256  } else {
257  if ((ret=alloc_and_copy(out, NULL, 0, buf, nal_size, unit_type == H264_NAL_SPS || unit_type == H264_NAL_PPS)) < 0)
258  goto fail;
259  if (!s->new_idr && unit_type == H264_NAL_SLICE) {
260  s->new_idr = 1;
261  s->idr_sps_seen = 0;
262  s->idr_pps_seen = 0;
263  }
264  }
265 
266 next_nal:
267  buf += nal_size;
268  cumul_size += nal_size + s->length_size;
269  } while (cumul_size < buf_size);
270 
271  ret = av_packet_copy_props(out, in);
272  if (ret < 0)
273  goto fail;
274 
275 fail:
276  if (ret < 0)
277  av_packet_unref(out);
278  av_packet_free(&in);
279 
280  return ret;
281 }
282 
284 {
285  H264BSFContext *s = ctx->priv_data;
286 
287  s->idr_sps_seen = 0;
288  s->idr_pps_seen = 0;
289  s->new_idr = s->extradata_parsed;
290 }
291 
292 static const enum AVCodecID codec_ids[] = {
294 };
295 
297  .name = "h264_mp4toannexb",
298  .priv_data_size = sizeof(H264BSFContext),
302  .codec_ids = codec_ids,
303 };
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5736
static void flush(AVCodecContext *avctx)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Memory handling functions.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
The bitstream filter state.
Definition: avcodec.h:5702
int size
Definition: avcodec.h:1445
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:87
static int h264_mp4toannexb_init(AVBSFContext *ctx)
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5723
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhd.c:153
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:62
uint8_t
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
const char * name
Definition: avcodec.h:5752
uint8_t * data
Definition: avcodec.h:1444
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:647
static int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding)
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define av_log(a,...)
H.264 common definitions.
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
static void h264_mp4toannexb_flush(AVBSFContext *ctx)
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
#define fail()
Definition: checkasm.h:117
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3917
int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
Copy only "properties" fields from src to dst.
Definition: avpacket.c:558
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
static int alloc_and_copy(AVPacket *out, const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size, int ps)
static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
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:163
Libavcodec external API header.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:592
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
void * buf
Definition: avisynth_c.h:690
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
static enum AVCodecID codec_ids[]
int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
Called by the bitstream filters to get the next packet for filtering.
Definition: bsf.c:216
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition: avpacket.c:109
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:781
const AVBitStreamFilter ff_h264_mp4toannexb_bsf
#define av_free(p)
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3913
FILE * out
Definition: movenc.c:54
#define av_freep(p)
This structure stores compressed data.
Definition: avcodec.h:1421
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5730