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  ptrdiff_t nalu_size = nal_end - nal_start;
92  while (nalu_size > 0 && nal_start[nalu_size - 1] == 0)
93  --nalu_size;
94  avio_wb32(pb, nalu_size);
95  avio_write(pb, nal_start, nalu_size);
96  } else if (list->nb_nalus >= nalu_limit) {
97  return AVERROR(ERANGE);
98  } else {
99  NALU *tmp = av_fast_realloc(list->nalus, &list->nalus_array_size,
100  (list->nb_nalus + 1) * sizeof(*list->nalus));
101  if (!tmp)
102  return AVERROR(ENOMEM);
103  list->nalus = tmp;
104  tmp[list->nb_nalus++] = (NALU){ .offset = nal_start - p,
105  .size = nal_end - nal_start };
106  }
107  size += 4 + nal_end - nal_start;
108  nal_start = nal_end;
109  }
110  return size;
111 }
112 
113 int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
114 {
115  return nal_parse_units(pb, NULL, buf_in, size);
116 }
117 
118 int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size)
119 {
120  list->nb_nalus = 0;
121  return nal_parse_units(NULL, list, buf, size);
122 }
123 
125  const uint8_t *buf)
126 {
127  for (unsigned i = 0; i < list->nb_nalus; i++) {
128  avio_wb32(pb, list->nalus[i].size);
129  avio_write(pb, buf + list->nalus[i].offset, list->nalus[i].size);
130  }
131 }
132 
133 int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
134 {
135  AVIOContext *pb;
136  int ret = avio_open_dyn_buf(&pb);
137  if(ret < 0)
138  return ret;
139 
140  ff_nal_parse_units(pb, buf_in, *size);
141 
142  *size = avio_close_dyn_buf(pb, buf);
143  return 0;
144 }
145 
146 const uint8_t *ff_nal_mp4_find_startcode(const uint8_t *start,
147  const uint8_t *end,
148  int nal_length_size)
149 {
150  unsigned int res = 0;
151 
152  if (end - start < nal_length_size)
153  return NULL;
154  while (nal_length_size--)
155  res = (res << 8) | *start++;
156 
157  if (res > end - start)
158  return NULL;
159 
160  return start + res;
161 }
162 
163 uint8_t *ff_nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len,
164  uint32_t *dst_len, int header_len)
165 {
166  uint8_t *dst;
167  uint32_t i, len;
168 
170  if (!dst)
171  return NULL;
172 
173  /* NAL unit header */
174  i = len = 0;
175  while (i < header_len && i < src_len)
176  dst[len++] = src[i++];
177 
178  while (i + 2 < src_len)
179  if (!src[i] && !src[i + 1] && src[i + 2] == 3) {
180  dst[len++] = src[i++];
181  dst[len++] = src[i++];
182  i++; // remove emulation_prevention_three_byte
183  } else
184  dst[len++] = src[i++];
185 
186  while (i < src_len)
187  dst[len++] = src[i++];
188 
189  memset(dst + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
190 
191  *dst_len = len;
192  return dst;
193 }
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
static FILE * out
Definition: movenc.c:55
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:1410
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1365
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:146
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:113
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
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:163
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:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
ff_nal_parse_units_buf
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition: nal.c:133
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:206
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:368
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:124
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
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
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
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:118
src
#define src
Definition: vp8dsp.c:248