00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "libavutil/audioconvert.h"
00024 #include "libavutil/avassert.h"
00025 #include "libavcodec/avcodec.h"
00026
00027 #include "avfilter.h"
00028 #include "internal.h"
00029 #include "avcodec.h"
00030
00031 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
00032 {
00033 if (ptr->extended_data != ptr->data)
00034 av_freep(&ptr->extended_data);
00035 av_free(ptr->data[0]);
00036 av_free(ptr);
00037 }
00038
00039 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
00040 {
00041 AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
00042 if (!ret)
00043 return NULL;
00044 *ret = *ref;
00045 if (ref->type == AVMEDIA_TYPE_VIDEO) {
00046 ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
00047 if (!ret->video) {
00048 av_free(ret);
00049 return NULL;
00050 }
00051 *ret->video = *ref->video;
00052 ret->extended_data = ret->data;
00053 } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
00054 ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
00055 if (!ret->audio) {
00056 av_free(ret);
00057 return NULL;
00058 }
00059 *ret->audio = *ref->audio;
00060
00061 if (ref->extended_data && ref->extended_data != ref->data) {
00062 int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
00063 if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
00064 nb_channels))) {
00065 av_freep(&ret->audio);
00066 av_freep(&ret);
00067 return NULL;
00068 }
00069 memcpy(ret->extended_data, ref->extended_data,
00070 sizeof(*ret->extended_data) * nb_channels);
00071 } else
00072 ret->extended_data = ret->data;
00073 }
00074 ret->perms &= pmask;
00075 ret->buf->refcount ++;
00076 return ret;
00077 }
00078
00079 void ff_free_pool(AVFilterPool *pool)
00080 {
00081 int i;
00082
00083 av_assert0(pool->refcount > 0);
00084
00085 for (i = 0; i < POOL_SIZE; i++) {
00086 if (pool->pic[i]) {
00087 AVFilterBufferRef *picref = pool->pic[i];
00088
00089
00090 av_assert0(!picref->buf->refcount);
00091 av_freep(&picref->buf->data[0]);
00092 av_freep(&picref->buf);
00093
00094 av_freep(&picref->audio);
00095 av_freep(&picref->video);
00096 av_freep(&pool->pic[i]);
00097 pool->count--;
00098 }
00099 }
00100 pool->draining = 1;
00101
00102 if (!--pool->refcount) {
00103 av_assert0(!pool->count);
00104 av_free(pool);
00105 }
00106 }
00107
00108 static void store_in_pool(AVFilterBufferRef *ref)
00109 {
00110 int i;
00111 AVFilterPool *pool= ref->buf->priv;
00112
00113 av_assert0(ref->buf->data[0]);
00114 av_assert0(pool->refcount>0);
00115
00116 if (pool->count == POOL_SIZE) {
00117 AVFilterBufferRef *ref1 = pool->pic[0];
00118 av_freep(&ref1->video);
00119 av_freep(&ref1->audio);
00120 av_freep(&ref1->buf->data[0]);
00121 av_freep(&ref1->buf);
00122 av_free(ref1);
00123 memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
00124 pool->count--;
00125 pool->pic[POOL_SIZE-1] = NULL;
00126 }
00127
00128 for (i = 0; i < POOL_SIZE; i++) {
00129 if (!pool->pic[i]) {
00130 pool->pic[i] = ref;
00131 pool->count++;
00132 break;
00133 }
00134 }
00135 if (pool->draining) {
00136 ff_free_pool(pool);
00137 } else
00138 --pool->refcount;
00139 }
00140
00141 void avfilter_unref_buffer(AVFilterBufferRef *ref)
00142 {
00143 if (!ref)
00144 return;
00145 av_assert0(ref->buf->refcount > 0);
00146 if (!(--ref->buf->refcount)) {
00147 if (!ref->buf->free) {
00148 store_in_pool(ref);
00149 return;
00150 }
00151 ref->buf->free(ref->buf);
00152 }
00153 if (ref->extended_data != ref->data)
00154 av_freep(&ref->extended_data);
00155 av_freep(&ref->video);
00156 av_freep(&ref->audio);
00157 av_free(ref);
00158 }
00159
00160 void avfilter_unref_bufferp(AVFilterBufferRef **ref)
00161 {
00162 avfilter_unref_buffer(*ref);
00163 *ref = NULL;
00164 }
00165
00166 int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
00167 {
00168 dst->pts = src->pts;
00169 dst->pos = av_frame_get_pkt_pos(src);
00170 dst->format = src->format;
00171
00172 switch (dst->type) {
00173 case AVMEDIA_TYPE_VIDEO:
00174 dst->video->w = src->width;
00175 dst->video->h = src->height;
00176 dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
00177 dst->video->interlaced = src->interlaced_frame;
00178 dst->video->top_field_first = src->top_field_first;
00179 dst->video->key_frame = src->key_frame;
00180 dst->video->pict_type = src->pict_type;
00181 break;
00182 case AVMEDIA_TYPE_AUDIO:
00183 dst->audio->sample_rate = src->sample_rate;
00184 dst->audio->channel_layout = src->channel_layout;
00185 break;
00186 default:
00187 return AVERROR(EINVAL);
00188 }
00189
00190 return 0;
00191 }
00192
00193 int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
00194 {
00195 int planes, nb_channels;
00196
00197 memcpy(dst->data, src->data, sizeof(dst->data));
00198 memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
00199
00200 dst->pts = src->pts;
00201 dst->format = src->format;
00202
00203 switch (src->type) {
00204 case AVMEDIA_TYPE_VIDEO:
00205 dst->width = src->video->w;
00206 dst->height = src->video->h;
00207 dst->sample_aspect_ratio = src->video->sample_aspect_ratio;
00208 dst->interlaced_frame = src->video->interlaced;
00209 dst->top_field_first = src->video->top_field_first;
00210 dst->key_frame = src->video->key_frame;
00211 dst->pict_type = src->video->pict_type;
00212 break;
00213 case AVMEDIA_TYPE_AUDIO:
00214 nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
00215 planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
00216
00217 if (planes > FF_ARRAY_ELEMS(dst->data)) {
00218 dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
00219 if (!dst->extended_data)
00220 return AVERROR(ENOMEM);
00221 memcpy(dst->extended_data, src->extended_data,
00222 planes * sizeof(dst->extended_data));
00223 } else
00224 dst->extended_data = dst->data;
00225
00226 dst->sample_rate = src->audio->sample_rate;
00227 dst->channel_layout = src->audio->channel_layout;
00228 dst->nb_samples = src->audio->nb_samples;
00229 break;
00230 default:
00231 return AVERROR(EINVAL);
00232 }
00233
00234 return 0;
00235 }
00236
00237 void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
00238 {
00239
00240 dst->pts = src->pts;
00241 dst->pos = src->pos;
00242
00243 switch (src->type) {
00244 case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
00245 case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
00246 default: break;
00247 }
00248 }