Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6147 serge 1
/*
2
 *
3
 * This file is part of FFmpeg.
4
 *
5
 * FFmpeg 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
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19
 
20
#include "channel_layout.h"
21
#include "avassert.h"
22
#include "buffer.h"
23
#include "common.h"
24
#include "dict.h"
25
#include "frame.h"
26
#include "imgutils.h"
27
#include "mem.h"
28
#include "samplefmt.h"
29
 
30
MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp)
31
MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration)
32
MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos)
33
MAKE_ACCESSORS(AVFrame, frame, int64_t, channel_layout)
34
MAKE_ACCESSORS(AVFrame, frame, int,     channels)
35
MAKE_ACCESSORS(AVFrame, frame, int,     sample_rate)
36
MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
37
MAKE_ACCESSORS(AVFrame, frame, int,     decode_error_flags)
38
MAKE_ACCESSORS(AVFrame, frame, int,     pkt_size)
39
MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace)
40
MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range)
41
 
42
#define CHECK_CHANNELS_CONSISTENCY(frame) \
43
    av_assert2(!(frame)->channel_layout || \
44
               (frame)->channels == \
45
               av_get_channel_layout_nb_channels((frame)->channel_layout))
46
 
47
AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame) {return &frame->metadata;};
48
 
49
int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type)
50
{
51
    av_buffer_unref(&f->qp_table_buf);
52
 
53
    f->qp_table_buf = buf;
54
 
55
    f->qscale_table = buf->data;
56
    f->qstride      = stride;
57
    f->qscale_type  = qp_type;
58
 
59
    return 0;
60
}
61
 
62
int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type)
63
{
64
    *stride = f->qstride;
65
    *type   = f->qscale_type;
66
 
67
    if (!f->qp_table_buf)
68
        return NULL;
69
 
70
    return f->qp_table_buf->data;
71
}
72
 
73
const char *av_get_colorspace_name(enum AVColorSpace val)
74
{
75
    static const char * const name[] = {
76
        [AVCOL_SPC_RGB]       = "GBR",
77
        [AVCOL_SPC_BT709]     = "bt709",
78
        [AVCOL_SPC_FCC]       = "fcc",
79
        [AVCOL_SPC_BT470BG]   = "bt470bg",
80
        [AVCOL_SPC_SMPTE170M] = "smpte170m",
81
        [AVCOL_SPC_SMPTE240M] = "smpte240m",
82
        [AVCOL_SPC_YCOCG]     = "YCgCo",
83
    };
84
    if ((unsigned)val >= FF_ARRAY_ELEMS(name))
85
        return NULL;
86
    return name[val];
87
}
88
 
89
static void get_frame_defaults(AVFrame *frame)
90
{
91
    if (frame->extended_data != frame->data)
92
        av_freep(&frame->extended_data);
93
 
94
    memset(frame, 0, sizeof(*frame));
95
 
96
    frame->pts                   =
97
    frame->pkt_dts               =
98
    frame->pkt_pts               = AV_NOPTS_VALUE;
99
    av_frame_set_best_effort_timestamp(frame, AV_NOPTS_VALUE);
100
    av_frame_set_pkt_duration         (frame, 0);
101
    av_frame_set_pkt_pos              (frame, -1);
102
    av_frame_set_pkt_size             (frame, -1);
103
    frame->key_frame           = 1;
104
    frame->sample_aspect_ratio = (AVRational){ 0, 1 };
105
    frame->format              = -1; /* unknown */
106
    frame->extended_data       = frame->data;
107
    frame->color_primaries     = AVCOL_PRI_UNSPECIFIED;
108
    frame->color_trc           = AVCOL_TRC_UNSPECIFIED;
109
    frame->colorspace          = AVCOL_SPC_UNSPECIFIED;
110
    frame->color_range         = AVCOL_RANGE_UNSPECIFIED;
111
    frame->chroma_location     = AVCHROMA_LOC_UNSPECIFIED;
112
}
113
 
