FFmpeg
Loading...
Searching...
No Matches
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
31static 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
68const 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
74static int nal_parse_units(AVIOContext *pb, NALUList *list,
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 size_t nalu_size = nal_end - nal_start;
91 while (nalu_size > 0 && nal_start[nalu_size - 1] == 0)
92 --nalu_size;
93 if (pb) {
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 {
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 = nalu_size };
106 }
107 size += 4 + nalu_size;
108 nal_start = nal_end;
109 }
110 return size;
111}
112
113int 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
118int 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
133int 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
146const 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
163uint8_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
190
191 *dst_len = len;
192 return dst;
193}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
Buffered I/O operations.
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1410
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition aviobuf.c:1365
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
Misc types and constants that do not belong anywhere else.
error code definitions
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AVERROR(e)
Definition error.h:45
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:495
int a
Memory handling functions.
void ff_nal_units_write_list(const NALUList *list, AVIOContext *pb, const uint8_t *buf)
Definition nal.c:124
int ff_nal_parse_units(AVIOContext *pb, const uint8_t *buf_in, int size)
Definition nal.c:113
int ff_nal_parse_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
Definition nal.c:133
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
static int nal_parse_units(AVIOContext *pb, NALUList *list, const uint8_t *buf_in, int size)
Definition nal.c:74
int ff_nal_units_create_list(NALUList *list, const uint8_t *buf, int size)
Definition nal.c:118
const uint8_t * ff_nal_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
Definition nal.c:146
const uint8_t * ff_nal_find_startcode(const uint8_t *p, const uint8_t *end)
Definition nal.c:68
static const uint8_t * nal_find_startcode_internal(const uint8_t *p, const uint8_t *end)
Definition nal.c:31
#define av_malloc(s)
Definition ops_static.c:52
Bytestream IO Context.
Definition avio.h:160
Definition evc.c:73
unsigned nb_nalus
valid entries in nalus
Definition evc.c:76
unsigned nalus_array_size
Definition evc.c:75
NALU * nalus
Definition evc.c:74
Definition evc.c:68
int offset
Definition evc.c:69
uint32_t size
Definition evc.c:70
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
int size
int len