Move AVFrame from lavc to lavu.
[libav.git] / libavutil / frame.c
1 /*
2 *
3 * This file is part of Libav.
4 *
5 * Libav is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * Libav is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with Libav; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "audioconvert.h"
21 #include "buffer.h"
22 #include "common.h"
23 #include "frame.h"
24 #include "imgutils.h"
25 #include "mem.h"
26 #include "samplefmt.h"
27
28 static void get_frame_defaults(AVFrame *frame)
29 {
30 if (frame->extended_data != frame->data)
31 av_freep(&frame->extended_data);
32
33 memset(frame, 0, sizeof(*frame));
34
35 frame->pts = AV_NOPTS_VALUE;
36 frame->key_frame = 1;
37 frame->sample_aspect_ratio = (AVRational){ 0, 1 };
38 frame->format = -1; /* unknown */
39 frame->extended_data = frame->data;
40 }
41
42 AVFrame *av_frame_alloc(void)
43 {
44 AVFrame *frame = av_mallocz(sizeof(*frame));
45
46 if (!frame)
47 return NULL;
48
49 get_frame_defaults(frame);
50
51 return frame;
52 }
53
54 void av_frame_free(AVFrame **frame)
55 {
56 if (!frame || !*frame)
57 return;
58
59 av_frame_unref(*frame);
60 av_freep(frame);
61 }
62
63 static int get_video_buffer(AVFrame *frame, int align)
64 {
65 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
66 int ret, i;
67
68 if (!desc)
69 return AVERROR(EINVAL);
70
71 if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
72 return ret;
73
74 if (!frame->linesize[0]) {
75 ret = av_image_fill_linesizes(frame->linesize, frame->format,
76 frame->width);
77 if (ret < 0)
78 return ret;
79
80 for (i = 0; i < 4 && frame->linesize[i]; i++)
81 frame->linesize[i] = FFALIGN(frame->linesize[i], align);
82 }
83
84 for (i = 0; i < 4 && frame->linesize[i]; i++) {
85 int h = frame->height;
86 if (i == 1 || i == 2)
87 h = -((-h) >> desc->log2_chroma_h);
88
89 frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h);
90 if (!frame->buf[i])
91 goto fail;
92
93 frame->data[i] = frame->buf[i]->data;
94 }
95 if (desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL) {
96 av_buffer_unref(&frame->buf[1]);
97 frame->buf[1] = av_buffer_alloc(1024);
98 if (!frame->buf[1])
99 goto fail;
100 frame->data[1] = frame->buf[1]->data;
101 }
102
103 frame->extended_data = frame->data;
104
105 return 0;
106 fail:
107 av_frame_unref(frame);
108 return AVERROR(ENOMEM);
109 }
110
111 static int get_audio_buffer(AVFrame *frame, int align)
112 {
113 int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
114 int planar = av_sample_fmt_is_planar(frame->format);
115 int planes = planar ? channels : 1;
116 int ret, i;
117
118 if (!frame->linesize[0]) {
119 ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
120 frame->nb_samples, frame->format,
121 align);
122 if (ret < 0)
123 return ret;
124 }
125
126 if (planes > AV_NUM_DATA_POINTERS) {
127 frame->extended_data = av_mallocz(planes *
128 sizeof(*frame->extended_data));
129 frame->extended_buf = av_mallocz((planes - AV_NUM_DATA_POINTERS) *
130 sizeof(*frame->extended_buf));
131 if (!frame->extended_data || !frame->extended_buf) {
132 av_freep(&frame->extended_data);
133 av_freep(&frame->extended_buf);
134 return AVERROR(ENOMEM);
135 }
136 frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
137 } else
138 frame->extended_data = frame->data;
139
140 for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
141 frame->buf[i] = av_buffer_alloc(frame->linesize[0]);
142 if (!frame->buf[i]) {
143 av_frame_unref(frame);
144 return AVERROR(ENOMEM);
145 }
146 frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
147 }
148 for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) {
149 frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]);
150 if (!frame->extended_buf[i]) {
151 av_frame_unref(frame);
152 return AVERROR(ENOMEM);
153 }
154 frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
155 }
156 return 0;
157
158 }
159
160 int av_frame_get_buffer(AVFrame *frame, int align)
161 {
162 if (frame->format < 0)
163 return AVERROR(EINVAL);
164
165 if (frame->width > 0 && frame->height > 0)
166 return get_video_buffer(frame, align);
167 else if (frame->nb_samples > 0 && frame->channel_layout)
168 return get_audio_buffer(frame, align);
169
170 return AVERROR(EINVAL);
171 }
172
173 int av_frame_ref(AVFrame *dst, AVFrame *src)
174 {
175 int i, ret = 0;
176
177 dst->format = src->format;
178 dst->width = src->width;
179 dst->height = src->height;
180 dst->channel_layout = src->channel_layout;
181 dst->nb_samples = src->nb_samples;
182
183 ret = av_frame_copy_props(dst, src);
184 if (ret < 0)
185 return ret;
186
187 /* duplicate the frame data if it's not refcounted */
188 if (!src->buf[0]) {
189 ret = av_frame_get_buffer(dst, 32);
190 if (ret < 0)
191 return ret;
192
193 if (src->nb_samples) {
194 int ch = av_get_channel_layout_nb_channels(src->channel_layout);
195 av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
196 dst->nb_samples, ch, dst->format);
197 } else {
198 av_image_copy(dst->data, dst->linesize, src->data, src->linesize,
199 dst->format, dst->width, dst->height);
200 }
201 return 0;
202 }
203
204 /* ref the buffers */
205 for (i = 0; i < FF_ARRAY_ELEMS(src->buf) && src->buf[i]; i++) {
206 dst->buf[i] = av_buffer_ref(src->buf[i]);
207 if (!dst->buf[i]) {
208 ret = AVERROR(ENOMEM);
209 goto fail;
210 }
211 }
212
213 if (src->extended_buf) {
214 dst->extended_buf = av_mallocz(sizeof(*dst->extended_buf) *
215 src->nb_extended_buf);
216 if (!dst->extended_buf) {
217 ret = AVERROR(ENOMEM);
218 goto fail;
219 }
220 dst->nb_extended_buf = src->nb_extended_buf;
221
222 for (i = 0; i < src->nb_extended_buf; i++) {
223 dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]);
224 if (!dst->extended_buf[i]) {
225 ret = AVERROR(ENOMEM);
226 goto fail;
227 }
228 }
229 }
230
231 /* duplicate extended data */
232 if (src->extended_data != src->data) {
233 int ch = av_get_channel_layout_nb_channels(src->channel_layout);
234
235 if (!ch) {
236 ret = AVERROR(EINVAL);
237 goto fail;
238 }
239
240 dst->extended_data = av_malloc(sizeof(*dst->extended_data) * ch);
241 if (!dst->extended_data) {
242 ret = AVERROR(ENOMEM);
243 goto fail;
244 }
245 memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch);
246 } else
247 dst->extended_data = dst->data;
248
249 memcpy(dst->data, src->data, sizeof(src->data));
250 memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
251
252 return 0;
253
254 fail:
255 av_frame_unref(dst);
256 return ret;
257 }
258
259 AVFrame *av_frame_clone(AVFrame *src)
260 {
261 AVFrame *ret = av_frame_alloc();
262
263 if (!ret)
264 return NULL;
265
266 if (av_frame_ref(ret, src) < 0)
267 av_frame_free(&ret);
268
269 return ret;
270 }
271
272 void av_frame_unref(AVFrame *frame)
273 {
274 int i;
275
276 for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
277 av_buffer_unref(&frame->buf[i]);
278 for (i = 0; i < frame->nb_extended_buf; i++)
279 av_buffer_unref(&frame->extended_buf[i]);
280 av_freep(&frame->extended_buf);
281 get_frame_defaults(frame);
282 }
283
284 void av_frame_move_ref(AVFrame *dst, AVFrame *src)
285 {
286 *dst = *src;
287 if (src->extended_data == src->data)
288 dst->extended_data = dst->data;
289 memset(src, 0, sizeof(*src));
290 get_frame_defaults(src);
291 }
292
293 int av_frame_is_writable(AVFrame *frame)
294 {
295 int i, ret = 1;
296
297 /* assume non-refcounted frames are not writable */
298 if (!frame->buf[0])
299 return 0;
300
301 for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++)
302 ret &= !!av_buffer_is_writable(frame->buf[i]);
303 for (i = 0; i < frame->nb_extended_buf; i++)
304 ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
305
306 return ret;
307 }
308
309 int av_frame_make_writable(AVFrame *frame)
310 {
311 AVFrame tmp;
312 int ret;
313
314 if (!frame->buf[0])
315 return AVERROR(EINVAL);
316
317 if (av_frame_is_writable(frame))
318 return 0;
319
320 memset(&tmp, 0, sizeof(tmp));
321 tmp.format = frame->format;
322 tmp.width = frame->width;
323 tmp.height = frame->height;
324 tmp.channel_layout = frame->channel_layout;
325 tmp.nb_samples = frame->nb_samples;
326 ret = av_frame_get_buffer(&tmp, 32);
327 if (ret < 0)
328 return ret;
329
330 if (tmp.nb_samples) {
331 int ch = av_get_channel_layout_nb_channels(tmp.channel_layout);
332 av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0,
333 frame->nb_samples, ch, frame->format);
334 } else {
335 av_image_copy(tmp.data, tmp.linesize, frame->data, frame->linesize,
336 frame->format, frame->width, frame->height);
337 }
338
339 ret = av_frame_copy_props(&tmp, frame);
340 if (ret < 0) {
341 av_frame_unref(&tmp);
342 return ret;
343 }
344
345 av_frame_unref(frame);
346
347 *frame = tmp;
348 if (tmp.data == tmp.extended_data)
349 frame->extended_data = frame->data;
350
351 return 0;
352 }
353
354 int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
355 {
356 dst->key_frame = src->key_frame;
357 dst->pict_type = src->pict_type;
358 dst->sample_aspect_ratio = src->sample_aspect_ratio;
359 dst->pts = src->pts;
360 dst->interlaced_frame = src->interlaced_frame;
361 dst->top_field_first = src->top_field_first;
362 dst->sample_rate = src->sample_rate;
363 dst->opaque = src->opaque;
364 dst->pkt_pts = src->pkt_pts;
365 dst->pkt_dts = src->pkt_dts;
366 dst->quality = src->quality;
367 dst->coded_picture_number = src->coded_picture_number;
368 dst->display_picture_number = src->display_picture_number;
369
370 return 0;
371 }
372
373 AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane)
374 {
375 uint8_t *data;
376 int planes, i;
377
378 if (frame->nb_samples) {
379 int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
380 if (!channels)
381 return NULL;
382 planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
383 } else
384 planes = 4;
385
386 if (plane < 0 || plane >= planes || !frame->extended_data[plane])
387 return NULL;
388 data = frame->extended_data[plane];
389
390 for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) {
391 AVBufferRef *buf = frame->buf[i];
392 if (data >= buf->data && data < buf->data + buf->size)
393 return buf;
394 }
395 for (i = 0; i < frame->nb_extended_buf; i++) {
396 AVBufferRef *buf = frame->extended_buf[i];
397 if (data >= buf->data && data < buf->data + buf->size)
398 return buf;
399 }
400 return NULL;
401 }