114
static void free_side_data(AVFrameSideData **ptr_sd)
115
{
116
    AVFrameSideData *sd = *ptr_sd;
117
 
118
    av_buffer_unref(&sd->buf);
119
    av_dict_free(&sd->metadata);
120
    av_freep(ptr_sd);
121
}
122
 
123
static void wipe_side_data(AVFrame *frame)
124
{
125
    int i;
126
 
127
    for (i = 0; i < frame->nb_side_data; i++) {
128
        free_side_data(&frame->side_data[i]);
129
    }
130
    frame->nb_side_data = 0;
131
 
132
    av_freep(&frame->side_data);
133
}
134
 
135
AVFrame *av_frame_alloc(void)
136
{
137
    AVFrame *frame = av_mallocz(sizeof(*frame));
138
 
139
    if (!frame)
140
        return NULL;
141
 
142
    frame->extended_data = NULL;
143
    get_frame_defaults(frame);
144
 
145
    return frame;
146
}
147
 
148
void av_frame_free(AVFrame **frame)
149
{
150
    if (!frame || !*frame)
151
        return;
152
 
153
    av_frame_unref(*frame);
154
    av_freep(frame);
155
}
156
 
157
static int get_video_buffer(AVFrame *frame, int align)
158
{
159
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
160
    int ret, i;
161
 
162
    if (!desc)
163
        return AVERROR(EINVAL);
164
 
165
    if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
166
        return ret;
167
 
168
    if (!frame->linesize[0]) {
169
        for(i=1; i<=align; i+=i) {
170
            ret = av_image_fill_linesizes(frame->linesize, frame->format,
171
                                          FFALIGN(frame->width, i));
172
            if (ret < 0)
173
                return ret;
174
            if (!(frame->linesize[0] & (align-1)))
175
                break;
176
        }
177
 
178
        for (i = 0; i < 4 && frame->linesize[i]; i++)
179
            frame->linesize[i] = FFALIGN(frame->linesize[i], align);
180
    }
181
 
182
    for (i = 0; i < 4 && frame->linesize[i]; i++) {
183
        int h = FFALIGN(frame->height, 32);
184
        if (i == 1 || i == 2)
185
            h = FF_CEIL_RSHIFT(h, desc->log2_chroma_h);
186
 
187
        frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16 + 16/*STRIDE_ALIGN*/ - 1);
188
        if (!frame->buf[i])
189
            goto fail;
190
 
191
        frame->data[i] = frame->buf[i]->data;
192
    }
193
    if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
194
        av_buffer_unref(&frame->buf[1]);
195
        frame->buf[1] = av_buffer_alloc(1024);
196
        if (!frame->buf[1])
197
            goto fail;
198
        frame->data[1] = frame->buf[1]->data;
199
    }
200
 
201
    frame->extended_data = frame->data;
202
 
203
    return 0;
204
fail:
205
    av_frame_unref(frame);
206
    return AVERROR(ENOMEM);
207
}
208
 
209
static int get_audio_buffer(AVFrame *frame, int align)
210
{
211
    int channels;
212
    int planar   = av_sample_fmt_is_planar(frame->format);
213
    int planes;
214
    int ret, i;
215
 
216
    if (!frame->channels)
217
        frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout);
218
 
219
    channels = frame->channels;
220
    planes = planar ? channels : 1;
221
 
222
    CHECK_CHANNELS_CONSISTENCY(frame);
223
    if (!frame->linesize[0]) {
224
        ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
225
                                         frame->nb_samples, frame->format,
226
                                         align);
227
        if (ret < 0)
228
            return ret;
229
    }
230
 
231
    if (planes > AV_NUM_DATA_POINTERS) {
232
        frame->extended_data = av_mallocz_array(planes,
233
                                          sizeof(*frame->extended_data));
234
        frame->extended_buf  = av_mallocz_array((planes - AV_NUM_DATA_POINTERS),
235
                                          sizeof(*frame->extended_buf));
236
        if (!frame->extended_data || !frame->extended_buf) {
237
            av_freep(&frame->extended_data);
238
            av_freep(&frame->extended_buf);
239
            return AVERROR(ENOMEM);
240
        }
241
        frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
242
    } else
243
        frame->extended_data = frame->data;
