FFmpeg
nal.c
Go to the documentation of this file.
1 /*
2  * NAL helper functions for muxers
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 <stdint.h>
22 #include <string.h>
23 
24 #include "libavutil/mem.h"
25 #include "libavutil/error.h"
26 #include "libavcodec/defs.h"
27 #include "avio.h"
28 #include "avio_internal.h"
29 #include "nal.h"
30 
31 static const uint8_t *nal_find_startcode_internal(const uint8_t *p, const uint8_t *end)
32 {
33  const uint8_t *a = p + 4 - ((intptr_t)p & 3);
34 
35  for (end -= 3; p < a && p < end; p++) {
36  if (p[0] == 0 && p[1] == 0 && p[2] == 1)
37  return p;
38  }
39 
40  for (end -= 3; p < end; p += 4) {
41  uint32_t x = *(const uint32_t*)p;
42 // if ((x - 0x01000100) & (~x) & 0x80008000) // little endian
43 // if ((x - 0x00010001) & (~x) & 0x00800080) // big endian
44  if ((x - 0x01010101) & (~x) & 0x80808080) { // generic
45  if (p[1] == 0) {
46  if (p[0] == 0 && p[2] == 1)
47  return p;
48  if (p[2] == 0 && p[3] == 1)
49  return p+1;
50  }
51  if (p[3] == 0) {
52  if (p[2] == 0 && p[4] == 1)
53  return p+2;
54  if (p[4] == 0 && p[5] == 1)
55  return p+3;
56  }
57  }
58  }
59 
60  for (end += 3; p < end; p++) {
61  if (p[0] == 0 && p[1] == 0 && p[2] == 1)
62  return p;
63  }
64 
65  return end + 3;
66 }
67 
68 const uint8_t *ff_nal_find_startcode(const uint8_t *p, const uint8_t *end){
69  const uint8_t *out = nal_find_startcode_internal(p, end);
70  if(p<out && out<end && !out[-1]) out--;
71  return out;
72 }
73 
75  const uint8_t *buf_in, int size)
76 {
77  const uint8_t *p = buf_in;
78  const uint8_t *end = p + size;
79  const uint8_t *nal_start, *nal_end;
80 
81  size = 0;
82  nal_start = ff_nal_find_startcode(p, end);
83  for (;;) {
84  const size_t nalu_limit = SIZE_MAX / sizeof(*list->nalus);
85  while (nal_start < end && !*(nal_start++));
86  if (nal_start == end)
87  break;
88 
89  nal_end = ff_nal_find_startcode(nal_start, end);
90  if (pb) {
91  avio_wb32(pb, nal_end - nal_start);
92  avio_write(pb, nal_start, nal_end - nal_start);
93  } else if (list->nb_nalus >= nalu_limit) {
94  return AVERROR(ERANGE);
95  } else {
96  NALU *tmp = av_fast_realloc(list->nalus, &list->nalus_array_size,
97  (list->nb_nalus + 1) * sizeof(*list->nalus));
98  if (!tmp)
99  return AVERROR(ENOMEM);
100  list->nalus = tmp;
101  tmp[list->nb_nalus++] = (NALU){ .offset = nal_start - p,
102  .size = nal_end - nal_start };
103  }
104  size += 4 + nal_end - nal_start;
105  nal_start = nal_end;
106  }
107  return size;
108 }
109 
110 int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
111 {
112  return nal_parse_units(pb, NULL, buf_in, size);
113 }
114 
115 int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size)
116 {
117  list->nb_nalus = 0;
118  return nal_parse_units(NULL, list, buf, size);
119 }
120 
122  const uint8_t *buf)
123 {
124  for (unsigned i = 0; i < list->nb_nalus; i++) {
125  avio_wb32(pb, list->nalus[i].size);
126  avio_write(pb, buf + list->nalus[i].offset, list->nalus[i].size);
127  }
128 }
129 
130 int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
131 {
132  AVIOContext *pb;
133  int ret = avio_open_dyn_buf(&pb);
134  if(ret < 0)
135  return ret;
136 
137  ff_nal_parse_units(pb, buf_in, *size);
138 
139  *size = avio_close_dyn_buf(pb, buf);
140  return 0;
141 }
142 
143 const uint8_t *ff_nal_mp4_find_startcode(const uint8_t *start,
144  const uint8_t *end,
145  int nal_length_size)
146 {
147  unsigned int res = 0;
148 
149  if (end - start < nal_length_size)
150  return NULL;
151  while (nal_length_size--)
152  res = (res << 8) | *start++;
153 
154  if (res > end - start)
155  return NULL;
156 
157  return start + res;
158 }
159 
160 uint8_t *ff_nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len,
161  uint32_t *dst_len, int header_len)
162 {
163  uint8_t *dst;
164  uint32_t i, len;
165 
167  if (!dst)
168  return NULL;
169 
170  /* NAL unit header */
171  i = len = 0;
172  while (i < header_len && i < src_len)
173  dst[len++] = src[i++];
174 
175  while (i + 2 < src_len)
176  if (!src[i] && !src[i + 1] && src[i + 2] == 3) {
177  dst[len++] = src[i++];
178  dst[len++] = src[i++];
179  i++; // remove emulation_prevention_three_byte
180  } else
181  dst[len++] = src[i++];
182 
183  while (i < src_len)
184  dst[len++] = src[i++];
185 
186  memset(dst + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
187 
188  *dst_len = len;
189  return dst;
190 }
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1407
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1362
ff_nal_mp4_find_startcode
const uint8_t * ff_nal_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
Definition: nal.c:143
av_fast_realloc
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:497
nal_find_startcode_internal
static const uint8_t * nal_find_startcode_internal(const uint8_t *p, const uint8_t *end)
Definition: nal.c:31
ff_nal_parse_units
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition: nal.c:110
NULL
#define NULL
Definition: coverity.c:32
ff_nal_unit_extract_rbsp
uint8_t * ff_nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len, uint32_t *dst_len, int header_len)
Definition: nal.c:160
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
error.h
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
ff_nal_parse_units_buf
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: nal.c:130
size
int size
Definition: twinvq_data.h:10344
avio.h
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
ff_nal_units_write_list
void ff_nal_units_write_list(const NALUList *list, AVIOContext *pb, const uint8_t *buf)
Definition: nal.c:121
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
avio_internal.h
NALU
Definition: evc.c:68
len
int len
Definition: vorbis_enc_data.h:426
nal.h
ret
ret
Definition: filter_design.txt:187
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
NALUList
Definition: evc.c:73
defs.h
mem.h
nal_parse_units
static int nal_parse_units(AVIOContext *pb, NALUList *list, const uint8_t *buf_in, int size)
Definition: nal.c:74
ff_nal_find_startcode
const uint8_t * ff_nal_find_startcode(const uint8_t *p, const uint8_t *end)
Definition: nal.c:68
ff_nal_units_create_list
int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size)
Definition: nal.c:115
src
#define src
Definition: vp8dsp.c:248