LCOV - code coverage report
Current view: top level - src/libavfilter - framepool.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 106 137 77.4 %
Date: 2017-01-24 04:42:20 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of FFmpeg.
       3             :  *
       4             :  * Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com>
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include "framepool.h"
      22             : #include "libavutil/avassert.h"
      23             : #include "libavutil/avutil.h"
      24             : #include "libavutil/buffer.h"
      25             : #include "libavutil/frame.h"
      26             : #include "libavutil/imgutils.h"
      27             : #include "libavutil/mem.h"
      28             : #include "libavutil/pixfmt.h"
      29             : 
      30             : struct FFFramePool {
      31             : 
      32             :     enum AVMediaType type;
      33             : 
      34             :     /* video */
      35             :     int width;
      36             :     int height;
      37             : 
      38             :     /* audio */
      39             :     int planes;
      40             :     int channels;
      41             :     int nb_samples;
      42             : 
      43             :     /* common */
      44             :     int format;
      45             :     int align;
      46             :     int linesize[4];
      47             :     AVBufferPool *pools[4];
      48             : 
      49             : };
      50             : 
      51        3499 : FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size),
      52             :                                       int width,
      53             :                                       int height,
      54             :                                       enum AVPixelFormat format,
      55             :                                       int align)
      56             : {
      57             :     int i, ret;
      58             :     FFFramePool *pool;
      59        3499 :     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
      60             : 
      61        3499 :     if (!desc)
      62           0 :         return NULL;
      63             : 
      64        3499 :     pool = av_mallocz(sizeof(FFFramePool));
      65        3499 :     if (!pool)
      66           0 :         return NULL;
      67             : 
      68        3499 :     pool->type = AVMEDIA_TYPE_VIDEO;
      69        3499 :     pool->width = width;
      70        3499 :     pool->height = height;
      71        3499 :     pool->format = format;
      72        3499 :     pool->align = align;
      73             : 
      74        3499 :     if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) {
      75           0 :         goto fail;
      76             :     }
      77             : 
      78        3499 :     if (!pool->linesize[0]) {
      79        5532 :         for(i = 1; i <= align; i += i) {
      80        5496 :             ret = av_image_fill_linesizes(pool->linesize, pool->format,
      81        5496 :                                           FFALIGN(pool->width, i));
      82        5496 :             if (ret < 0) {
      83           0 :                 goto fail;
      84             :             }
      85        5496 :             if (!(pool->linesize[0] & (pool->align - 1)))
      86        3463 :                 break;
      87             :         }
      88             : 
      89       12004 :         for (i = 0; i < 4 && pool->linesize[i]; i++) {
      90        8505 :             pool->linesize[i] = FFALIGN(pool->linesize[i], pool->align);
      91             :         }
      92             :     }
      93             : 
      94       12004 :     for (i = 0; i < 4 && pool->linesize[i]; i++) {
      95        8505 :         int h = FFALIGN(pool->height, 32);
      96        8505 :         if (i == 1 || i == 2)
      97        4500 :             h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
      98             : 
      99        8505 :         pool->pools[i] = av_buffer_pool_init(pool->linesize[i] * h + 16 + 16 - 1,
     100             :                                              alloc);
     101        8505 :         if (!pool->pools[i])
     102           0 :             goto fail;
     103             :     }
     104             : 
     105        6984 :     if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
     106        3485 :         desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
     107         120 :         pool->pools[1] = av_buffer_pool_init(AVPALETTE_SIZE, alloc);
     108         120 :         if (!pool->pools[1])
     109           0 :             goto fail;
     110             :     }
     111             : 
     112        3499 :     return pool;
     113             : 
     114             : fail:
     115           0 :     ff_frame_pool_uninit(&pool);
     116           0 :     return NULL;
     117             : }
     118             : 
     119        2793 : 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        2793 :     pool = av_mallocz(sizeof(FFFramePool));
     129        2793 :     if (!pool)
     130           0 :         return NULL;
     131             : 
     132        2793 :     planar = av_sample_fmt_is_planar(format);
     133             : 
     134        2793 :     pool->type = AVMEDIA_TYPE_AUDIO;
     135        2793 :     pool->planes = planar ? channels : 1;
     136        2793 :     pool->channels = channels;
     137        2793 :     pool->nb_samples = nb_samples;
     138        2793 :     pool->format = format;
     139        2793 :     pool->align = align;
     140             : 
     141        2793 :     ret = av_samples_get_buffer_size(&pool->linesize[0], channels,
     142             :                                      nb_samples, format, 0);
     143        2793 :     if (ret < 0)
     144           0 :         goto fail;
     145             : 
     146        2793 :     pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
     147        2793 :     if (!pool->pools[0])
     148           0 :         goto fail;
     149             : 
     150        2793 :     return pool;
     151             : 
     152             : fail:
     153           0 :     ff_frame_pool_uninit(&pool);
     154           0 :     return NULL;
     155             : }
     156             : 
     157       37118 : int ff_frame_pool_get_video_config(FFFramePool *pool,
     158             :                                    int *width,
     159             :                                    int *height,
     160             :                                    enum AVPixelFormat *format,
     161             :                                    int *align)
     162             : {
     163       37118 :     if (!pool)
     164           0 :         return AVERROR(EINVAL);
     165             : 
     166       37118 :     av_assert0(pool->type == AVMEDIA_TYPE_VIDEO);
     167             : 
     168       37118 :     *width = pool->width;
     169       37118 :     *height = pool->height;
     170       37118 :     *format = pool->format;
     171       37118 :     *align = pool->align;
     172             : 
     173       37118 :     return 0;
     174             : }
     175             : 
     176      285853 : 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      285853 :     if (!pool)
     183           0 :         return AVERROR(EINVAL);
     184             : 
     185      285853 :     av_assert0(pool->type == AVMEDIA_TYPE_AUDIO);
     186             : 
     187      285853 :     *channels = pool->channels;
     188      285853 :     *nb_samples = pool->nb_samples;
     189      285853 :     *format = pool->format;
     190      285853 :     *align = pool->align;
     191             : 
     192      285853 :     return 0;
     193             : }
     194             : 
     195      327646 : AVFrame *ff_frame_pool_get(FFFramePool *pool)
     196             : {
     197             :     int i;
     198             :     AVFrame *frame;
     199             :     const AVPixFmtDescriptor *desc;
     200             : 
     201      327646 :     frame = av_frame_alloc();
     202      327646 :     if (!frame) {
     203           0 :         return NULL;
     204             :     }
     205             : 
     206      327646 :     switch(pool->type) {
     207             :     case AVMEDIA_TYPE_VIDEO:
     208       40616 :         desc = av_pix_fmt_desc_get(pool->format);
     209       40616 :         if (!desc) {
     210           0 :             goto fail;
     211             :         }
     212             : 
     213       40616 :         frame->width = pool->width;
     214       40616 :         frame->height = pool->height;
     215       40616 :         frame->format = pool->format;
     216             : 
     217      132703 :         for (i = 0; i < 4; i++) {
     218      130922 :             frame->linesize[i] = pool->linesize[i];
     219      130922 :             if (!pool->pools[i])
     220       38835 :                 break;
     221             : 
     222       92087 :             frame->buf[i] = av_buffer_pool_get(pool->pools[i]);
     223       92087 :             if (!frame->buf[i])
     224           0 :                 goto fail;
     225             : 
     226       92087 :             frame->data[i] = frame->buf[i]->data;
     227             :         }
     228             : 
     229       80836 :         if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
     230       40220 :             desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
     231        1952 :             enum AVPixelFormat format =
     232        1952 :                 pool->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : pool->format;
     233             : 
     234        1952 :             av_assert0(frame->data[1] != NULL);
     235        1952 :             if (avpriv_set_systematic_pal2((uint32_t *)frame->data[1], format) < 0)
     236           0 :                 goto fail;
     237             :         }
     238             : 
     239       40616 :         frame->extended_data = frame->data;
     240       40616 :         break;
     241             :     case AVMEDIA_TYPE_AUDIO:
     242      287030 :         frame->nb_samples = pool->nb_samples;
     243      287030 :         av_frame_set_channels(frame, pool->channels);
     244      287030 :         frame->format = pool->format;
     245      287030 :         frame->linesize[0] = pool->linesize[0];
     246             : 
     247      287030 :         if (pool->planes > AV_NUM_DATA_POINTERS) {
     248           0 :             frame->extended_data = av_mallocz_array(pool->planes,
     249             :                                                     sizeof(*frame->extended_data));
     250           0 :             frame->nb_extended_buf = pool->planes - AV_NUM_DATA_POINTERS;
     251           0 :             frame->extended_buf = av_mallocz_array(frame->nb_extended_buf,
     252             :                                                    sizeof(*frame->extended_buf));
     253           0 :             if (!frame->extended_data || !frame->extended_buf)
     254             :                 goto fail;
     255             :         } else {
     256      287030 :             frame->extended_data = frame->data;
     257      287030 :             av_assert0(frame->nb_extended_buf == 0);
     258             :         }
     259             : 
     260      620373 :         for (i = 0; i < FFMIN(pool->planes, AV_NUM_DATA_POINTERS); i++) {
     261      333343 :             frame->buf[i] = av_buffer_pool_get(pool->pools[0]);
     262      333343 :             if (!frame->buf[i])
     263           0 :                 goto fail;
     264      333343 :             frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
     265             :         }
     266      287030 :         for (i = 0; i < frame->nb_extended_buf; i++) {
     267           0 :             frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]);
     268           0 :             if (!frame->extended_buf[i])
     269           0 :                 goto fail;
     270           0 :             frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
     271             :         }
     272             : 
     273      287030 :         break;
     274             :     default:
     275           0 :         av_assert0(0);
     276             :     }
     277             : 
     278      327646 :     return frame;
     279             : fail:
     280           0 :     av_frame_free(&frame);
     281           0 :     return NULL;
     282             : }
     283             : 
     284       22026 : void ff_frame_pool_uninit(FFFramePool **pool)
     285             : {
     286             :     int i;
     287             : 
     288       22026 :     if (!pool || !*pool)
     289       15734 :         return;
     290             : 
     291       31460 :     for (i = 0; i < 4; i++) {
     292       25168 :         av_buffer_pool_uninit(&(*pool)->pools[i]);
     293             :     }
     294             : 
     295        6292 :     av_freep(pool);
     296             : }

Generated by: LCOV version 1.12