244
 
245
    for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
246
        frame->buf[i] = av_buffer_alloc(frame->linesize[0]);
247
        if (!frame->buf[i]) {
248
            av_frame_unref(frame);
249
            return AVERROR(ENOMEM);
250
        }
251
        frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
252
    }
253
    for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) {
254
        frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]);
255
        if (!frame->extended_buf[i]) {
256
            av_frame_unref(frame);
257
            return AVERROR(ENOMEM);
258
        }
259
        frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
260
    }
261
    return 0;
262
 
263
}
264
 
265
int av_frame_get_buffer(AVFrame *frame, int align)
266
{
267
    if (frame->format < 0)
268
        return AVERROR(EINVAL);
269
 
270
    if (frame->width > 0 && frame->height > 0)
271
        return get_video_buffer(frame, align);
272
    else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0))
273
        return get_audio_buffer(frame, align);
274
 
275
    return AVERROR(EINVAL);
276
}
277
 
278
static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
279
{
280
    int i;
281
 
282
    dst->key_frame              = src->key_frame;
283
    dst->pict_type              = src->pict_type;
284
    dst->sample_aspect_ratio    = src->sample_aspect_ratio;
285
    dst->pts                    = src->pts;
286
    dst->repeat_pict            = src->repeat_pict;
287
    dst->interlaced_frame       = src->interlaced_frame;
288
    dst->top_field_first        = src->top_field_first;
289
    dst->palette_has_changed    = src->palette_has_changed;
290
    dst->sample_rate            = src->sample_rate;
291
    dst->opaque                 = src->opaque;
292
#if FF_API_AVFRAME_LAVC
293
FF_DISABLE_DEPRECATION_WARNINGS
294
    dst->type                   = src->type;
295
FF_ENABLE_DEPRECATION_WARNINGS
296
#endif
297
    dst->pkt_pts                = src->pkt_pts;
298
    dst->pkt_dts                = src->pkt_dts;
299
    dst->pkt_pos                = src->pkt_pos;
300
    dst->pkt_size               = src->pkt_size;
301
    dst->pkt_duration           = src->pkt_duration;
302
    dst->reordered_opaque       = src->reordered_opaque;
303
    dst->quality                = src->quality;
304
    dst->best_effort_timestamp  = src->best_effort_timestamp;
305
    dst->coded_picture_number   = src->coded_picture_number;
306
    dst->display_picture_number = src->display_picture_number;
307
    dst->flags                  = src->flags;
308
    dst->decode_error_flags     = src->decode_error_flags;
309
    dst->color_primaries        = src->color_primaries;
310
    dst->color_trc              = src->color_trc;
311
    dst->colorspace             = src->colorspace;
312
    dst->color_range            = src->color_range;
313
    dst->chroma_location        = src->chroma_location;
314
 
315
    av_dict_copy(&dst->metadata, src->metadata, 0);
316
 
317
    memcpy(dst->error, src->error, sizeof(dst->error));
318
 
319
    for (i = 0; i < src->nb_side_data; i++) {
320
        const AVFrameSideData *sd_src = src->side_data[i];
321
        AVFrameSideData *sd_dst;
322
        if (   sd_src->type == AV_FRAME_DATA_PANSCAN
323
            && (src->width != dst->width || src->height != dst->height))
324
            continue;
325
        if (force_copy) {
326
            sd_dst = av_frame_new_side_data(dst, sd_src->type,
327
                                            sd_src->size);
328
            if (!sd_dst) {
329
                wipe_side_data(dst);
330
                return AVERROR(ENOMEM);
331
            }
332
            memcpy(sd_dst->data, sd_src->data, sd_src->size);
333
        } else {
334
            sd_dst = av_frame_new_side_data(dst, sd_src->type, 0);
335
            if (!sd_dst) {
336
                wipe_side_data(dst);
337
                return AVERROR(ENOMEM);
338
            }
339
            sd_dst->buf = av_buffer_ref(sd_src->buf);
340
            if (!sd_dst->buf) {
341
                wipe_side_data(dst);
342
                return AVERROR(ENOMEM);
343
            }
344
            sd_dst->data = sd_dst->buf->data;
345
            sd_dst->size = sd_dst->buf->size;
346
        }
347
        av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
348
    }
349
 
350
    dst->qscale_table = NULL;
351
    dst->qstride      = 0;
352
    dst->qscale_type  = 0;
353
    if (src->qp_table_buf) {
354
        dst->qp_table_buf = av_buffer_ref(src->qp_table_buf);
355
        if (dst->qp_table_buf) {
356
            dst->qscale_table = dst->qp_table_buf->data;
357
            dst->qstride      = src->qstride;
358
            dst->qscale_type  = src->qscale_type;
359
        }
360
    }
361
 
362
    return 0;
363
}
364
 
