lavfi: add extended_data to AVFilterBuffer.
This is similar to what has previously been done in AVFrame to allow dealing with more than 8 channels.
This commit is contained in:
parent
c22953b8a3
commit
9453c9e1de
@ -57,6 +57,7 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*ret->video = *ref->video;
|
*ret->video = *ref->video;
|
||||||
|
ret->extended_data = ret->data;
|
||||||
} else if (ref->type == AVMEDIA_TYPE_AUDIO) {
|
} else if (ref->type == AVMEDIA_TYPE_AUDIO) {
|
||||||
ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
|
ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
|
||||||
if (!ret->audio) {
|
if (!ret->audio) {
|
||||||
@ -64,6 +65,19 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*ret->audio = *ref->audio;
|
*ret->audio = *ref->audio;
|
||||||
|
|
||||||
|
if (ref->extended_data != ref->data) {
|
||||||
|
int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
|
||||||
|
if (!(ret->extended_data = av_malloc(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->perms &= pmask;
|
||||||
ret->buf->refcount ++;
|
ret->buf->refcount ++;
|
||||||
@ -76,6 +90,8 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref)
|
|||||||
return;
|
return;
|
||||||
if (!(--ref->buf->refcount))
|
if (!(--ref->buf->refcount))
|
||||||
ref->buf->free(ref->buf);
|
ref->buf->free(ref->buf);
|
||||||
|
if (ref->extended_data != ref->data)
|
||||||
|
av_freep(&ref->extended_data);
|
||||||
av_free(ref->video);
|
av_free(ref->video);
|
||||||
av_free(ref->audio);
|
av_free(ref->audio);
|
||||||
av_free(ref);
|
av_free(ref);
|
||||||
@ -338,6 +354,9 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
|
|||||||
memcpy(picref->data, pic->data, sizeof(picref->data));
|
memcpy(picref->data, pic->data, sizeof(picref->data));
|
||||||
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
|
memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
|
||||||
|
|
||||||
|
pic-> extended_data = pic->data;
|
||||||
|
picref->extended_data = picref->data;
|
||||||
|
|
||||||
return picref;
|
return picref;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -710,6 +729,8 @@ int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
|
|||||||
|
|
||||||
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
|
int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
|
||||||
{
|
{
|
||||||
|
int planes, nb_channels;
|
||||||
|
|
||||||
memcpy(dst->data, src->data, sizeof(dst->data));
|
memcpy(dst->data, src->data, sizeof(dst->data));
|
||||||
memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
|
memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
|
||||||
|
|
||||||
@ -727,6 +748,18 @@ int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
|
|||||||
dst->pict_type = src->video->pict_type;
|
dst->pict_type = src->video->pict_type;
|
||||||
break;
|
break;
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
|
nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
|
||||||
|
planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
|
||||||
|
|
||||||
|
if (planes > FF_ARRAY_ELEMS(dst->data)) {
|
||||||
|
dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
|
||||||
|
if (!dst->extended_data)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
memcpy(dst->extended_data, src->extended_data,
|
||||||
|
planes * sizeof(dst->extended_data));
|
||||||
|
} else
|
||||||
|
dst->extended_data = dst->data;
|
||||||
|
|
||||||
dst->sample_rate = src->audio->sample_rate;
|
dst->sample_rate = src->audio->sample_rate;
|
||||||
dst->channel_layout = src->audio->channel_layout;
|
dst->channel_layout = src->audio->channel_layout;
|
||||||
dst->nb_samples = src->audio->nb_samples;
|
dst->nb_samples = src->audio->nb_samples;
|
||||||
|
@ -76,6 +76,22 @@ typedef struct AVFilterBuffer {
|
|||||||
|
|
||||||
int format; ///< media format
|
int format; ///< media format
|
||||||
int w, h; ///< width and height of the allocated buffer
|
int w, h; ///< width and height of the allocated buffer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
} AVFilterBuffer;
|
} AVFilterBuffer;
|
||||||
|
|
||||||
#define AV_PERM_READ 0x01 ///< can read from the buffer
|
#define AV_PERM_READ 0x01 ///< can read from the buffer
|
||||||
@ -140,6 +156,22 @@ typedef struct AVFilterBufferRef {
|
|||||||
enum AVMediaType type; ///< media type of buffer data
|
enum AVMediaType type; ///< media type of buffer data
|
||||||
AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
|
AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
|
||||||
AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
|
AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
} AVFilterBufferRef;
|
} AVFilterBufferRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
|
/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
|
||||||
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
||||||
{
|
{
|
||||||
|
if (ptr->extended_data != ptr->data)
|
||||||
|
av_freep(&ptr->extended_data);
|
||||||
av_free(ptr->data[0]);
|
av_free(ptr->data[0]);
|
||||||
av_free(ptr);
|
av_free(ptr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user