00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "avcodec.h"
00027 #include "libavutil/avassert.h"
00028 #include "libavutil/opt.h"
00029
00030 int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
00031 {
00032 dst->pts = src->pts;
00033 dst->pos = av_frame_get_pkt_pos(src);
00034 dst->format = src->format;
00035
00036 av_dict_free(&dst->metadata);
00037 av_dict_copy(&dst->metadata, av_frame_get_metadata(src), 0);
00038
00039 switch (dst->type) {
00040 case AVMEDIA_TYPE_VIDEO:
00041 dst->video->w = src->width;
00042 dst->video->h = src->height;
00043 dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
00044 dst->video->interlaced = src->interlaced_frame;
00045 dst->video->top_field_first = src->top_field_first;
00046 dst->video->key_frame = src->key_frame;
00047 dst->video->pict_type = src->pict_type;
00048 av_freep(&dst->video->qp_table);
00049 dst->video->qp_table_linesize = 0;
00050 if (src->qscale_table) {
00051 int qsize = src->qstride ? src->qstride * ((src->height+15)/16) : (src->width+15)/16;
00052 dst->video->qp_table = av_malloc(qsize);
00053 if (!dst->video->qp_table)
00054 return AVERROR(ENOMEM);
00055 dst->video->qp_table_linesize = src->qstride;
00056 dst->video->qp_table_size = qsize;
00057 memcpy(dst->video->qp_table, src->qscale_table, qsize);
00058 }
00059 break;
00060 case AVMEDIA_TYPE_AUDIO:
00061 dst->audio->sample_rate = src->sample_rate;
00062 dst->audio->channel_layout = src->channel_layout;
00063 dst->audio->channels = src->channels;
00064 if(src->channels < av_get_channel_layout_nb_channels(src->channel_layout)) {
00065 av_log(NULL, AV_LOG_ERROR, "libavfilter does not support this channel layout\n");
00066 return AVERROR(EINVAL);
00067 }
00068 break;
00069 default:
00070 return AVERROR(EINVAL);
00071 }
00072
00073 return 0;
00074 }
00075
00076 AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame,
00077 int perms)
00078 {
00079 AVFilterBufferRef *picref =
00080 avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, perms,
00081 frame->width, frame->height,
00082 frame->format);
00083 if (!picref)
00084 return NULL;
00085 if (avfilter_copy_frame_props(picref, frame) < 0) {
00086 picref->buf->data[0] = NULL;
00087 avfilter_unref_bufferp(&picref);
00088 }
00089 return picref;
00090 }
00091
00092 AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame,
00093 int perms)
00094 {
00095 AVFilterBufferRef *samplesref;
00096 int64_t layout = av_frame_get_channel_layout(frame);
00097
00098 if(av_frame_get_channels(frame) > 8)
00099 return NULL;
00100
00101 if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
00102 av_log(0, AV_LOG_ERROR, "Layout indicates a differnt number of channels than actually present\n");
00103 return NULL;
00104 }
00105
00106 samplesref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms,
00107 frame->nb_samples, frame->format,
00108 av_frame_get_channel_layout(frame));
00109 if (!samplesref)
00110 return NULL;
00111 if (avfilter_copy_frame_props(samplesref, frame) < 0) {
00112 samplesref->buf->data[0] = NULL;
00113 avfilter_unref_bufferp(&samplesref);
00114 }
00115 return samplesref;
00116 }
00117
00118 AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type,
00119 const AVFrame *frame,
00120 int perms)
00121 {
00122 switch (type) {
00123 case AVMEDIA_TYPE_VIDEO:
00124 return avfilter_get_video_buffer_ref_from_frame(frame, perms);
00125 case AVMEDIA_TYPE_AUDIO:
00126 return avfilter_get_audio_buffer_ref_from_frame(frame, perms);
00127 default:
00128 return NULL;
00129 }
00130 }
00131
00132 int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
00133 {
00134 int planes, nb_channels;
00135
00136 if (!dst)
00137 return AVERROR(EINVAL);
00138
00139 av_assert0(src);
00140
00141 memcpy(dst->data, src->data, sizeof(dst->data));
00142 memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
00143
00144 dst->pts = src->pts;
00145 dst->format = src->format;
00146 av_frame_set_pkt_pos(dst, src->pos);
00147
00148 switch (src->type) {
00149 case AVMEDIA_TYPE_VIDEO:
00150 av_assert0(src->video);
00151 dst->width = src->video->w;
00152 dst->height = src->video->h;
00153 dst->sample_aspect_ratio = src->video->sample_aspect_ratio;
00154 dst->interlaced_frame = src->video->interlaced;
00155 dst->top_field_first = src->video->top_field_first;
00156 dst->key_frame = src->video->key_frame;
00157 dst->pict_type = src->video->pict_type;
00158 break;
00159 case AVMEDIA_TYPE_AUDIO:
00160 av_assert0(src->audio);
00161 nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
00162 planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
00163
00164 if (planes > FF_ARRAY_ELEMS(dst->data)) {
00165 dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
00166 if (!dst->extended_data)
00167 return AVERROR(ENOMEM);
00168 memcpy(dst->extended_data, src->extended_data,
00169 planes * sizeof(*dst->extended_data));
00170 } else
00171 dst->extended_data = dst->data;
00172 dst->nb_samples = src->audio->nb_samples;
00173 av_frame_set_sample_rate (dst, src->audio->sample_rate);
00174 av_frame_set_channel_layout(dst, src->audio->channel_layout);
00175 av_frame_set_channels (dst, src->audio->channels);
00176 break;
00177 default:
00178 return AVERROR(EINVAL);
00179 }
00180
00181 return 0;
00182 }
00183
00184 #ifdef FF_API_FILL_FRAME
00185 int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
00186 const AVFilterBufferRef *samplesref)
00187 {
00188 return avfilter_copy_buf_props(frame, samplesref);
00189 }
00190
00191 int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
00192 const AVFilterBufferRef *picref)
00193 {
00194 return avfilter_copy_buf_props(frame, picref);
00195 }
00196
00197 int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
00198 const AVFilterBufferRef *ref)
00199 {
00200 return avfilter_copy_buf_props(frame, ref);
00201 }
00202 #endif