365
int av_frame_ref(AVFrame *dst, const AVFrame *src)
366
{
367
    int i, ret = 0;
368
 
369
    dst->format         = src->format;
370
    dst->width          = src->width;
371
    dst->height         = src->height;
372
    dst->channels       = src->channels;
373
    dst->channel_layout = src->channel_layout;
374
    dst->nb_samples     = src->nb_samples;
375
 
376
    ret = frame_copy_props(dst, src, 0);
377
    if (ret < 0)
378
        return ret;
379
 
380
    /* duplicate the frame data if it's not refcounted */
381
    if (!src->buf[0]) {
382
        ret = av_frame_get_buffer(dst, 32);
383
        if (ret < 0)
384
            return ret;
385
 
386
        ret = av_frame_copy(dst, src);
387
        if (ret < 0)
388
            av_frame_unref(dst);
389
 
390
        return ret;
391
    }
392
 
393
    /* ref the buffers */
394
    for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
395
        if (!src->buf[i])
396
            continue;
397
        dst->buf[i] = av_buffer_ref(src->buf[i]);
398
        if (!dst->buf[i]) {
399
            ret = AVERROR(ENOMEM);
400
            goto fail;
401
        }
402
    }
403
 
404
    if (src->extended_buf) {
405
        dst->extended_buf = av_mallocz_array(sizeof(*dst->extended_buf),
406
                                       src->nb_extended_buf);
407
        if (!dst->extended_buf) {
408
            ret = AVERROR(ENOMEM);
409
            goto fail;
410
        }
411
        dst->nb_extended_buf = src->nb_extended_buf;
412
 
413
        for (i = 0; i < src->nb_extended_buf; i++) {
414
            dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]);
415
            if (!dst->extended_buf[i]) {
416
                ret = AVERROR(ENOMEM);
417
                goto fail;
418
            }
419
        }
420
    }
421
 
422
    /* duplicate extended data */
423
    if (src->extended_data != src->data) {
424
        int ch = src->channels;
425
 
426
        if (!ch) {
427
            ret = AVERROR(EINVAL);
428
            goto fail;
429
        }
430
        CHECK_CHANNELS_CONSISTENCY(src);
431
 
432
        dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch);
433
        if (!dst->extended_data) {
434
            ret = AVERROR(ENOMEM);
435
            goto fail;
436
        }
437
        memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch);
438
    } else
439
        dst->extended_data = dst->data;
440
 
441
    memcpy(dst->data,     src->data,     sizeof(src->data));
442
    memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
443
 
444
    return 0;
445
 
446
fail:
447
    av_frame_unref(dst);
448
    return ret;
449
}
450
 
451
AVFrame *av_frame_clone(const AVFrame *src)
452
{
453
    AVFrame *ret = av_frame_alloc();
454
 
455
    if (!ret)
456
        return NULL;
457
 
458
    if (av_frame_ref(ret, src) < 0)
459
        av_frame_free(&ret);
460
 
461
    return ret;
462
}
463
 
464
void av_frame_unref(AVFrame *frame)
465
{
466
    int i;
467
 
468
    if (!frame)
469
        return;
470
 
471
    wipe_side_data(frame);
472
 
473
    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
474
        av_buffer_unref(&frame->buf[i]);
475
    for (i = 0; i < frame->nb_extended_buf; i++)
476
        av_buffer_unref(&frame->extended_buf[i]);
477
    av_freep(&frame->extended_buf);
478
    av_dict_free(&frame->metadata);
479
    av_buffer_unref(&frame->qp_table_buf);
480
 
481
    get_frame_defaults(frame);
482
}
483
 
