yading@11: /* yading@11: * Copyright 2007 Bobby Bingham yading@11: * Copyright Stefano Sabatini yading@11: * Copyright Vitor Sessak yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or yading@11: * modify it under the terms of the GNU Lesser General Public yading@11: * License as published by the Free Software Foundation; either yading@11: * version 2.1 of the License, or (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@11: * Lesser General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU Lesser General Public yading@11: * License along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: #include yading@11: #include yading@11: yading@11: #include "libavutil/avassert.h" yading@11: #include "libavutil/buffer.h" yading@11: #include "libavutil/imgutils.h" yading@11: #include "libavutil/mem.h" yading@11: yading@11: #include "avfilter.h" yading@11: #include "internal.h" yading@11: #include "video.h" yading@11: yading@11: AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h) yading@11: { yading@11: return ff_get_video_buffer(link->dst->outputs[0], w, h); yading@11: } yading@11: yading@11: /* TODO: set the buffer's priv member to a context structure for the whole yading@11: * filter chain. This will allow for a buffer pool instead of the constant yading@11: * alloc & free cycle currently implemented. */ yading@11: AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) yading@11: { yading@11: AVFrame *frame = av_frame_alloc(); yading@11: int ret; yading@11: yading@11: #if 0 //POOL yading@11: AVFilterPool *pool = link->pool; yading@11: if (pool) { yading@11: for (i = 0; i < POOL_SIZE; i++) { yading@11: picref = pool->pic[i]; yading@11: if (picref && picref->buf->format == link->format && picref->buf->w == w && picref->buf->h == h) { yading@11: AVFilterBuffer *pic = picref->buf; yading@11: pool->pic[i] = NULL; yading@11: pool->count--; yading@11: av_assert0(!picref->video->qp_table); yading@11: picref->video->w = w; yading@11: picref->video->h = h; yading@11: picref->perms = full_perms; yading@11: picref->format = link->format; yading@11: pic->refcount = 1; yading@11: memcpy(picref->data, pic->data, sizeof(picref->data)); yading@11: memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize)); yading@11: pool->refcount++; yading@11: return picref; yading@11: } yading@11: } yading@11: } else { yading@11: pool = link->pool = av_mallocz(sizeof(AVFilterPool)); yading@11: pool->refcount = 1; yading@11: } yading@11: #endif yading@11: if (!frame) yading@11: return NULL; yading@11: yading@11: frame->width = w; yading@11: frame->height = h; yading@11: frame->format = link->format; yading@11: yading@11: ret = av_frame_get_buffer(frame, 32); yading@11: if (ret < 0) yading@11: av_frame_free(&frame); yading@11: yading@11: #if 0 //POOL yading@11: memset(data[0], 128, i); yading@11: yading@11: picref->buf->priv = pool; yading@11: picref->buf->free = NULL; yading@11: pool->refcount++; yading@11: #endif yading@11: yading@11: return frame; yading@11: } yading@11: yading@11: #if FF_API_AVFILTERBUFFER yading@11: AVFilterBufferRef * yading@11: avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms, yading@11: int w, int h, enum AVPixelFormat format) yading@11: { yading@11: AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer)); yading@11: AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef)); yading@11: yading@11: if (!pic || !picref) yading@11: goto fail; yading@11: yading@11: picref->buf = pic; yading@11: picref->buf->free = ff_avfilter_default_free_buffer; yading@11: if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps)))) yading@11: goto fail; yading@11: yading@11: pic->w = picref->video->w = w; yading@11: pic->h = picref->video->h = h; yading@11: yading@11: /* make sure the buffer gets read permission or it's useless for output */ yading@11: picref->perms = perms | AV_PERM_READ; yading@11: yading@11: pic->refcount = 1; yading@11: picref->type = AVMEDIA_TYPE_VIDEO; yading@11: pic->format = picref->format = format; yading@11: yading@11: memcpy(pic->data, data, 4*sizeof(data[0])); yading@11: memcpy(pic->linesize, linesize, 4*sizeof(linesize[0])); yading@11: memcpy(picref->data, pic->data, sizeof(picref->data)); yading@11: memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize)); yading@11: yading@11: pic-> extended_data = pic->data; yading@11: picref->extended_data = picref->data; yading@11: yading@11: picref->pts = AV_NOPTS_VALUE; yading@11: yading@11: return picref; yading@11: yading@11: fail: yading@11: if (picref && picref->video) yading@11: av_free(picref->video); yading@11: av_free(picref); yading@11: av_free(pic); yading@11: return NULL; yading@11: } yading@11: #endif yading@11: yading@11: AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h) yading@11: { yading@11: AVFrame *ret = NULL; yading@11: yading@11: av_unused char buf[16]; yading@11: FF_TPRINTF_START(NULL, get_video_buffer); ff_tlog_link(NULL, link, 0); yading@11: yading@11: if (link->dstpad->get_video_buffer) yading@11: ret = link->dstpad->get_video_buffer(link, w, h); yading@11: yading@11: if (!ret) yading@11: ret = ff_default_get_video_buffer(link, w, h); yading@11: yading@11: return ret; yading@11: }