]> git.sesse.net Git - ffmpeg/blob - libavcodec/avpacket.c
build: avcodec: order cosmetics
[ffmpeg] / libavcodec / avpacket.c
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 <string.h>
23
24 #include "libavutil/avassert.h"
25 #include "libavutil/mem.h"
26 #include "avcodec.h"
27
28 void av_destruct_packet_nofree(AVPacket *pkt)
29 {
30     pkt->data            = NULL;
31     pkt->size            = 0;
32     pkt->side_data       = NULL;
33     pkt->side_data_elems = 0;
34 }
35
36 void av_destruct_packet(AVPacket *pkt)
37 {
38     int i;
39
40     av_free(pkt->data);
41     pkt->data = NULL;
42     pkt->size = 0;
43
44     for (i = 0; i < pkt->side_data_elems; i++)
45         av_free(pkt->side_data[i].data);
46     av_freep(&pkt->side_data);
47     pkt->side_data_elems = 0;
48 }
49
50 void av_init_packet(AVPacket *pkt)
51 {
52     pkt->pts                  = AV_NOPTS_VALUE;
53     pkt->dts                  = AV_NOPTS_VALUE;
54     pkt->pos                  = -1;
55     pkt->duration             = 0;
56     pkt->convergence_duration = 0;
57     pkt->flags                = 0;
58     pkt->stream_index         = 0;
59     pkt->destruct             = NULL;
60     pkt->side_data            = NULL;
61     pkt->side_data_elems      = 0;
62 }
63
64 int av_new_packet(AVPacket *pkt, int size)
65 {
66     uint8_t *data = NULL;
67     if ((unsigned)size < (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
68         data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
69     if (data) {
70         memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
71     } else
72         size = 0;
73
74     av_init_packet(pkt);
75     pkt->data     = data;
76     pkt->size     = size;
77     pkt->destruct = av_destruct_packet;
78     if (!data)
79         return AVERROR(ENOMEM);
80     return 0;
81 }
82
83 void av_shrink_packet(AVPacket *pkt, int size)
84 {
85     if (pkt->size <= size)
86         return;
87     pkt->size = size;
88     memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
89 }
90
91 int av_grow_packet(AVPacket *pkt, int grow_by)
92 {
93     void *new_ptr;
94     av_assert0((unsigned)pkt->size <= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
95     if (!pkt->size)
96         return av_new_packet(pkt, grow_by);
97     if ((unsigned)grow_by >
98         INT_MAX - (pkt->size + FF_INPUT_BUFFER_PADDING_SIZE))
99         return -1;
100     new_ptr = av_realloc(pkt->data,
101                          pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE);
102     if (!new_ptr)
103         return AVERROR(ENOMEM);
104     pkt->data  = new_ptr;
105     pkt->size += grow_by;
106     memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
107     return 0;
108 }
109
110 #define DUP_DATA(dst, src, size, padding)                               \
111     do {                                                                \
112         void *data;                                                     \
113         if (padding) {                                                  \
114             if ((unsigned)(size) >                                      \
115                 (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE)        \
116                 goto failed_alloc;                                      \
117             data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);      \
118         } else {                                                        \
119             data = av_malloc(size);                                     \
120         }                                                               \
121         if (!data)                                                      \
122             goto failed_alloc;                                          \
123         memcpy(data, src, size);                                        \
124         if (padding)                                                    \
125             memset((uint8_t *)data + size, 0,                           \
126                    FF_INPUT_BUFFER_PADDING_SIZE);                       \
127         dst = data;                                                     \
128     } while (0)
129
130 int av_dup_packet(AVPacket *pkt)
131 {
132     AVPacket tmp_pkt;
133
134     if (((pkt->destruct == av_destruct_packet_nofree) ||
135          (pkt->destruct == NULL)) && pkt->data) {
136         tmp_pkt = *pkt;
137
138         pkt->data      = NULL;
139         pkt->side_data = NULL;
140         DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1);
141         pkt->destruct = av_destruct_packet;
142
143         if (pkt->side_data_elems) {
144             int i;
145
146             DUP_DATA(pkt->side_data, tmp_pkt.side_data,
147                      pkt->side_data_elems * sizeof(*pkt->side_data), 0);
148             memset(pkt->side_data, 0,
149                    pkt->side_data_elems * sizeof(*pkt->side_data));
150             for (i = 0; i < pkt->side_data_elems; i++)
151                 DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data,
152                          tmp_pkt.side_data[i].size, 1);
153         }
154     }
155     return 0;
156
157 failed_alloc:
158     av_destruct_packet(pkt);
159     return AVERROR(ENOMEM);
160 }
161
162 void av_free_packet(AVPacket *pkt)
163 {
164     if (pkt) {
165         if (pkt->destruct)
166             pkt->destruct(pkt);
167         pkt->data            = NULL;
168         pkt->size            = 0;
169         pkt->side_data       = NULL;
170         pkt->side_data_elems = 0;
171     }
172 }
173
174 uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
175                                  int size)
176 {
177     int elems = pkt->side_data_elems;
178
179     if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
180         return NULL;
181     if ((unsigned)size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
182         return NULL;
183
184     pkt->side_data = av_realloc(pkt->side_data,
185                                 (elems + 1) * sizeof(*pkt->side_data));
186     if (!pkt->side_data)
187         return NULL;
188
189     pkt->side_data[elems].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
190     if (!pkt->side_data[elems].data)
191         return NULL;
192     pkt->side_data[elems].size = size;
193     pkt->side_data[elems].type = type;
194     pkt->side_data_elems++;
195
196     return pkt->side_data[elems].data;
197 }
198
199 uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
200                                  int *size)
201 {
202     int i;
203
204     for (i = 0; i < pkt->side_data_elems; i++) {
205         if (pkt->side_data[i].type == type) {
206             if (size)
207                 *size = pkt->side_data[i].size;
208             return pkt->side_data[i].data;
209         }
210     }
211     return NULL;
212 }
213
214 int av_packet_shrink_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 > pkt->side_data[i].size)
222                 return AVERROR(ENOMEM);
223             pkt->side_data[i].size = size;
224             return 0;
225         }
226     }
227     return AVERROR(ENOENT);
228 }