484
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
485
{
486
    *dst = *src;
487
    if (src->extended_data == src->data)
488
        dst->extended_data = dst->data;
489
    memset(src, 0, sizeof(*src));
490
    get_frame_defaults(src);
491
}
492
 
493
int av_frame_is_writable(AVFrame *frame)
494
{
495
    int i, ret = 1;
496
 
497
    /* assume non-refcounted frames are not writable */
498
    if (!frame->buf[0])
499
        return 0;
500
 
501
    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
502
        if (frame->buf[i])
503
            ret &= !!av_buffer_is_writable(frame->buf[i]);
504
    for (i = 0; i < frame->nb_extended_buf; i++)
505
        ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
506
 
507
    return ret;
508
}
509
 
510
int av_frame_make_writable(AVFrame *frame)
511
{
512
    AVFrame tmp;
513
    int ret;
514
 
515
    if (!frame->buf[0])
516
        return AVERROR(EINVAL);
517
 
518
    if (av_frame_is_writable(frame))
519
        return 0;
520
 
521
    memset(&tmp, 0, sizeof(tmp));
522
    tmp.format         = frame->format;
523
    tmp.width          = frame->width;
524
    tmp.height         = frame->height;
525
    tmp.channels       = frame->channels;
526
    tmp.channel_layout = frame->channel_layout;
527
    tmp.nb_samples     = frame->nb_samples;
528
    ret = av_frame_get_buffer(&tmp, 32);
529
    if (ret < 0)
530
        return ret;
531
 
532
    ret = av_frame_copy(&tmp, frame);
533
    if (ret < 0) {
534
        av_frame_unref(&tmp);
535
        return ret;
536
    }
537
 
538
    ret = av_frame_copy_props(&tmp, frame);
539
    if (ret < 0) {
540
        av_frame_unref(&tmp);
541
        return ret;
542
    }
543
 
544
    av_frame_unref(frame);
545
 
546
    *frame = tmp;
547
    if (tmp.data == tmp.extended_data)
548
        frame->extended_data = frame->data;
549
 
550
    return 0;
551
}
552
 
553
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
554
{
555
    return frame_copy_props(dst, src, 1);
556
}
557
 
558
AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane)
559
{
560
    uint8_t *data;
561
    int planes, i;
562
 
563
    if (frame->nb_samples) {
564
        int channels = frame->channels;
565
        if (!channels)
566
            return NULL;
567
        CHECK_CHANNELS_CONSISTENCY(frame);
568
        planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
569
    } else
570
        planes = 4;
571
 
572
    if (plane < 0 || plane >= planes || !frame->extended_data[plane])
573
        return NULL;
574
    data = frame->extended_data[plane];
575
 
576
    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) {
577
        AVBufferRef *buf = frame->buf[i];
578
        if (data >= buf->data && data < buf->data + buf->size)
579
            return buf;
580
    }
581
    for (i = 0; i < frame->nb_extended_buf; i++) {
582
        AVBufferRef *buf = frame->extended_buf[i];
583
        if (data >= buf->data && data < buf->data + buf->size)
584
            return buf;
585
    }
586
    return NULL;
587
}
588
 
589
AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
590
                                        enum AVFrameSideDataType type,
591
                                        int size)
592
{
593
    AVFrameSideData *ret, **tmp;
594
 
595
    if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
596
        return NULL;
597
 
598
    tmp = av_realloc(frame->side_data,
599
                     (frame->nb_side_data + 1) * sizeof(*frame->side_data));
600
    if (!tmp)
601
        return NULL;
602
    frame->side_data = tmp;
603
 
604
    ret = av_mallocz(sizeof(*ret));
605
    if (!ret)
606
        return NULL;
607
 
608
    if (size > 0) {
609
        ret->buf = av_buffer_alloc(size);
610
        if (!ret->buf) {
611
            av_freep(&ret);
612
            return NULL;
613
        }
614
 
615
        ret->data = ret->buf->data;
616
        ret->size = size;
617
    }
618
    ret->type = type;
619
 
620
    frame->side_data[frame->nb_side_data++] = ret;
621
 
622
    return ret;
623
}
624
 
