video.c 3.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * This file is part of Libav.
 *
 * Libav is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Libav is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

19
#include <string.h>
20
#include <stdio.h>
21

22
#include "libavutil/buffer.h"
23
#include "libavutil/imgutils.h"
24
#include "libavutil/mem.h"
25 26 27

#include "avfilter.h"
#include "internal.h"
28
#include "video.h"
29

30
AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
31
{
32
    return ff_get_video_buffer(link->dst->outputs[0], w, h);
33 34 35 36 37
}

/* TODO: set the buffer's priv member to a context structure for the whole
 * filter chain.  This will allow for a buffer pool instead of the constant
 * alloc & free cycle currently implemented. */
38
AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h)
39
{
40 41
    AVFrame *frame = av_frame_alloc();
    int ret;
42

43
    if (!frame)
44 45
        return NULL;

46 47 48
    frame->width  = w;
    frame->height = h;
    frame->format = link->format;
49

50 51 52 53 54
    ret = av_frame_get_buffer(frame, 32);
    if (ret < 0)
        av_frame_free(&frame);

    return frame;
55 56
}

57
#if FF_API_AVFILTERBUFFER
58 59
AVFilterBufferRef *
avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
60
                                          int w, int h, enum AVPixelFormat format)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
{
    AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
    AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));

    if (!pic || !picref)
        goto fail;

    picref->buf = pic;
    picref->buf->free = ff_avfilter_default_free_buffer;
    if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
        goto fail;

    pic->w = picref->video->w = w;
    pic->h = picref->video->h = h;

    /* make sure the buffer gets read permission or it's useless for output */
    picref->perms = perms | AV_PERM_READ;

    pic->refcount = 1;
    picref->type = AVMEDIA_TYPE_VIDEO;
    pic->format = picref->format = format;

    memcpy(pic->data,        data,          4*sizeof(data[0]));
    memcpy(pic->linesize,    linesize,      4*sizeof(linesize[0]));
    memcpy(picref->data,     pic->data,     sizeof(picref->data));
    memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));

    pic->   extended_data = pic->data;
    picref->extended_data = picref->data;

91 92
    picref->pts = AV_NOPTS_VALUE;

93 94 95 96 97 98 99 100 101
    return picref;

fail:
    if (picref && picref->video)
        av_free(picref->video);
    av_free(picref);
    av_free(pic);
    return NULL;
}
102
#endif
103

104
AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h)
105
{
106
    AVFrame *ret = NULL;
107 108 109 110 111

    av_unused char buf[16];
    FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);

    if (link->dstpad->get_video_buffer)
112
        ret = link->dstpad->get_video_buffer(link, w, h);
113 114

    if (!ret)
115
        ret = ff_default_get_video_buffer(link, w, h);
116 117 118

    return ret;
}