Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Copyright (c) Stefano Sabatini | stefasab at gmail.com
3
 * Copyright (c) S.N. Hemanth Meenakshisundaram | smeenaks at ucsd.edu
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 "libavutil/avassert.h"
23
#include "libavutil/channel_layout.h"
24
#include "libavutil/common.h"
25
#include "libavcodec/avcodec.h"
26
 
27
#include "audio.h"
28
#include "avfilter.h"
29
#include "internal.h"
30
 
31
int avfilter_ref_get_channels(AVFilterBufferRef *ref)
32
{
33
    return ref->audio ? ref->audio->channels : 0;
34
}
35
 
36
AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
37
{
38
    return ff_get_audio_buffer(link->dst->outputs[0], nb_samples);
39
}
40
 
41
AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples)
42
{
43
    AVFrame *frame = av_frame_alloc();
44
    int channels = link->channels;
45
    int ret;
46
 
47
    av_assert0(channels == av_get_channel_layout_nb_channels(link->channel_layout) || !av_get_channel_layout_nb_channels(link->channel_layout));
48
 
49
    if (!frame)
50
        return NULL;
51
 
52
    frame->nb_samples     = nb_samples;
53
    frame->format         = link->format;
54
    av_frame_set_channels(frame, link->channels);
55
    frame->channel_layout = link->channel_layout;
56
    frame->sample_rate    = link->sample_rate;
57
    ret = av_frame_get_buffer(frame, 0);
58
    if (ret < 0) {
59
        av_frame_free(&frame);
60
        return NULL;
61
    }
62
 
63
    av_samples_set_silence(frame->extended_data, 0, nb_samples, channels,
64
                           link->format);
65
 
66
 
67
    return frame;
68
}
69
 
70
AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
71
{
72
    AVFrame *ret = NULL;
73
 
74
    if (link->dstpad->get_audio_buffer)
75
        ret = link->dstpad->get_audio_buffer(link, nb_samples);
76
 
77
    if (!ret)
78
        ret = ff_default_get_audio_buffer(link, nb_samples);
79
 
80
    return ret;
81
}
82
 
83
#if FF_API_AVFILTERBUFFER
84
AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
85
                                                                      int linesize,int perms,
86
                                                                      int nb_samples,
87
                                                                      enum AVSampleFormat sample_fmt,
88
                                                                      int channels,
89
                                                                      uint64_t channel_layout)
90
{
91
    int planes;
92
    AVFilterBuffer    *samples    = av_mallocz(sizeof(*samples));
93
    AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
94
 
95
    if (!samples || !samplesref)
96
        goto fail;
97
 
98
    av_assert0(channels);
99
    av_assert0(channel_layout == 0 ||
100
               channels == av_get_channel_layout_nb_channels(channel_layout));
101
 
102
    samplesref->buf         = samples;
103
    samplesref->buf->free   = ff_avfilter_default_free_buffer;
104
    if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
105
        goto fail;
106
 
107
    samplesref->audio->nb_samples     = nb_samples;
108
    samplesref->audio->channel_layout = channel_layout;
109
    samplesref->audio->channels       = channels;
110
 
111
    planes = av_sample_fmt_is_planar(sample_fmt) ? channels : 1;
112
 
113
    /* make sure the buffer gets read permission or it's useless for output */
114
    samplesref->perms = perms | AV_PERM_READ;
115
 
116
    samples->refcount  = 1;
117
    samplesref->type   = AVMEDIA_TYPE_AUDIO;
118
    samplesref->format = sample_fmt;
119
 
120
    memcpy(samples->data, data,
121
           FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
122
    memcpy(samplesref->data, samples->data, sizeof(samples->data));
123
 
124
    samples->linesize[0] = samplesref->linesize[0] = linesize;
125
 
126
    if (planes > FF_ARRAY_ELEMS(samples->data)) {
127
        samples->   extended_data = av_mallocz(sizeof(*samples->extended_data) *
128
                                               planes);
129
        samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) *
130
                                               planes);
131
 
132
        if (!samples->extended_data || !samplesref->extended_data)
133
            goto fail;
134
 
135
        memcpy(samples->   extended_data, data, sizeof(*data)*planes);
136
        memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
137
    } else {
138
        samples->extended_data    = samples->data;
139
        samplesref->extended_data = samplesref->data;
140
    }
141
 
142
    samplesref->pts = AV_NOPTS_VALUE;
143
 
144
    return samplesref;
145
 
146
fail:
147
    if (samples && samples->extended_data != samples->data)
148
        av_freep(&samples->extended_data);
149
    if (samplesref) {
150
        av_freep(&samplesref->audio);
151
        if (samplesref->extended_data != samplesref->data)
152
            av_freep(&samplesref->extended_data);
153
    }
154
    av_freep(&samplesref);
155
    av_freep(&samples);
156
    return NULL;
157
}
158
 
159
AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
160
                                                             int linesize,int perms,
161
                                                             int nb_samples,
162
                                                             enum AVSampleFormat sample_fmt,
163
                                                             uint64_t channel_layout)
164
{
165
    int channels = av_get_channel_layout_nb_channels(channel_layout);
166
    return avfilter_get_audio_buffer_ref_from_arrays_channels(data, linesize, perms,
167
                                                              nb_samples, sample_fmt,
168
                                                              channels, channel_layout);
169
}
170
#endif