FFmpeg
1.2.12
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
avpacket.c
Go to the documentation of this file.
1
/*
2
* AVPacket functions for libavcodec
3
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
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/avassert.h"
25
#include "libavutil/mem.h"
26
#include "
avcodec.h
"
27
#include "
bytestream.h
"
28
#include "
internal.h
"
29
30
void
ff_packet_free_side_data
(
AVPacket
*
pkt
)
31
{
32
int
i;
33
for
(i = 0; i < pkt->
side_data_elems
; i++)
34
av_free
(pkt->
side_data
[i].
data
);
35
av_freep
(&pkt->
side_data
);
36
pkt->
side_data_elems
= 0;
37
}
38
39
void
av_destruct_packet
(
AVPacket
*
pkt
)
40
{
41
av_free
(pkt->
data
);
42
pkt->
data
=
NULL
;
43
pkt->
size
= 0;
44
}
45
46
void
av_init_packet
(
AVPacket
*
pkt
)
47
{
48
pkt->
pts
=
AV_NOPTS_VALUE
;
49
pkt->
dts
=
AV_NOPTS_VALUE
;
50
pkt->
pos
= -1;
51
pkt->
duration
= 0;
52
pkt->
convergence_duration
= 0;
53
pkt->
flags
= 0;
54
pkt->
stream_index
= 0;
55
pkt->
destruct
=
NULL
;
56
pkt->
side_data
=
NULL
;
57
pkt->
side_data_elems
= 0;
58
}
59
60
int
av_new_packet
(
AVPacket
*
pkt
,
int
size
)
61
{
62
uint8_t
*
data
=
NULL
;
63
if
((
unsigned
)size < (
unsigned
)size +
FF_INPUT_BUFFER_PADDING_SIZE
)
64
data =
av_malloc
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
65
if
(data) {
66
memset(data + size, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
67
}
else
68
size = 0;
69
70
av_init_packet
(pkt);
71
pkt->
data
=
data
;
72
pkt->
size
=
size
;
73
pkt->
destruct
=
av_destruct_packet
;
74
if
(!data)
75
return
AVERROR
(ENOMEM);
76
return
0;
77
}
78
79
void
av_shrink_packet
(
AVPacket
*
pkt
,
int
size
)
80
{
81
if
(pkt->
size
<= size)
82
return
;
83
pkt->
size
=
size
;
84
memset(pkt->
data
+ size, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
85
}
86
87
int
av_grow_packet
(
AVPacket
*
pkt
,
int
grow_by)
88
{
89
void
*new_ptr;
90
av_assert0
((
unsigned
)pkt->
size
<= INT_MAX -
FF_INPUT_BUFFER_PADDING_SIZE
);
91
if
(!pkt->
size
)
92
return
av_new_packet
(pkt, grow_by);
93
if
((
unsigned
)grow_by >
94
INT_MAX - (pkt->
size
+
FF_INPUT_BUFFER_PADDING_SIZE
))
95
return
-1;
96
new_ptr =
av_realloc
(pkt->
data
,
97
pkt->
size
+ grow_by +
FF_INPUT_BUFFER_PADDING_SIZE
);
98
if
(!new_ptr)
99
return
AVERROR
(ENOMEM);
100
pkt->
data
= new_ptr;
101
pkt->
size
+= grow_by;
102
memset(pkt->
data
+ pkt->
size
, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
103
return
0;
104
}
105
106
#define DUP_DATA(dst, src, size, padding) \
107
do { \
108
void *data; \
109
if (padding) { \
110
if ((unsigned)(size) > \
111
(unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
112
goto failed_alloc; \
113
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
114
} else { \
115
data = av_malloc(size); \
116
} \
117
if (!data) \
118
goto failed_alloc; \
119
memcpy(data, src, size); \
120
if (padding) \
121
memset((uint8_t *)data + size, 0, \
122
FF_INPUT_BUFFER_PADDING_SIZE); \
123
dst = data; \
124
} while (0)
125
126
/* Makes duplicates of data, side_data, but does not copy any other fields */
127
static
int
copy_packet_data
(
AVPacket
*
dst
,
AVPacket
*src)
128
{
129
dst->
data
=
NULL
;
130
dst->
side_data
=
NULL
;
131
DUP_DATA
(dst->
data
, src->
data
, dst->
size
, 1);
132
dst->
destruct
=
av_destruct_packet
;
133
134
if
(dst->
side_data_elems
) {
135
int
i;
136
137
DUP_DATA
(dst->
side_data
, src->
side_data
,
138
dst->
side_data_elems
*
sizeof
(*dst->
side_data
), 0);
139
memset(dst->
side_data
, 0,
140
dst->
side_data_elems
*
sizeof
(*dst->
side_data
));
141
for
(i = 0; i < dst->
side_data_elems
; i++) {
142
DUP_DATA
(dst->
side_data
[i].
data
, src->
side_data
[i].
data
,
143
src->
side_data
[i].
size
, 1);
144
dst->
side_data
[i].
size
= src->
side_data
[i].
size
;
145
dst->
side_data
[i].
type
= src->
side_data
[i].
type
;
146
}
147
}
148
return
0;
149
150
failed_alloc:
151
av_destruct_packet
(dst);
152
return
AVERROR
(ENOMEM);
153
}
154
155
int
av_dup_packet
(
AVPacket
*
pkt
)
156
{
157
AVPacket
tmp_pkt;
158
159
if
(pkt->
destruct
==
NULL
&& pkt->
data
) {
160
tmp_pkt = *
pkt
;
161
return
copy_packet_data
(pkt, &tmp_pkt);
162
}
163
return
0;
164
}
165
166
int
av_copy_packet
(
AVPacket
*
dst
,
AVPacket
*src)
167
{
168
*dst = *src;
169
return
copy_packet_data
(dst, src);
170
}
171
172
void
av_free_packet
(
AVPacket
*
pkt
)
173
{
174
if
(pkt) {
175
int
i;
176
177
if
(pkt->
destruct
)
178
pkt->
destruct
(pkt);
179
pkt->
data
=
NULL
;
180
pkt->
size
= 0;
181
182
for
(i = 0; i < pkt->
side_data_elems
; i++)
183
av_free
(pkt->
side_data
[i].
data
);
184
av_freep
(&pkt->
side_data
);
185
pkt->
side_data_elems
= 0;
186
}
187
}
188
189
uint8_t
*
av_packet_new_side_data
(
AVPacket
*
pkt
,
enum
AVPacketSideDataType
type,
190
int
size
)
191
{
192
int
elems = pkt->
side_data_elems
;
193
194
if
((
unsigned
)elems + 1 > INT_MAX /
sizeof
(*pkt->
side_data
))
195
return
NULL
;
196
if
((
unsigned
)size > INT_MAX -
FF_INPUT_BUFFER_PADDING_SIZE
)
197
return
NULL
;
198
199
pkt->
side_data
=
av_realloc
(pkt->
side_data
,
200
(elems + 1) *
sizeof
(*pkt->
side_data
));
201
if
(!pkt->
side_data
)
202
return
NULL
;
203
204
pkt->
side_data
[elems].
data
=
av_malloc
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
205
if
(!pkt->
side_data
[elems].
data
)
206
return
NULL
;
207
pkt->
side_data
[elems].
size
=
size
;
208
pkt->
side_data
[elems].
type
= type;
209
pkt->
side_data_elems
++;
210
211
return
pkt->
side_data
[elems].
data
;
212
}
213
214
uint8_t
*
av_packet_get_side_data
(
AVPacket
*
pkt
,
enum
AVPacketSideDataType
type,
215
int
*
size
)
216
{
217
int
i;
218
219
for
(i = 0; i < pkt->
side_data_elems
; i++) {
220
if
(pkt->
side_data
[i].
type
== type) {
221
if
(size)
222
*size = pkt->
side_data
[i].
size
;
223
return
pkt->
side_data
[i].
data
;
224
}
225
}
226
return
NULL
;
227
}
228
229
#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
230
231
int
av_packet_merge_side_data
(
AVPacket
*
pkt
){
232
if
(pkt->
side_data_elems
){
233
int
i;
234
uint8_t
*p;
235
uint64_t
size
= pkt->
size
+ 8LL +
FF_INPUT_BUFFER_PADDING_SIZE
;
236
AVPacket
old= *
pkt
;
237
for
(i=0; i<old.
side_data_elems
; i++) {
238
size += old.
side_data
[i].
size
+ 5LL;
239
}
240
if
(size > INT_MAX)
241
return
AVERROR
(EINVAL);
242
p =
av_malloc
(size);
243
if
(!p)
244
return
AVERROR
(ENOMEM);
245
pkt->
data
= p;
246
pkt->
destruct
=
av_destruct_packet
;
247
pkt->
size
= size -
FF_INPUT_BUFFER_PADDING_SIZE
;
248
bytestream_put_buffer
(&p, old.
data
, old.
size
);
249
for
(i=old.
side_data_elems
-1; i>=0; i--) {
250
bytestream_put_buffer
(&p, old.
side_data
[i].
data
, old.
side_data
[i].
size
);
251
bytestream_put_be32(&p, old.
side_data
[i].
size
);
252
*p++ = old.
side_data
[i].
type
| ((i==old.
side_data_elems
-1)*128);
253
}
254
bytestream_put_be64(&p,
FF_MERGE_MARKER
);
255
av_assert0
(p-pkt->
data
== pkt->
size
);
256
memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
257
av_free_packet
(&old);
258
pkt->
side_data_elems
= 0;
259
pkt->
side_data
=
NULL
;
260
return
1;
261
}
262
return
0;
263
}
264
265
int
av_packet_split_side_data
(
AVPacket
*
pkt
){
266
if
(!pkt->
side_data_elems
&& pkt->
size
>12 &&
AV_RB64
(pkt->
data
+ pkt->
size
- 8) ==
FF_MERGE_MARKER
){
267
int
i;
268
unsigned
int
size
;
269
uint8_t
*p;
270
271
p = pkt->
data
+ pkt->
size
- 8 - 5;
272
for
(i=1; ; i++){
273
size =
AV_RB32
(p);
274
if
(size>INT_MAX || p - pkt->
data
< size)
275
return
0;
276
if
(p[4]&128)
277
break
;
278
p-= size+5;
279
}
280
281
pkt->
side_data
=
av_malloc
(i *
sizeof
(*pkt->
side_data
));
282
if
(!pkt->
side_data
)
283
return
AVERROR
(ENOMEM);
284
285
p= pkt->
data
+ pkt->
size
- 8 - 5;
286
for
(i=0; ; i++){
287
size=
AV_RB32
(p);
288
av_assert0
(size<=INT_MAX && p - pkt->
data
>= size);
289
pkt->
side_data
[i].
data
=
av_mallocz
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
290
pkt->
side_data
[i].
size
=
size
;
291
pkt->
side_data
[i].
type
= p[4]&127;
292
if
(!pkt->
side_data
[i].
data
)
293
return
AVERROR
(ENOMEM);
294
memcpy(pkt->
side_data
[i].
data
, p-size, size);
295
pkt->
size
-= size + 5;
296
if
(p[4]&128)
297
break
;
298
p-= size+5;
299
}
300
pkt->
size
-= 8;
301
pkt->
side_data_elems
= i+1;
302
return
1;
303
}
304
return
0;
305
}
306
307
int
av_packet_shrink_side_data
(
AVPacket
*
pkt
,
enum
AVPacketSideDataType
type,
308
int
size
)
309
{
310
int
i;
311
312
for
(i = 0; i < pkt->
side_data_elems
; i++) {
313
if
(pkt->
side_data
[i].
type
== type) {
314
if
(size > pkt->
side_data
[i].
size
)
315
return
AVERROR
(ENOMEM);
316
pkt->
side_data
[i].
size
=
size
;
317
return
0;
318
}
319
}
320
return
AVERROR
(ENOENT);
321
}
Generated on Thu Feb 12 2015 17:56:52 for FFmpeg by
1.8.1.2