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