Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 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/channel_layout.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 = |
||
36 | avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, perms, |
||
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); |
||
128 | av_frame_set_channel_layout(dst, src->audio->channel_layout); |
||
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>> |