Browse code

lavfi/framepool: add audio support

Matthieu Bouron authored on 2017/01/04 01:44:07
Showing 2 changed files
... ...
@@ -20,6 +20,7 @@
20 20
 
21 21
 #include "framepool.h"
22 22
 #include "libavutil/avassert.h"
23
+#include "libavutil/avutil.h"
23 24
 #include "libavutil/buffer.h"
24 25
 #include "libavutil/frame.h"
25 26
 #include "libavutil/imgutils.h"
... ...
@@ -28,8 +29,18 @@
28 28
 
29 29
 struct FFFramePool {
30 30
 
31
+    enum AVMediaType type;
32
+
33
+    /* video */
31 34
     int width;
32 35
     int height;
36
+
37
+    /* audio */
38
+    int planes;
39
+    int channels;
40
+    int nb_samples;
41
+
42
+    /* common */
33 43
     int format;
34 44
     int align;
35 45
     int linesize[4];
... ...
@@ -54,6 +65,7 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size),
54 54
     if (!pool)
55 55
         return NULL;
56 56
 
57
+    pool->type = AVMEDIA_TYPE_VIDEO;
57 58
     pool->width = width;
58 59
     pool->height = height;
59 60
     pool->format = format;
... ...
@@ -104,6 +116,44 @@ fail:
104 104
     return NULL;
105 105
 }
106 106
 
107
+FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size),
108
+                                      int channels,
109
+                                      int nb_samples,
110
+                                      enum AVSampleFormat format,
111
+                                      int align)
112
+{
113
+    int ret, planar;
114
+    FFFramePool *pool;
115
+
116
+    pool = av_mallocz(sizeof(FFFramePool));
117
+    if (!pool)
118
+        return NULL;
119
+
120
+    planar = av_sample_fmt_is_planar(format);
121
+
122
+    pool->type = AVMEDIA_TYPE_AUDIO;
123
+    pool->planes = planar ? channels : 1;
124
+    pool->channels = channels;
125
+    pool->nb_samples = nb_samples;
126
+    pool->format = format;
127
+    pool->align = align;
128
+
129
+    ret = av_samples_get_buffer_size(&pool->linesize[0], channels,
130
+                                     nb_samples, format, 0);
131
+    if (ret < 0)
132
+        goto fail;
133
+
134
+    pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
135
+    if (!pool->pools[0])
136
+        goto fail;
137
+
138
+    return pool;
139
+
140
+fail:
141
+    ff_frame_pool_uninit(&pool);
142
+    return NULL;
143
+}
144
+
107 145
 int ff_frame_pool_get_video_config(FFFramePool *pool,
108 146
                                    int *width,
109 147
                                    int *height,
... ...
@@ -113,6 +163,8 @@ int ff_frame_pool_get_video_config(FFFramePool *pool,
113 113
     if (!pool)
114 114
         return AVERROR(EINVAL);
115 115
 
116
+    av_assert0(pool->type == AVMEDIA_TYPE_VIDEO);
117
+
116 118
     *width = pool->width;
117 119
     *height = pool->height;
118 120
     *format = pool->format;
... ...
@@ -121,6 +173,24 @@ int ff_frame_pool_get_video_config(FFFramePool *pool,
121 121
     return 0;
122 122
 }
123 123
 
124
+int ff_frame_pool_get_audio_config(FFFramePool *pool,
125
+                                   int *channels,
126
+                                   int *nb_samples,
127
+                                   enum AVSampleFormat *format,
128
+                                   int *align)
129
+{
130
+    if (!pool)
131
+        return AVERROR(EINVAL);
132
+
133
+    av_assert0(pool->type == AVMEDIA_TYPE_AUDIO);
134
+
135
+    *channels = pool->channels;
136
+    *nb_samples = pool->nb_samples;
137
+    *format = pool->format;
138
+    *align = pool->align;
139
+
140
+    return 0;
141
+}
124 142
 
125 143
 AVFrame *ff_frame_pool_get(FFFramePool *pool)
126 144
 {
... ...
@@ -133,6 +203,8 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool)
133 133
         return NULL;
134 134
     }
135 135
 
136
+    switch(pool->type) {
137
+    case AVMEDIA_TYPE_VIDEO:
136 138
     desc = av_pix_fmt_desc_get(pool->format);
137 139
     if (!desc) {
138 140
         goto fail;
... ...
@@ -167,6 +239,43 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool)
167 167
     }
168 168
 
169 169
     frame->extended_data = frame->data;
170
+    break;
171
+    case AVMEDIA_TYPE_AUDIO:
172
+        frame->nb_samples = pool->nb_samples;
173
+        av_frame_set_channels(frame, pool->channels);
174
+        frame->format = pool->format;
175
+        frame->linesize[0] = pool->linesize[0];
176
+
177
+        if (pool->planes > AV_NUM_DATA_POINTERS) {
178
+            frame->extended_data = av_mallocz_array(pool->planes,
179
+                                                    sizeof(*frame->extended_data));
180
+            frame->nb_extended_buf = pool->planes - AV_NUM_DATA_POINTERS;
181
+            frame->extended_buf = av_mallocz_array(frame->nb_extended_buf,
182
+                                                   sizeof(*frame->extended_buf));
183
+            if (!frame->extended_data || !frame->extended_buf)
184
+                goto fail;
185
+        } else {
186
+            frame->extended_data = frame->data;
187
+            av_assert0(frame->nb_extended_buf == 0);
188
+        }
189
+
190
+        for (i = 0; i < FFMIN(pool->planes, AV_NUM_DATA_POINTERS); i++) {
191
+            frame->buf[i] = av_buffer_pool_get(pool->pools[0]);
192
+            if (!frame->buf[i])
193
+                goto fail;
194
+            frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
195
+        }
196
+        for (i = 0; i < frame->nb_extended_buf; i++) {
197
+            frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]);
198
+            if (!frame->extended_buf[i])
199
+                goto fail;
200
+            frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
201
+        }
202
+
203
+        break;
204
+    default:
205
+        av_assert0(0);
206
+    }
170 207
 
