FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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_malloc
(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 Sat May 25 2013 04:01:01 for FFmpeg by
1.8.2