625
AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
626
                                        enum AVFrameSideDataType type)
627
{
628
    int i;
629
 
630
    for (i = 0; i < frame->nb_side_data; i++) {
631
        if (frame->side_data[i]->type == type)
632
            return frame->side_data[i];
633
    }
634
    return NULL;
635
}
636
 
637
static int frame_copy_video(AVFrame *dst, const AVFrame *src)
638
{
639
    const uint8_t *src_data[4];
640
    int i, planes;
641
 
642
    if (dst->width  < src->width ||
643
        dst->height < src->height)
644
        return AVERROR(EINVAL);
645
 
646
    planes = av_pix_fmt_count_planes(dst->format);
647
    for (i = 0; i < planes; i++)
648
        if (!dst->data[i] || !src->data[i])
649
            return AVERROR(EINVAL);
650
 
651
    memcpy(src_data, src->data, sizeof(src_data));
652
    av_image_copy(dst->data, dst->linesize,
653
                  src_data, src->linesize,
654
                  dst->format, src->width, src->height);
655
 
656
    return 0;
657
}
658
 
659
static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
660
{
661
    int planar   = av_sample_fmt_is_planar(dst->format);
662
    int channels = dst->channels;
663
    int planes   = planar ? channels : 1;
664
    int i;
665
 
666
    if (dst->nb_samples     != src->nb_samples ||
667
        dst->channels       != src->channels ||
668
        dst->channel_layout != src->channel_layout)
669
        return AVERROR(EINVAL);
670
 
671
    CHECK_CHANNELS_CONSISTENCY(src);
672
 
673
    for (i = 0; i < planes; i++)
674
        if (!dst->extended_data[i] || !src->extended_data[i])
675
            return AVERROR(EINVAL);
676
 
677
    av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
678
                    dst->nb_samples, channels, dst->format);
679
 
680
    return 0;
681
}
682
 
683
int av_frame_copy(AVFrame *dst, const AVFrame *src)
684
{
685
    if (dst->format != src->format || dst->format < 0)
686
        return AVERROR(EINVAL);
687
 
688
    if (dst->width > 0 && dst->height > 0)
689
        return frame_copy_video(dst, src);
690
    else if (dst->nb_samples > 0 && dst->channel_layout)
691
        return frame_copy_audio(dst, src);
692
 
693
    return AVERROR(EINVAL);
694
}
695
 
696
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
697
{
698
    int i;
699
 
700
    for (i = 0; i < frame->nb_side_data; i++) {
701
        AVFrameSideData *sd = frame->side_data[i];
702
        if (sd->type == type) {
703
            free_side_data(&frame->side_data[i]);
704
            frame->side_data[i] = frame->side_data[frame->nb_side_data - 1];
705
            frame->nb_side_data--;
706
        }
707
    }
708
}
709
 
710
const char *av_frame_side_data_name(enum AVFrameSideDataType type)
711
{
712
    switch(type) {
713
    case AV_FRAME_DATA_PANSCAN:         return "AVPanScan";
714
    case AV_FRAME_DATA_A53_CC:          return "ATSC A53 Part 4 Closed Captions";
715
    case AV_FRAME_DATA_STEREO3D:        return "Stereoscopic 3d metadata";
716
    case AV_FRAME_DATA_MATRIXENCODING:  return "AVMatrixEncoding";
717
    case AV_FRAME_DATA_DOWNMIX_INFO:    return "Metadata relevant to a downmix procedure";
718
    case AV_FRAME_DATA_REPLAYGAIN:      return "AVReplayGain";
719
    case AV_FRAME_DATA_DISPLAYMATRIX:   return "3x3 displaymatrix";
720
    case AV_FRAME_DATA_MOTION_VECTORS:  return "Motion vectors";
721
    }
722
    return NULL;
723
}