FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
avcodec.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Stefano Sabatini | stefasab at gmail.com
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * libavcodec/libavfilter gluing utilities
24  */
25 
26 #include "avcodec.h"
27 #include "libavutil/avassert.h"
29 #include "libavutil/opt.h"
30 
31 #if FF_API_AVFILTERBUFFER
32 AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame,
33  int perms)
34 {
35  AVFilterBufferRef *picref =
37  frame->width, frame->height,
38  frame->format);
39  if (!picref)
40  return NULL;
41  if (avfilter_copy_frame_props(picref, frame) < 0) {
42  picref->buf->data[0] = NULL;
43  avfilter_unref_bufferp(&picref);
44  }
45  return picref;
46 }
47 
48 AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame,
49  int perms)
50 {
51  AVFilterBufferRef *samplesref;
52  int channels = av_frame_get_channels(frame);
53  int64_t layout = av_frame_get_channel_layout(frame);
54 
55  if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
56  av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
57  return NULL;
58  }
59 
60  samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels(
61  (uint8_t **)frame->extended_data, frame->linesize[0], perms,
62  frame->nb_samples, frame->format, channels, layout);
63  if (!samplesref)
64  return NULL;
65  if (avfilter_copy_frame_props(samplesref, frame) < 0) {
66  samplesref->buf->data[0] = NULL;
67  avfilter_unref_bufferp(&samplesref);
68  }
69  return samplesref;
70 }
71 
72 AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type,
73  const AVFrame *frame,
74  int perms)
75 {
76  switch (type) {
77  case AVMEDIA_TYPE_VIDEO:
78  return avfilter_get_video_buffer_ref_from_frame(frame, perms);
79  case AVMEDIA_TYPE_AUDIO:
80  return avfilter_get_audio_buffer_ref_from_frame(frame, perms);
81  default:
82  return NULL;
83  }
84 }
85 
86 int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
87 {
88  int planes, nb_channels;
89 
90  if (!dst)
91  return AVERROR(EINVAL);
92  /* abort in case the src is NULL and dst is not, avoid inconsistent state in dst */
93  av_assert0(src);
94 
95  memcpy(dst->data, src->data, sizeof(dst->data));
96  memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
97 
98  dst->pts = src->pts;
99  dst->format = src->format;
100  av_frame_set_pkt_pos(dst, src->pos);
101 
102  switch (src->type) {
103  case AVMEDIA_TYPE_VIDEO:
104  av_assert0(src->video);
105  dst->width = src->video->w;
106  dst->height = src->video->h;
107  dst->sample_aspect_ratio = src->video->sample_aspect_ratio;
108  dst->interlaced_frame = src->video->interlaced;
109  dst->top_field_first = src->video->top_field_first;
110  dst->key_frame = src->video->key_frame;
111  dst->pict_type = src->video->pict_type;
112  break;
113  case AVMEDIA_TYPE_AUDIO:
114  av_assert0(src->audio);
115  nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
116  planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
117 
118  if (planes > FF_ARRAY_ELEMS(dst->data)) {
119  dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
120  if (!dst->extended_data)
121  return AVERROR(ENOMEM);
122  memcpy(dst->extended_data, src->extended_data,
123  planes * sizeof(*dst->extended_data));
124  } else
125  dst->extended_data = dst->data;
126  dst->nb_samples = src->audio->nb_samples;
127  av_frame_set_sample_rate (dst, src->audio->sample_rate);
129  av_frame_set_channels (dst, src->audio->channels);
130  break;
131  default:
132  return AVERROR(EINVAL);
133  }
134 
135  return 0;
136 }
137 #endif
138 
139 #if FF_API_FILL_FRAME
140 int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
141  const AVFilterBufferRef *samplesref)
142 {
143  return avfilter_copy_buf_props(frame, samplesref);
144 }
145 
146 int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
147  const AVFilterBufferRef *picref)
148 {
149  return avfilter_copy_buf_props(frame, picref);
150 }
151 
152 int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
153  const AVFilterBufferRef *ref)
154 {
155  return avfilter_copy_buf_props(frame, ref);
156 }
157 #endif