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