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 "libavutil/common.h"
00026 #include "libavutil/imgutils.h"
00027 #include "libavcodec/avcodec.h"
00028
00029 #include "avfilter.h"
00030 #include "internal.h"
00031 #include "audio.h"
00032 #include "avcodec.h"
00033
00034 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
00035 {
00036 if (ptr->extended_data != ptr->data)
00037 av_freep(&ptr->extended_data);
00038 av_free(ptr->data[0]);
00039 av_free(ptr);
00040 }
00041
00042 static void copy_video_props(AVFilterBufferRefVideoProps *dst, AVFilterBufferRefVideoProps *src) {
00043 *dst = *src;
00044 if (src->qp_table) {
00045 int qsize = src->qp_table_size;
00046 dst->qp_table = av_malloc(qsize);
00047 memcpy(dst->qp_table, src->qp_table, qsize);
00048 }
00049 }
00050
00051 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
00052 {
00053 AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
00054 if (!ret)
00055 return NULL;
00056 *ret = *ref;
00057 if (ref->type == AVMEDIA_TYPE_VIDEO) {
00058 ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
00059 if (!ret->video) {
00060 av_free(ret);
00061 return NULL;
00062 }
00063 copy_video_props(ret->video, ref->video);
00064 ret->extended_data = ret->data;
00065 } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
00066 ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
00067 if (!ret->audio) {
00068 av_free(ret);
00069 return NULL;
00070 }
00071 *ret->audio = *ref->audio;
00072
00073 if (ref->extended_data && ref->extended_data != ref->data) {
00074 int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
00075 if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
00076 nb_channels))) {
00077 av_freep(&ret->audio);
00078 av_freep(&ret);
00079 return NULL;
00080 }
00081 memcpy(ret->extended_data, ref->extended_data,
00082 sizeof(*ret->extended_data) * nb_channels);
00083 } else
00084 ret->extended_data = ret->data;
00085 }
00086 ret->perms &= pmask;
00087 ret->buf->refcount ++;
00088 return ret;
00089 }
00090
00091 void ff_free_pool(AVFilterPool *pool)
00092 {
00093 int i;
00094
00095 av_assert0(pool->refcount > 0);
00096
00097 for (i = 0; i < POOL_SIZE; i++) {
00098 if (pool->pic[i]) {
00099 AVFilterBufferRef *picref = pool->pic[i];
00100
00101
00102 av_assert0(!picref->buf->refcount);
00103 av_freep(&picref->buf->data[0]);
00104 av_freep(&picref->buf);
00105
00106 av_freep(&picref->audio);
00107 av_assert0(!picref->video || !picref->video->qp_table);
00108 av_freep(&picref->video);
00109 av_freep(&pool->pic[i]);
00110 pool->count--;
00111 }
00112 }
00113 pool->draining = 1;
00114
00115 if (!--pool->refcount) {
00116 av_assert0(!pool->count);
00117 av_free(pool);
00118 }
00119 }
00120
00121 static void store_in_pool(AVFilterBufferRef *ref)
00122 {
00123 int i;
00124 AVFilterPool *pool= ref->buf->priv;
00125
00126 av_assert0(ref->buf->data[0]);
00127 av_assert0(pool->refcount>0);
00128
00129 if (ref->video)
00130 av_freep(&ref->video->qp_table);
00131
00132 if (pool->count == POOL_SIZE) {
00133 AVFilterBufferRef *ref1 = pool->pic[0];
00134 av_freep(&ref1->video);
00135 av_freep(&ref1->audio);
00136 av_freep(&ref1->buf->data[0]);
00137 av_freep(&ref1->buf);
00138 av_free(ref1);
00139 memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
00140 pool->count--;
00141 pool->pic[POOL_SIZE-1] = NULL;
00142 }
00143
00144 for (i = 0; i < POOL_SIZE; i++) {
00145 if (!pool->pic[i]) {
00146 pool->pic[i] = ref;
00147 pool->count++;
00148 break;
00149 }
00150 }
00151 if (pool->draining) {
00152 ff_free_pool(pool);
00153 } else
00154 --pool->refcount;
00155 }
00156
00157 void avfilter_unref_buffer(AVFilterBufferRef *ref)
00158 {
00159 if (!ref)
00160 return;
00161 av_assert0(ref->buf->refcount > 0);
00162 if (!(--ref->buf->refcount)) {
00163 if (!ref->buf->free) {
00164 store_in_pool(ref);
00165 return;
00166 }
00167 ref->buf->free(ref->buf);
00168 }
00169 if (ref->extended_data != ref->data)
00170 av_freep(&ref->extended_data);
00171 if (ref->video)
00172 av_freep(&ref->video->qp_table);
00173 av_freep(&ref->video);
00174 av_freep(&ref->audio);
00175 av_free(ref);
00176 }
00177
00178 void avfilter_unref_bufferp(AVFilterBufferRef **ref)
00179 {
00180 avfilter_unref_buffer(*ref);
00181 *ref = NULL;
00182 }
00183
00184 void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
00185 {
00186
00187 dst->pts = src->pts;
00188 dst->pos = src->pos;
00189
00190 switch (src->type) {
00191 case AVMEDIA_TYPE_VIDEO: {
00192 if (dst->video->qp_table)
00193 av_freep(&dst->video->qp_table);
00194 copy_video_props(dst->video, src->video);
00195 break;
00196 }
00197 case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
00198 default: break;
00199 }
00200 }
00201
00202 AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
00203 AVFilterBufferRef *ref)
00204 {
00205 AVFilterBufferRef *buf;
00206 int channels;
00207
00208 switch (outlink->type) {
00209
00210 case AVMEDIA_TYPE_VIDEO:
00211 buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
00212 ref->video->w, ref->video->h);
00213 if(!buf)
00214 return NULL;
00215 av_image_copy(buf->data, buf->linesize,
00216 (void*)ref->data, ref->linesize,
00217 ref->format, ref->video->w, ref->video->h);
00218 break;
00219
00220 case AVMEDIA_TYPE_AUDIO:
00221 buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
00222 ref->audio->nb_samples);
00223 if(!buf)
00224 return NULL;
00225 channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
00226 av_samples_copy(buf->extended_data, ref->buf->extended_data,
00227 0, 0, ref->audio->nb_samples,
00228 channels,
00229 ref->format);
00230 break;
00231
00232 default:
00233 return NULL;
00234 }
00235 avfilter_copy_buffer_ref_props(buf, ref);
00236 return buf;
00237 }