| @@ -20,6 +20,7 @@ · 19 unmodified lines |
| 20 | | 20 | |
| 21 | #include "framepool.h" | 21 | #include "framepool.h" |
| 22 | #include "libavutil/avassert.h" | 22 | #include "libavutil/avassert.h" |
| | 23 | #include "libavutil/avutil.h" |
| 23 | #include "libavutil/buffer.h" | 24 | #include "libavutil/buffer.h" |
| 24 | #include "libavutil/frame.h" | 25 | #include "libavutil/frame.h" |
| 25 | #include "libavutil/imgutils.h" | 26 | #include "libavutil/imgutils.h" |
| @@ -28,8 +29,18 @@ · 2 unmodified lines |
| 28 | | 29 | |
| 29 | struct FFFramePool { | 30 | struct FFFramePool { |
| 30 | | 31 | |
| | 32 | enum AVMediaType type; |
| | 33 | |
| | 34 | /* video */ |
| 31 | int width; | 35 | int width; |
| 32 | int height; | 36 | int height; |
| | 37 | |
| | 38 | /* audio */ |
| | 39 | int planes; |
| | 40 | int channels; |
| | 41 | int nb_samples; |
| | 42 | |
| | 43 | /* common */ |
| 33 | int format; | 44 | int format; |
| 34 | int align; | 45 | int align; |
| 35 | int linesize[4]; | 46 | int linesize[4]; |
| @@ -54,6 +65,7 @@ FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size), · 18 unmodified lines |
| 54 | if (!pool) | 65 | if (!pool) |
| 55 | return NULL; | 66 | return NULL; |
| 56 | | 67 | |
| | 68 | pool->type = AVMEDIA_TYPE_VIDEO; |
| 57 | pool->width = width; | 69 | pool->width = width; |
| 58 | pool->height = height; | 70 | pool->height = height; |
| 59 | pool->format = format; | 71 | pool->format = format; |
| @@ -104,6 +116,44 @@ fail: · 44 unmodified lines |
| 104 | return NULL; | 116 | return NULL; |
| 105 | } | 117 | } |
| 106 | | 118 | |
| | 119 | FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size), |
| | 120 | int channels, |
| | 121 | int nb_samples, |
| | 122 | enum AVSampleFormat format, |
| | 123 | int align) |
| | 124 | { |
| | 125 | int ret, planar; |
| | 126 | FFFramePool *pool; |
| | 127 | |
| | 128 | pool = av_mallocz(sizeof(FFFramePool)); |
| | 129 | if (!pool) |
| | 130 | return NULL; |
| | 131 | |
| | 132 | planar = av_sample_fmt_is_planar(format); |
| | 133 | |
| | 134 | pool->type = AVMEDIA_TYPE_AUDIO; |
| | 135 | pool->planes = planar ? channels : 1; |
| | 136 | pool->channels = channels; |
| | 137 | pool->nb_samples = nb_samples; |
| | 138 | pool->format = format; |
| | 139 | pool->align = align; |
| | 140 | |
| | 141 | ret = av_samples_get_buffer_size(&pool->linesize[0], channels, |
| | 142 | nb_samples, format, 0); |
| | 143 | if (ret < 0) |
| | 144 | goto fail; |
| | 145 | |
| | 146 | pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); |
| | 147 | if (!pool->pools[0]) |
| | 148 | goto fail; |
| | 149 | |
| | 150 | return pool; |
| | 151 | |
| | 152 | fail: |
| | 153 | ff_frame_pool_uninit(&pool); |
| | 154 | return NULL; |
| | 155 | } |
| | 156 | |
| 107 | int ff_frame_pool_get_video_config(FFFramePool *pool, | 157 | int ff_frame_pool_get_video_config(FFFramePool *pool, |
| 108 | int *width, | 158 | int *width, |
| 109 | int *height, | 159 | int *height, |
| @@ -113,6 +163,8 @@ int ff_frame_pool_get_video_config(FFFramePool *pool, · 3 unmodified lines |
| 113 | if (!pool) | 163 | if (!pool) |
| 114 | return AVERROR(EINVAL); | 164 | return AVERROR(EINVAL); |
| 115 | | 165 | |
| | 166 | av_assert0(pool->type == AVMEDIA_TYPE_VIDEO); |
| | 167 | |
| 116 | *width = pool->width; | 168 | *width = pool->width; |
| 117 | *height = pool->height; | 169 | *height = pool->height; |
| 118 | *format = pool->format; | 170 | *format = pool->format; |
| @@ -121,6 +173,24 @@ int ff_frame_pool_get_video_config(FFFramePool *pool, · 2 unmodified lines |
| 121 | return 0; | 173 | return 0; |
| 122 | } | 174 | } |
| 123 | | 175 | |
| | 176 | int ff_frame_pool_get_audio_config(FFFramePool *pool, |
| | 177 | int *channels, |
| | 178 | int *nb_samples, |
| | 179 | enum AVSampleFormat *format, |
| | 180 | int *align) |
| | 181 | { |
| | 182 | if (!pool) |
| | 183 | return AVERROR(EINVAL); |
| | 184 | |
| | 185 | av_assert0(pool->type == AVMEDIA_TYPE_AUDIO); |
| | 186 | |
| | 187 | *channels = pool->channels; |
| | 188 | *nb_samples = pool->nb_samples; |
| | 189 | *format = pool->format; |
| | 190 | *align = pool->align; |
| | 191 | |
| | 192 | return 0; |
| | 193 | } |
| 124 | | 194 | |
| 125 | AVFrame *ff_frame_pool_get(FFFramePool *pool) | 195 | AVFrame *ff_frame_pool_get(FFFramePool *pool) |
| 126 | { | 196 | { |
| @@ -133,6 +203,8 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool) · 6 unmodified lines |
| 133 | return NULL; | 203 | return NULL; |
| 134 | } | 204 | } |
| 135 | | 205 | |
| | 206 | switch(pool->type) { |
| | 207 | case AVMEDIA_TYPE_VIDEO: |
| 136 | desc = av_pix_fmt_desc_get(pool->format); | 208 | desc = av_pix_fmt_desc_get(pool->format); |
| 137 | if (!desc) { | 209 | if (!desc) { |
| 138 | goto fail; | 210 | goto fail; |
| @@ -167,6 +239,43 @@ AVFrame *ff_frame_pool_get(FFFramePool *pool) · 28 unmodified lines |
| 167 | } | 239 | } |
| 168 | | 240 | |
| 169 | frame->extended_data = frame->data; | 241 | frame->extended_data = frame->data; |
| | 242 | break; |
| | 243 | case AVMEDIA_TYPE_AUDIO: |
| | 244 | frame->nb_samples = pool->nb_samples; |
| | 245 | av_frame_set_channels(frame, pool->channels); |
| | 246 | frame->format = pool->format; |
| | 247 | frame->linesize[0] = pool->linesize[0]; |
| | 248 | |
| | 249 | if (pool->planes > AV_NUM_DATA_POINTERS) { |
| | 250 | frame->extended_data = av_mallocz_array(pool->planes, |
| | 251 | sizeof(*frame->extended_data)); |
| | 252 | frame->nb_extended_buf = pool->planes - AV_NUM_DATA_POINTERS; |
| | 253 | frame->extended_buf = av_mallocz_array(frame->nb_extended_buf, |
| | 254 | sizeof(*frame->extended_buf)); |
| | 255 | if (!frame->extended_data || !frame->extended_buf) |
| | 256 | goto fail; |
| | 257 | } else { |
| | 258 | frame->extended_data = frame->data; |
| | 259 | av_assert0(frame->nb_extended_buf == 0); |
| | 260 | } |
| | 261 | |
| | 262 | for (i = 0; i < FFMIN(pool->planes, AV_NUM_DATA_POINTERS); i++) { |
| | 263 | frame->buf[i] = av_buffer_pool_get(pool->pools[0]); |
| | 264 | if (!frame->buf[i]) |
| | 265 | goto fail; |
| | 266 | frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; |
| | 267 | } |
| | 268 | for (i = 0; i < frame->nb_extended_buf; i++) { |
| | 269 | frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); |
| | 270 | if (!frame->extended_buf[i]) |
| | 271 | goto fail; |
| | 272 | frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; |
| | 273 | } |
| | 274 | |
| | 275 | break; |
| | 276 | default: |
| | 277 | av_assert0(0); |
| | 278 | } |
| 170 | | 279 | |
| 171 | return frame; | 280 | return frame; |
| 172 | fail: | 281 | fail: |