FFmpeg
 All Data Structures 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"
28 #include "libavutil/opt.h"
29 
31 {
32  dst->pts = src->pts;
33  dst->pos = av_frame_get_pkt_pos(src);
34  dst->format = src->format;
35 
36  av_dict_free(&dst->metadata);
38 
39  switch (dst->type) {
40  case AVMEDIA_TYPE_VIDEO:
41  dst->video->w = src->width;
42  dst->video->h = src->height;
44  dst->video->interlaced = src->interlaced_frame;
46  dst->video->key_frame = src->key_frame;
47  dst->video->pict_type = src->pict_type;
48  av_freep(&dst->video->qp_table);
49  dst->video->qp_table_linesize = 0;
50  if (src->qscale_table) {
51  int qsize = src->qstride ? src->qstride * ((src->height+15)/16) : (src->width+15)/16;
52  dst->video->qp_table = av_malloc(qsize);
53  if (!dst->video->qp_table)
54  return AVERROR(ENOMEM);
55  dst->video->qp_table_linesize = src->qstride;
56  dst->video->qp_table_size = qsize;
57  memcpy(dst->video->qp_table, src->qscale_table, qsize);
58  }
59  break;
60  case AVMEDIA_TYPE_AUDIO:
61  dst->audio->sample_rate = src->sample_rate;
62  dst->audio->channel_layout = src->channel_layout;
63  dst->audio->channels = src->channels;
65  av_log(NULL, AV_LOG_ERROR, "libavfilter does not support this channel layout\n");
66  return AVERROR(EINVAL);
67  }
68  break;
69  default:
70  return AVERROR(EINVAL);
71  }
72 
73  return 0;
74 }
75 
77  int perms)
78 {
79  AVFilterBufferRef *picref =
81  frame->width, frame->height,
82  frame->format);
83  if (!picref)
84  return NULL;
85  if (avfilter_copy_frame_props(picref, frame) < 0) {
86  picref->buf->data[0] = NULL;
87  avfilter_unref_bufferp(&picref);
88  }
89  return picref;
90 }
91 
93  int perms)
94 {
95  AVFilterBufferRef *samplesref;
96  int channels = av_frame_get_channels(frame);
97  int64_t layout = av_frame_get_channel_layout(frame);
98 
99  if(av_frame_get_channels(frame) > 8) // libavfilter does not suport more than 8 channels FIXME, remove once libavfilter is fixed
100  return NULL;
101 
102  if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) {
103  av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n");
104  return NULL;
105  }
106 
108  (uint8_t **)frame->data, frame->linesize[0], perms,
109  frame->nb_samples, frame->format, channels, layout);
110  if (!samplesref)
111  return NULL;
112  if (avfilter_copy_frame_props(samplesref, frame) < 0) {
113  samplesref->buf->data[0] = NULL;
114  avfilter_unref_bufferp(&samplesref);
115  }
116  return samplesref;
117 }
118 
120  const AVFrame *frame,
121  int perms)
122 {
123  switch (type) {
124  case AVMEDIA_TYPE_VIDEO:
125  return avfilter_get_video_buffer_ref_from_frame(frame, perms);
126  case AVMEDIA_TYPE_AUDIO:
127  return avfilter_get_audio_buffer_ref_from_frame(frame, perms);
128  default:
129  return NULL;
130  }
131 }
132 
134 {
135  int planes, nb_channels;
136 
137  if (!dst)
138  return AVERROR(EINVAL);
139  /* abort in case the src is NULL and dst is not, avoid inconsistent state in dst */
140  av_assert0(src);
141 
142  memcpy(dst->data, src->data, sizeof(dst->data));
143  memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
144 
145  dst->pts = src->pts;
146  dst->format = src->format;
147  av_frame_set_pkt_pos(dst, src->pos);
148 
149  switch (src->type) {
150  case AVMEDIA_TYPE_VIDEO:
151  av_assert0(src->video);
152  dst->width = src->video->w;
153  dst->height = src->video->h;
155  dst->interlaced_frame = src->video->interlaced;
157  dst->key_frame = src->video->key_frame;
158  dst->pict_type = src->video->pict_type;
159  break;
160  case AVMEDIA_TYPE_AUDIO:
161  av_assert0(src->audio);
163  planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
164 
165  if (planes > FF_ARRAY_ELEMS(dst->data)) {
166  dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
167  if (!dst->extended_data)
168  return AVERROR(ENOMEM);
169  memcpy(dst->extended_data, src->extended_data,
170  planes * sizeof(*dst->extended_data));
171  } else
172  dst->extended_data = dst->data;
173  dst->nb_samples = src->audio->nb_samples;
176  av_frame_set_channels (dst, src->audio->channels);
177  break;
178  default:
179  return AVERROR(EINVAL);
180  }
181 
182  return 0;
183 }
184 
185 #ifdef FF_API_FILL_FRAME
186 int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
187  const AVFilterBufferRef *samplesref)
188 {
189  return avfilter_copy_buf_props(frame, samplesref);
190 }
191 
192 int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
193  const AVFilterBufferRef *picref)
194 {
195  return avfilter_copy_buf_props(frame, picref);
196 }
197 
198 int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
199  const AVFilterBufferRef *ref)
200 {
201  return avfilter_copy_buf_props(frame, ref);
202 }
203 #endif