mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Merge commit 'f6974fe651d29ef6eb68d66d73f7b6c011062aa0'
* commit 'f6974fe651d29ef6eb68d66d73f7b6c011062aa0': lavfi: Drop deprecated AVFilterBuffer* code Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
commit
033764e015
@ -14,7 +14,6 @@ OBJS = allfilters.o \
|
||||
audio.o \
|
||||
avfilter.o \
|
||||
avfiltergraph.o \
|
||||
buffer.o \
|
||||
buffersink.o \
|
||||
buffersrc.o \
|
||||
drawutils.o \
|
||||
|
@ -28,15 +28,6 @@
|
||||
#include "avfilter.h"
|
||||
#include "internal.h"
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
int avfilter_ref_get_channels(AVFilterBufferRef *ref)
|
||||
{
|
||||
return ref->audio ? ref->audio->channels : 0;
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
|
||||
{
|
||||
return ff_get_audio_buffer(link->dst->outputs[0], nb_samples);
|
||||
@ -83,94 +74,3 @@ AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
|
||||
int linesize,int perms,
|
||||
int nb_samples,
|
||||
enum AVSampleFormat sample_fmt,
|
||||
int channels,
|
||||
uint64_t channel_layout)
|
||||
{
|
||||
int planes;
|
||||
AVFilterBuffer *samples = av_mallocz(sizeof(*samples));
|
||||
AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref));
|
||||
|
||||
if (!samples || !samplesref)
|
||||
goto fail;
|
||||
|
||||
av_assert0(channels);
|
||||
av_assert0(channel_layout == 0 ||
|
||||
channels == av_get_channel_layout_nb_channels(channel_layout));
|
||||
|
||||
samplesref->buf = samples;
|
||||
samplesref->buf->free = ff_avfilter_default_free_buffer;
|
||||
if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio))))
|
||||
goto fail;
|
||||
|
||||
samplesref->audio->nb_samples = nb_samples;
|
||||
samplesref->audio->channel_layout = channel_layout;
|
||||
samplesref->audio->channels = channels;
|
||||
|
||||
planes = av_sample_fmt_is_planar(sample_fmt) ? channels : 1;
|
||||
|
||||
/* make sure the buffer gets read permission or it's useless for output */
|
||||
samplesref->perms = perms | AV_PERM_READ;
|
||||
|
||||
samples->refcount = 1;
|
||||
samplesref->type = AVMEDIA_TYPE_AUDIO;
|
||||
samplesref->format = sample_fmt;
|
||||
|
||||
memcpy(samples->data, data,
|
||||
FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0]));
|
||||
memcpy(samplesref->data, samples->data, sizeof(samples->data));
|
||||
|
||||
samples->linesize[0] = samplesref->linesize[0] = linesize;
|
||||
|
||||
if (planes > FF_ARRAY_ELEMS(samples->data)) {
|
||||
samples-> extended_data = av_mallocz_array(sizeof(*samples->extended_data),
|
||||
planes);
|
||||
samplesref->extended_data = av_mallocz_array(sizeof(*samplesref->extended_data),
|
||||
planes);
|
||||
|
||||
if (!samples->extended_data || !samplesref->extended_data)
|
||||
goto fail;
|
||||
|
||||
memcpy(samples-> extended_data, data, sizeof(*data)*planes);
|
||||
memcpy(samplesref->extended_data, data, sizeof(*data)*planes);
|
||||
} else {
|
||||
samples->extended_data = samples->data;
|
||||
samplesref->extended_data = samplesref->data;
|
||||
}
|
||||
|
||||
samplesref->pts = AV_NOPTS_VALUE;
|
||||
|
||||
return samplesref;
|
||||
|
||||
fail:
|
||||
if (samples && samples->extended_data != samples->data)
|
||||
av_freep(&samples->extended_data);
|
||||
if (samplesref) {
|
||||
av_freep(&samplesref->audio);
|
||||
if (samplesref->extended_data != samplesref->data)
|
||||
av_freep(&samplesref->extended_data);
|
||||
}
|
||||
av_freep(&samplesref);
|
||||
av_freep(&samples);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
|
||||
int linesize,int perms,
|
||||
int nb_samples,
|
||||
enum AVSampleFormat sample_fmt,
|
||||
uint64_t channel_layout)
|
||||
{
|
||||
int channels = av_get_channel_layout_nb_channels(channel_layout);
|
||||
return avfilter_get_audio_buffer_ref_from_arrays_channels(data, linesize, perms,
|
||||
nb_samples, sample_fmt,
|
||||
channels, channel_layout);
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
@ -66,182 +66,6 @@ typedef struct AVFilterLink AVFilterLink;
|
||||
typedef struct AVFilterPad AVFilterPad;
|
||||
typedef struct AVFilterFormats AVFilterFormats;
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* A reference-counted buffer data type used by the filter system. Filters
|
||||
* should not store pointers to this structure directly, but instead use the
|
||||
* AVFilterBufferRef structure below.
|
||||
*/
|
||||
typedef struct AVFilterBuffer {
|
||||
uint8_t *data[8]; ///< buffer data for each plane/channel
|
||||
|
||||
/**
|
||||
* pointers to the data planes/channels.
|
||||
*
|
||||
* For video, this should simply point to data[].
|
||||
*
|
||||
* For planar audio, each channel has a separate data pointer, and
|
||||
* linesize[0] contains the size of each channel buffer.
|
||||
* For packed audio, there is just one data pointer, and linesize[0]
|
||||
* contains the total size of the buffer for all channels.
|
||||
*
|
||||
* Note: Both data and extended_data will always be set, but for planar
|
||||
* audio with more channels that can fit in data, extended_data must be used
|
||||
* in order to access all channels.
|
||||
*/
|
||||
uint8_t **extended_data;
|
||||
int linesize[8]; ///< number of bytes per line
|
||||
|
||||
/** private data to be used by a custom free function */
|
||||
void *priv;
|
||||
/**
|
||||
* A pointer to the function to deallocate this buffer if the default
|
||||
* function is not sufficient. This could, for example, add the memory
|
||||
* back into a memory pool to be reused later without the overhead of
|
||||
* reallocating it from scratch.
|
||||
*/
|
||||
void (*free)(struct AVFilterBuffer *buf);
|
||||
|
||||
int format; ///< media format
|
||||
int w, h; ///< width and height of the allocated buffer
|
||||
unsigned refcount; ///< number of references to this buffer
|
||||
} AVFilterBuffer;
|
||||
|
||||
#define AV_PERM_READ 0x01 ///< can read from the buffer
|
||||
#define AV_PERM_WRITE 0x02 ///< can write to the buffer
|
||||
#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer
|
||||
#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time
|
||||
#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time
|
||||
#define AV_PERM_NEG_LINESIZES 0x20 ///< the buffer requested can have negative linesizes
|
||||
#define AV_PERM_ALIGN 0x40 ///< the buffer must be aligned
|
||||
|
||||
#define AVFILTER_ALIGN 16 //not part of ABI
|
||||
|
||||
/**
|
||||
* Audio specific properties in a reference to an AVFilterBuffer. Since
|
||||
* AVFilterBufferRef is common to different media formats, audio specific
|
||||
* per reference properties must be separated out.
|
||||
*/
|
||||
typedef struct AVFilterBufferRefAudioProps {
|
||||
uint64_t channel_layout; ///< channel layout of audio buffer
|
||||
int nb_samples; ///< number of audio samples per channel
|
||||
int sample_rate; ///< audio buffer sample rate
|
||||
int channels; ///< number of channels (do not access directly)
|
||||
} AVFilterBufferRefAudioProps;
|
||||
|
||||
/**
|
||||
* Video specific properties in a reference to an AVFilterBuffer. Since
|
||||
* AVFilterBufferRef is common to different media formats, video specific
|
||||
* per reference properties must be separated out.
|
||||
*/
|
||||
typedef struct AVFilterBufferRefVideoProps {
|
||||
int w; ///< image width
|
||||
int h; ///< image height
|
||||
AVRational sample_aspect_ratio; ///< sample aspect ratio
|
||||
int interlaced; ///< is frame interlaced
|
||||
int top_field_first; ///< field order
|
||||
enum AVPictureType pict_type; ///< picture type of the frame
|
||||
int key_frame; ///< 1 -> keyframe, 0-> not
|
||||
int qp_table_linesize; ///< qp_table stride
|
||||
int qp_table_size; ///< qp_table size
|
||||
int8_t *qp_table; ///< array of Quantization Parameters
|
||||
} AVFilterBufferRefVideoProps;
|
||||
|
||||
/**
|
||||
* A reference to an AVFilterBuffer. Since filters can manipulate the origin of
|
||||
* a buffer to, for example, crop image without any memcpy, the buffer origin
|
||||
* and dimensions are per-reference properties. Linesize is also useful for
|
||||
* image flipping, frame to field filters, etc, and so is also per-reference.
|
||||
*
|
||||
* TODO: add anything necessary for frame reordering
|
||||
*/
|
||||
typedef struct AVFilterBufferRef {
|
||||
AVFilterBuffer *buf; ///< the buffer that this is a reference to
|
||||
uint8_t *data[8]; ///< picture/audio data for each plane
|
||||
/**
|
||||
* pointers to the data planes/channels.
|
||||
*
|
||||
* For video, this should simply point to data[].
|
||||
*
|
||||
* For planar audio, each channel has a separate data pointer, and
|
||||
* linesize[0] contains the size of each channel buffer.
|
||||
* For packed audio, there is just one data pointer, and linesize[0]
|
||||
* contains the total size of the buffer for all channels.
|
||||
*
|
||||
* Note: Both data and extended_data will always be set, but for planar
|
||||
* audio with more channels that can fit in data, extended_data must be used
|
||||
* in order to access all channels.
|
||||
*/
|
||||
uint8_t **extended_data;
|
||||
int linesize[8]; ///< number of bytes per line
|
||||
|
||||
AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
|
||||
AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
|
||||
|
||||
/**
|
||||
* presentation timestamp. The time unit may change during
|
||||
* filtering, as it is specified in the link and the filter code
|
||||
* may need to rescale the PTS accordingly.
|
||||
*/
|
||||
int64_t pts;
|
||||
int64_t pos; ///< byte position in stream, -1 if unknown
|
||||
|
||||
int format; ///< media format
|
||||
|
||||
int perms; ///< permissions, see the AV_PERM_* flags
|
||||
|
||||
enum AVMediaType type; ///< media type of buffer data
|
||||
|
||||
AVDictionary *metadata; ///< dictionary containing metadata key=value tags
|
||||
} AVFilterBufferRef;
|
||||
|
||||
/**
|
||||
* Copy properties of src to dst, without copying the actual data
|
||||
*/
|
||||
attribute_deprecated
|
||||
void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, const AVFilterBufferRef *src);
|
||||
|
||||
/**
|
||||
* Add a new reference to a buffer.
|
||||
*
|
||||
* @param ref an existing reference to the buffer
|
||||
* @param pmask a bitmask containing the allowable permissions in the new
|
||||
* reference
|
||||
* @return a new reference to the buffer with the same properties as the
|
||||
* old, excluding any permissions denied by pmask
|
||||
*/
|
||||
attribute_deprecated
|
||||
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
|
||||
|
||||
/**
|
||||
* Remove a reference to a buffer. If this is the last reference to the
|
||||
* buffer, the buffer itself is also automatically freed.
|
||||
*
|
||||
* @param ref reference to the buffer, may be NULL
|
||||
*
|
||||
* @note it is recommended to use avfilter_unref_bufferp() instead of this
|
||||
* function
|
||||
*/
|
||||
attribute_deprecated
|
||||
void avfilter_unref_buffer(AVFilterBufferRef *ref);
|
||||
|
||||
/**
|
||||
* Remove a reference to a buffer and set the pointer to NULL.
|
||||
* If this is the last reference to the buffer, the buffer itself
|
||||
* is also automatically freed.
|
||||
*
|
||||
* @param ref pointer to the buffer reference
|
||||
*/
|
||||
attribute_deprecated
|
||||
void avfilter_unref_bufferp(AVFilterBufferRef **ref);
|
||||
|
||||
/**
|
||||
* Get the number of channels of a buffer reference.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int avfilter_ref_get_channels(AVFilterBufferRef *ref);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the number of elements in a NULL-terminated array of AVFilterPads (e.g.
|
||||
* AVFilter.inputs/outputs).
|
||||
@ -742,69 +566,6 @@ void avfilter_link_set_closed(AVFilterLink *link, int closed);
|
||||
*/
|
||||
int avfilter_config_links(AVFilterContext *filter);
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Create a buffer reference wrapped around an already allocated image
|
||||
* buffer.
|
||||
*
|
||||
* @param data pointers to the planes of the image to reference
|
||||
* @param linesize linesizes for the planes of the image to reference
|
||||
* @param perms the required access permissions
|
||||
* @param w the width of the image specified by the data and linesize arrays
|
||||
* @param h the height of the image specified by the data and linesize arrays
|
||||
* @param format the pixel format of the image specified by the data and linesize arrays
|
||||
*/
|
||||
attribute_deprecated
|
||||
AVFilterBufferRef *
|
||||
avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
|
||||
int w, int h, enum AVPixelFormat format);
|
||||
|
||||
/**
|
||||
* Create an audio buffer reference wrapped around an already
|
||||
* allocated samples buffer.
|
||||
*
|
||||
* See avfilter_get_audio_buffer_ref_from_arrays_channels() for a version
|
||||
* that can handle unknown channel layouts.
|
||||
*
|
||||
* @param data pointers to the samples plane buffers
|
||||
* @param linesize linesize for the samples plane buffers
|
||||
* @param perms the required access permissions
|
||||
* @param nb_samples number of samples per channel
|
||||
* @param sample_fmt the format of each sample in the buffer to allocate
|
||||
* @param channel_layout the channel layout of the buffer
|
||||
*/
|
||||
attribute_deprecated
|
||||
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
|
||||
int linesize,
|
||||
int perms,
|
||||
int nb_samples,
|
||||
enum AVSampleFormat sample_fmt,
|
||||
uint64_t channel_layout);
|
||||
/**
|
||||
* Create an audio buffer reference wrapped around an already
|
||||
* allocated samples buffer.
|
||||
*
|
||||
* @param data pointers to the samples plane buffers
|
||||
* @param linesize linesize for the samples plane buffers
|
||||
* @param perms the required access permissions
|
||||
* @param nb_samples number of samples per channel
|
||||
* @param sample_fmt the format of each sample in the buffer to allocate
|
||||
* @param channels the number of channels of the buffer
|
||||
* @param channel_layout the channel layout of the buffer,
|
||||
* must be either 0 or consistent with channels
|
||||
*/
|
||||
attribute_deprecated
|
||||
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data,
|
||||
int linesize,
|
||||
int perms,
|
||||
int nb_samples,
|
||||
enum AVSampleFormat sample_fmt,
|
||||
int channels,
|
||||
uint64_t channel_layout);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically
|
||||
#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw)
|
||||
|
||||
@ -951,26 +712,6 @@ void avfilter_free(AVFilterContext *filter);
|
||||
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
|
||||
unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Copy the frame properties of src to dst, without copying the actual
|
||||
* image data.
|
||||
*
|
||||
* @return 0 on success, a negative number on error.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
|
||||
|
||||
/**
|
||||
* Copy the frame properties and data pointers of src to dst, without copying
|
||||
* the actual data.
|
||||
*
|
||||
* @return 0 on success, a negative number on error.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return AVClass for AVFilterContext.
|
||||
*
|
||||
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright Stefano Sabatini <stefasab gmail com>
|
||||
* Copyright Anton Khirnov <anton khirnov net>
|
||||
* Copyright Michael Niedermayer <michaelni gmx at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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.
|
||||
*
|
||||
* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include "avfilter.h"
|
||||
#include "internal.h"
|
||||
#include "audio.h"
|
||||
#include "avcodec.h"
|
||||
#include "version.h"
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
||||
{
|
||||
if (ptr->extended_data != ptr->data)
|
||||
av_freep(&ptr->extended_data);
|
||||
av_freep(&ptr->data[0]);
|
||||
av_free(ptr);
|
||||
}
|
||||
|
||||
static int copy_video_props(AVFilterBufferRefVideoProps *dst, AVFilterBufferRefVideoProps *src) {
|
||||
*dst = *src;
|
||||
if (src->qp_table) {
|
||||
int qsize = src->qp_table_size;
|
||||
dst->qp_table = av_malloc(qsize);
|
||||
if (!dst->qp_table) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to allocate qp_table\n");
|
||||
dst->qp_table_size = 0;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memcpy(dst->qp_table, src->qp_table, qsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
|
||||
{
|
||||
AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
|
||||
if (!ret)
|
||||
return NULL;
|
||||
*ret = *ref;
|
||||
|
||||
ret->metadata = NULL;
|
||||
av_dict_copy(&ret->metadata, ref->metadata, 0);
|
||||
|
||||
if (ref->type == AVMEDIA_TYPE_VIDEO) {
|
||||
ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
|
||||
if (!ret->video) {
|
||||
av_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
copy_video_props(ret->video, ref->video);
|
||||
ret->extended_data = ret->data;
|
||||
} else if (ref->type == AVMEDIA_TYPE_AUDIO) {
|
||||
ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
|
||||
if (!ret->audio) {
|
||||
av_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
*ret->audio = *ref->audio;
|
||||
|
||||
if (ref->extended_data && ref->extended_data != ref->data) {
|
||||
int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
|
||||
if (!(ret->extended_data = av_malloc_array(sizeof(*ret->extended_data),
|
||||
nb_channels))) {
|
||||
av_freep(&ret->audio);
|
||||
av_freep(&ret);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(ret->extended_data, ref->extended_data,
|
||||
sizeof(*ret->extended_data) * nb_channels);
|
||||
} else
|
||||
ret->extended_data = ret->data;
|
||||
}
|
||||
ret->perms &= pmask;
|
||||
ret->buf->refcount ++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void avfilter_unref_buffer(AVFilterBufferRef *ref)
|
||||
{
|
||||
if (!ref)
|
||||
return;
|
||||
av_assert0(ref->buf->refcount > 0);
|
||||
if (!(--ref->buf->refcount))
|
||||
ref->buf->free(ref->buf);
|
||||
if (ref->extended_data != ref->data)
|
||||
av_freep(&ref->extended_data);
|
||||
if (ref->video)
|
||||
av_freep(&ref->video->qp_table);
|
||||
av_freep(&ref->video);
|
||||
av_freep(&ref->audio);
|
||||
av_dict_free(&ref->metadata);
|
||||
av_free(ref);
|
||||
}
|
||||
|
||||
void avfilter_unref_bufferp(AVFilterBufferRef **ref)
|
||||
{
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
avfilter_unref_buffer(*ref);
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
*ref = NULL;
|
||||
}
|
||||
|
||||
int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
|
||||
{
|
||||
dst->pts = src->pts;
|
||||
dst->pos = av_frame_get_pkt_pos(src);
|
||||
dst->format = src->format;
|
||||
|
||||
av_dict_free(&dst->metadata);
|
||||
av_dict_copy(&dst->metadata, av_frame_get_metadata(src), 0);
|
||||
|
||||
switch (dst->type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
dst->video->w = src->width;
|
||||
dst->video->h = src->height;
|
||||
dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
|
||||
dst->video->interlaced = src->interlaced_frame;
|
||||
dst->video->top_field_first = src->top_field_first;
|
||||
dst->video->key_frame = src->key_frame;
|
||||
dst->video->pict_type = src->pict_type;
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
dst->audio->sample_rate = src->sample_rate;
|
||||
dst->audio->channel_layout = src->channel_layout;
|
||||
break;
|
||||
default:
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, const AVFilterBufferRef *src)
|
||||
{
|
||||
// copy common properties
|
||||
dst->pts = src->pts;
|
||||
dst->pos = src->pos;
|
||||
|
||||
switch (src->type) {
|
||||
case AVMEDIA_TYPE_VIDEO: {
|
||||
if (dst->video->qp_table)
|
||||
av_freep(&dst->video->qp_table);
|
||||
copy_video_props(dst->video, src->video);
|
||||
break;
|
||||
}
|
||||
case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
av_dict_free(&dst->metadata);
|
||||
av_dict_copy(&dst->metadata, src->metadata, 0);
|
||||
}
|
||||
#endif /* FF_API_AVFILTERBUFFER */
|
@ -266,95 +266,6 @@ void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)
|
||||
inlink->partial_buf_size = frame_size;
|
||||
}
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
static void compat_free_buffer(AVFilterBuffer *buf)
|
||||
{
|
||||
AVFrame *frame = buf->priv;
|
||||
av_frame_free(&frame);
|
||||
av_free(buf);
|
||||
}
|
||||
|
||||
static int compat_read(AVFilterContext *ctx,
|
||||
AVFilterBufferRef **pbuf, int nb_samples, int flags)
|
||||
{
|
||||
AVFilterBufferRef *buf;
|
||||
AVFrame *frame;
|
||||
int ret;
|
||||
|
||||
if (!pbuf)
|
||||
return ff_poll_frame(ctx->inputs[0]);
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (!nb_samples)
|
||||
ret = av_buffersink_get_frame_flags(ctx, frame, flags);
|
||||
else
|
||||
ret = av_buffersink_get_samples(ctx, frame, nb_samples);
|
||||
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
AV_NOWARN_DEPRECATED(
|
||||
if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) {
|
||||
buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize,
|
||||
AV_PERM_READ,
|
||||
frame->width, frame->height,
|
||||
frame->format);
|
||||
} else {
|
||||
buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data,
|
||||
frame->linesize[0], AV_PERM_READ,
|
||||
frame->nb_samples,
|
||||
frame->format,
|
||||
frame->channel_layout);
|
||||
}
|
||||
if (!buf) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
avfilter_copy_frame_props(buf, frame);
|
||||
)
|
||||
|
||||
buf->buf->priv = frame;
|
||||
buf->buf->free = compat_free_buffer;
|
||||
|
||||
*pbuf = buf;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int attribute_align_arg av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
|
||||
{
|
||||
return compat_read(ctx, buf, 0, 0);
|
||||
}
|
||||
|
||||
int attribute_align_arg av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
|
||||
int nb_samples)
|
||||
{
|
||||
return compat_read(ctx, buf, nb_samples, 0);
|
||||
}
|
||||
|
||||
int attribute_align_arg av_buffersink_get_buffer_ref(AVFilterContext *ctx,
|
||||
AVFilterBufferRef **bufref, int flags)
|
||||
{
|
||||
*bufref = NULL;
|
||||
|
||||
av_assert0( !strcmp(ctx->filter->name, "buffersink")
|
||||
|| !strcmp(ctx->filter->name, "abuffersink")
|
||||
|| !strcmp(ctx->filter->name, "ffbuffersink")
|
||||
|| !strcmp(ctx->filter->name, "ffabuffersink"));
|
||||
|
||||
return compat_read(ctx, bufref, 0, flags);
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx)
|
||||
{
|
||||
av_assert0( !strcmp(ctx->filter->name, "buffersink")
|
||||
@ -363,23 +274,6 @@ AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx)
|
||||
return ctx->inputs[0]->frame_rate;
|
||||
}
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
int attribute_align_arg av_buffersink_poll_frame(AVFilterContext *ctx)
|
||||
{
|
||||
BufferSinkContext *buf = ctx->priv;
|
||||
AVFilterLink *inlink = ctx->inputs[0];
|
||||
|
||||
av_assert0( !strcmp(ctx->filter->name, "buffersink")
|
||||
|| !strcmp(ctx->filter->name, "abuffersink")
|
||||
|| !strcmp(ctx->filter->name, "ffbuffersink")
|
||||
|| !strcmp(ctx->filter->name, "ffabuffersink"));
|
||||
|
||||
return av_fifo_size(buf->fifo)/FIFO_INIT_ELEMENT_SIZE + ff_poll_frame(inlink);
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
static av_cold int vsink_init(AVFilterContext *ctx, void *opaque)
|
||||
{
|
||||
BufferSinkContext *buf = ctx->priv;
|
||||
@ -518,57 +412,6 @@ static const AVOption abuffersink_options[] = {
|
||||
AVFILTER_DEFINE_CLASS(buffersink);
|
||||
AVFILTER_DEFINE_CLASS(abuffersink);
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
|
||||
#define ffbuffersink_options buffersink_options
|
||||
#define ffabuffersink_options abuffersink_options
|
||||
AVFILTER_DEFINE_CLASS(ffbuffersink);
|
||||
AVFILTER_DEFINE_CLASS(ffabuffersink);
|
||||
|
||||
static const AVFilterPad ffbuffersink_inputs[] = {
|
||||
{
|
||||
.name = "default",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.filter_frame = filter_frame,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
AVFilter ff_vsink_ffbuffersink = {
|
||||
.name = "ffbuffersink",
|
||||
.description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
|
||||
.priv_size = sizeof(BufferSinkContext),
|
||||
.priv_class = &ffbuffersink_class,
|
||||
.init_opaque = vsink_init,
|
||||
.uninit = uninit,
|
||||
|
||||
.query_formats = vsink_query_formats,
|
||||
.inputs = ffbuffersink_inputs,
|
||||
.outputs = NULL,
|
||||
};
|
||||
|
||||
static const AVFilterPad ffabuffersink_inputs[] = {
|
||||
{
|
||||
.name = "default",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.filter_frame = filter_frame,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
AVFilter ff_asink_ffabuffersink = {
|
||||
.name = "ffabuffersink",
|
||||
.description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
|
||||
.init_opaque = asink_init,
|
||||
.uninit = uninit,
|
||||
.priv_size = sizeof(BufferSinkContext),
|
||||
.priv_class = &ffabuffersink_class,
|
||||
.query_formats = asink_query_formats,
|
||||
.inputs = ffabuffersink_inputs,
|
||||
.outputs = NULL,
|
||||
};
|
||||
#endif /* FF_API_AVFILTERBUFFER */
|
||||
|
||||
static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
|
||||
{
|
||||
.name = "default",
|
||||
|
@ -33,63 +33,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Get an audio/video buffer data from buffer_sink and put it in bufref.
|
||||
*
|
||||
* This function works with both audio and video buffer sinks.
|
||||
*
|
||||
* @param buffer_sink pointer to a buffersink or abuffersink context
|
||||
* @param flags a combination of AV_BUFFERSINK_FLAG_* flags
|
||||
* @return >= 0 in case of success, a negative AVERROR code in case of
|
||||
* failure
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink,
|
||||
AVFilterBufferRef **bufref, int flags);
|
||||
|
||||
/**
|
||||
* Get the number of immediately available frames.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersink_poll_frame(AVFilterContext *ctx);
|
||||
|
||||
/**
|
||||
* Get a buffer with filtered data from sink and put it in buf.
|
||||
*
|
||||
* @param ctx pointer to a context of a buffersink or abuffersink AVFilter.
|
||||
* @param buf pointer to the buffer will be written here if buf is non-NULL. buf
|
||||
* must be freed by the caller using avfilter_unref_buffer().
|
||||
* Buf may also be NULL to query whether a buffer is ready to be
|
||||
* output.
|
||||
*
|
||||
* @return >= 0 in case of success, a negative AVERROR code in case of
|
||||
* failure.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf);
|
||||
|
||||
/**
|
||||
* Same as av_buffersink_read, but with the ability to specify the number of
|
||||
* samples read. This function is less efficient than av_buffersink_read(),
|
||||
* because it copies the data around.
|
||||
*
|
||||
* @param ctx pointer to a context of the abuffersink AVFilter.
|
||||
* @param buf pointer to the buffer will be written here if buf is non-NULL. buf
|
||||
* must be freed by the caller using avfilter_unref_buffer(). buf
|
||||
* will contain exactly nb_samples audio samples, except at the end
|
||||
* of stream, when it can contain less than nb_samples.
|
||||
* Buf may also be NULL to query whether a buffer is ready to be
|
||||
* output.
|
||||
*
|
||||
* @warning do not mix this function with av_buffersink_read(). Use only one or
|
||||
* the other with a single sink, not both.
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
|
||||
int nb_samples);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get a frame with filtered data from sink and put it in frame.
|
||||
*
|
||||
|
@ -184,127 +184,6 @@ static int av_buffersrc_add_frame_internal(AVFilterContext *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
static void compat_free_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
AVFilterBufferRef *buf = opaque;
|
||||
AV_NOWARN_DEPRECATED(
|
||||
avfilter_unref_buffer(buf);
|
||||
)
|
||||
}
|
||||
|
||||
static void compat_unref_buffer(void *opaque, uint8_t *data)
|
||||
{
|
||||
AVBufferRef *buf = opaque;
|
||||
AV_NOWARN_DEPRECATED(
|
||||
av_buffer_unref(&buf);
|
||||
)
|
||||
}
|
||||
|
||||
int av_buffersrc_add_ref(AVFilterContext *ctx, AVFilterBufferRef *buf,
|
||||
int flags)
|
||||
{
|
||||
BufferSourceContext *s = ctx->priv;
|
||||
AVFrame *frame = NULL;
|
||||
AVBufferRef *dummy_buf = NULL;
|
||||
int ret = 0, planes, i;
|
||||
|
||||
if (!buf) {
|
||||
s->eof = 1;
|
||||
return 0;
|
||||
} else if (s->eof)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, buf,
|
||||
(buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY);
|
||||
if (!dummy_buf) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
AV_NOWARN_DEPRECATED(
|
||||
if ((ret = avfilter_copy_buf_props(frame, buf)) < 0)
|
||||
goto fail;
|
||||
)
|
||||
|
||||
#define WRAP_PLANE(ref_out, data, data_size) \
|
||||
do { \
|
||||
AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \
|
||||
if (!dummy_ref) { \
|
||||
ret = AVERROR(ENOMEM); \
|
||||
goto fail; \
|
||||
} \
|
||||
ref_out = av_buffer_create(data, data_size, compat_unref_buffer, \
|
||||
dummy_ref, (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY); \
|
||||
if (!ref_out) { \
|
||||
av_buffer_unref(&dummy_ref); \
|
||||
av_frame_unref(frame); \
|
||||
ret = AVERROR(ENOMEM); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
if (ctx->outputs[0]->type == AVMEDIA_TYPE_VIDEO) {
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
|
||||
|
||||
planes = av_pix_fmt_count_planes(frame->format);
|
||||
if (!desc || planes <= 0) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < planes; i++) {
|
||||
int v_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
|
||||
int plane_size = (frame->height >> v_shift) * frame->linesize[i];
|
||||
|
||||
WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
|
||||
}
|
||||
} else {
|
||||
int planar = av_sample_fmt_is_planar(frame->format);
|
||||
int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
|
||||
|
||||
planes = planar ? channels : 1;
|
||||
|
||||
if (planes > FF_ARRAY_ELEMS(frame->buf)) {
|
||||
frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
|
||||
frame->extended_buf = av_mallocz_array(sizeof(*frame->extended_buf),
|
||||
frame->nb_extended_buf);
|
||||
if (!frame->extended_buf) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
|
||||
WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
|
||||
|
||||
for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++)
|
||||
WRAP_PLANE(frame->extended_buf[i],
|
||||
frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
|
||||
frame->linesize[0]);
|
||||
}
|
||||
|
||||
ret = av_buffersrc_add_frame_flags(ctx, frame, flags);
|
||||
|
||||
fail:
|
||||
av_buffer_unref(&dummy_buf);
|
||||
av_frame_free(&frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
|
||||
int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf)
|
||||
{
|
||||
return av_buffersrc_add_ref(ctx, buf, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static av_cold int init_video(AVFilterContext *ctx)
|
||||
{
|
||||
BufferSourceContext *c = ctx->priv;
|
||||
|
@ -42,13 +42,6 @@ enum {
|
||||
*/
|
||||
AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT = 1,
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Ignored
|
||||
*/
|
||||
AV_BUFFERSRC_FLAG_NO_COPY = 2,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Immediately push the frame to the output.
|
||||
*/
|
||||
@ -63,21 +56,6 @@ enum {
|
||||
|
||||
};
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Add buffer data in picref to buffer_src.
|
||||
*
|
||||
* @param buffer_src pointer to a buffer source context
|
||||
* @param picref a buffer reference, or NULL to mark EOF
|
||||
* @param flags a combination of AV_BUFFERSRC_FLAG_*
|
||||
* @return >= 0 in case of success, a negative AVERROR code
|
||||
* in case of failure
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersrc_add_ref(AVFilterContext *buffer_src,
|
||||
AVFilterBufferRef *picref, int flags);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the number of failed requests.
|
||||
*
|
||||
@ -87,21 +65,6 @@ int av_buffersrc_add_ref(AVFilterContext *buffer_src,
|
||||
*/
|
||||
unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src);
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/**
|
||||
* Add a buffer to a filtergraph.
|
||||
*
|
||||
* @param ctx an instance of the buffersrc filter
|
||||
* @param buf buffer containing frame data to be passed down the filtergraph.
|
||||
* This function will take ownership of buf, the user must not free it.
|
||||
* A NULL buf signals EOF -- i.e. no more frames will be sent to this filter.
|
||||
*
|
||||
* @deprecated use av_buffersrc_write_frame() or av_buffersrc_add_frame()
|
||||
*/
|
||||
attribute_deprecated
|
||||
int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Add a frame to the buffer source.
|
||||
*
|
||||
|
@ -162,11 +162,6 @@ struct AVFilterInternal {
|
||||
avfilter_execute_func *execute;
|
||||
};
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
/** default handler for freeing audio/video buffer when there are no references left */
|
||||
void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
|
||||
#endif
|
||||
|
||||
/** Tell is a format is contained in the provided list terminated by -1. */
|
||||
int ff_fmt_is_in(int fmt, const int *fmts);
|
||||
|
||||
|
@ -49,9 +49,6 @@
|
||||
* the public API and may change, break or disappear at any time.
|
||||
*/
|
||||
|
||||
#ifndef FF_API_AVFILTERBUFFER
|
||||
#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 6)
|
||||
#endif
|
||||
#ifndef FF_API_OLD_FILTER_OPTS
|
||||
#define FF_API_OLD_FILTER_OPTS (LIBAVFILTER_VERSION_MAJOR < 6)
|
||||
#endif
|
||||
|
@ -59,53 +59,6 @@ AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h)
|
||||
return frame;
|
||||
}
|
||||
|
||||
#if FF_API_AVFILTERBUFFER
|
||||
AVFilterBufferRef *
|
||||
avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
|
||||
int w, int h, enum AVPixelFormat format)
|
||||
{
|
||||
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;
|
||||
|
||||
picref->pts = AV_NOPTS_VALUE;
|
||||
|
||||
return picref;
|
||||
|
||||
fail:
|
||||
if (picref && picref->video)
|
||||
av_free(picref->video);
|
||||
av_free(picref);
|
||||
av_free(pic);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h)
|
||||
{
|
||||
AVFrame *ret = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user