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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
avcodec.h
"
23
#include "
libavutil/avassert.h
"
24
25
26
void
av_destruct_packet_nofree
(
AVPacket
*pkt)
27
{
28
pkt->
data
=
NULL
; pkt->
size
= 0;
29
pkt->
side_data
=
NULL
;
30
pkt->
side_data_elems
= 0;
31
}
32
33
void
av_destruct_packet
(
AVPacket
*pkt)
34
{
35
int
i;
36
37
av_free
(pkt->
data
);
38
pkt->
data
=
NULL
; pkt->
size
= 0;
39
40
for
(i = 0; i < pkt->
side_data_elems
; i++)
41
av_free
(pkt->
side_data
[i].
data
);
42
av_freep
(&pkt->
side_data
);
43
pkt->
side_data_elems
= 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)
return
;
82
pkt->
size
=
size
;
83
memset(pkt->
data
+ size, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
84
}
85
86
int
av_grow_packet
(
AVPacket
*pkt,
int
grow_by)
87
{
88
void
*new_ptr;
89
av_assert0
((
unsigned
)pkt->
size
<= INT_MAX -
FF_INPUT_BUFFER_PADDING_SIZE
);
90
if
(!pkt->
size
)
91
return
av_new_packet
(pkt, grow_by);
92
if
((
unsigned
)grow_by > INT_MAX - (pkt->
size
+
FF_INPUT_BUFFER_PADDING_SIZE
))
93
return
-1;
94
new_ptr =
av_realloc
(pkt->
data
, pkt->
size
+ grow_by +
FF_INPUT_BUFFER_PADDING_SIZE
);
95
if
(!new_ptr)
96
return
AVERROR
(ENOMEM);
97
pkt->
data
= new_ptr;
98
pkt->
size
+= grow_by;
99
memset(pkt->
data
+ pkt->
size
, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
100
return
0;
101
}
102
103
#define DUP_DATA(dst, src, size, padding) \
104
do { \
105
void *data; \
106
if (padding) { \
107
if ((unsigned)(size) > (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE) \
108
goto failed_alloc; \
109
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); \
110
} else { \
111
data = av_malloc(size); \
112
} \
113
if (!data) \
114
goto failed_alloc; \
115
memcpy(data, src, size); \
116
if (padding) \
117
memset((uint8_t*)data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); \
118
dst = data; \
119
} while(0)
120
121
int
av_dup_packet
(
AVPacket
*pkt)
122
{
123
AVPacket
tmp_pkt;
124
125
if
(((pkt->
destruct
==
av_destruct_packet_nofree
) || (pkt->
destruct
==
NULL
)) && pkt->
data
) {
126
tmp_pkt = *pkt;
127
128
pkt->
data
=
NULL
;
129
pkt->
side_data
=
NULL
;
130
DUP_DATA
(pkt->
data
, tmp_pkt.
data
, pkt->
size
, 1);
131
pkt->
destruct
=
av_destruct_packet
;
132
133
if
(pkt->
side_data_elems
) {
134
int
i;
135
136
DUP_DATA
(pkt->
side_data
, tmp_pkt.
side_data
,
137
pkt->
side_data_elems
*
sizeof
(*pkt->
side_data
), 0);
138
memset(pkt->
side_data
, 0, pkt->
side_data_elems
*
sizeof
(*pkt->
side_data
));
139
for
(i = 0; i < pkt->
side_data_elems
; i++) {
140
DUP_DATA
(pkt->
side_data
[i].
data
, tmp_pkt.
side_data
[i].
data
,
141
pkt->
side_data
[i].
size
, 1);
142
}
143
}
144
}
145
return
0;
146
failed_alloc:
147
av_destruct_packet
(pkt);
148
return
AVERROR
(ENOMEM);
149
}
150
151
void
av_free_packet
(
AVPacket
*pkt)
152
{
153
if
(pkt) {
154
if
(pkt->
destruct
) pkt->
destruct
(pkt);
155
pkt->
data
=
NULL
; pkt->
size
= 0;
156
pkt->
side_data
=
NULL
;
157
pkt->
side_data_elems
= 0;
158
}
159
}
160
161
uint8_t*
av_packet_new_side_data
(
AVPacket
*pkt,
enum
AVPacketSideDataType
type,
162
int
size
)
163
{
164
int
elems = pkt->
side_data_elems
;
165
166
if
((
unsigned
)elems + 1 > INT_MAX /
sizeof
(*pkt->
side_data
))
167
return
NULL
;
168
if
((
unsigned
)size > INT_MAX -
FF_INPUT_BUFFER_PADDING_SIZE
)
169
return
NULL
;
170
171
pkt->
side_data
=
av_realloc
(pkt->
side_data
, (elems + 1) *
sizeof
(*pkt->
side_data
));
172
if
(!pkt->
side_data
)
173
return
NULL
;
174
175
pkt->
side_data
[elems].
data
=
av_malloc
(size +
FF_INPUT_BUFFER_PADDING_SIZE
);
176
if
(!pkt->
side_data
[elems].
data
)
177
return
NULL
;
178
pkt->
side_data
[elems].
size
=
size
;
179
pkt->
side_data
[elems].
type
= type;
180
pkt->
side_data_elems
++;
181
182
return
pkt->
side_data
[elems].
data
;
183
}
184
185
uint8_t*
av_packet_get_side_data
(
AVPacket
*pkt,
enum
AVPacketSideDataType
type,
186
int
*
size
)
187
{
188
int
i;
189
190
for
(i = 0; i < pkt->
side_data_elems
; i++) {
191
if
(pkt->
side_data
[i].
type
== type) {
192
if
(size)
193
*size = pkt->
side_data
[i].
size
;
194
return
pkt->
side_data
[i].
data
;
195
}
196
}
197
return
NULL
;
198
}