171 208
     return frame;
172 209
 fail:
... ...
@@ -41,7 +41,7 @@ typedef struct FFFramePool FFFramePool;
41 41
  * @param height height of each frame in this pool
42 42
  * @param format format of each frame in this pool
43 43
  * @param align buffers alignement of each frame in this pool
44
- * @return newly created frame pool on success, NULL on error.
44
+ * @return newly created video frame pool on success, NULL on error.
45 45
  */
46 46
 FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size),
47 47
                                       int width,
... ...
@@ -50,6 +50,24 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size),
50 50
                                       int align);
51 51
 
52 52
 /**
53
+ * Allocate and initialize an audio frame pool.
54
+ *
55
+ * @param alloc a function that will be used to allocate new frame buffers when
56
+ * the pool is empty. May be NULL, then the default allocator will be used
57
+ * (av_buffer_alloc()).
58
+ * @param channels channels of each frame in this pool
59
+ * @param nb_samples number of samples of each frame in this pool
60
+ * @param format format of each frame in this pool
61
+ * @param align buffers alignement of each frame in this pool
62
+ * @return newly created audio frame pool on success, NULL on error.
63
+ */
64
+FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size),
65
+                                      int channels,
66
+                                      int samples,
67
+                                      enum AVSampleFormat format,
68
+                                      int align);
69
+
70
+/**
53 71
  * Deallocate the frame pool. It is safe to call this function while
54 72
  * some of the allocated frame are still in use.
55 73
  *
... ...
@@ -73,6 +91,22 @@ int ff_frame_pool_get_video_config(FFFramePool *pool,
73 73
                                    int *align);
74 74
 
75 75
 /**
76
+ * Get the audio frame pool configuration.
77
+ *
78
+ * @param channels channels of each frame in this pool
79
+ * @param nb_samples number of samples of each frame in this pool
80
+ * @param format format of each frame in this pool
81
+ * @param align buffers alignement of each frame in this pool
82
+ * @return 0 on success, a negative AVERROR otherwise.
83
+ */
84
+int ff_frame_pool_get_audio_config(FFFramePool *pool,
85
+                                   int *channels,
86
+                                   int *nb_samples,
87
+                                   enum AVSampleFormat *format,
88
+                                   int *align);
89
+
90
+
91
+/**
76 92
  * Allocate a new AVFrame, reussing old buffers from the pool when available.
77 93
  * This function may be called simultaneously from multiple threads.
78 94
  *