xref: /third_party/ffmpeg/libavcodec/codec_par.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * AVCodecParameters functions for libavcodec
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci/**
22cabdff1aSopenharmony_ci * @file
23cabdff1aSopenharmony_ci * AVCodecParameters functions for libavcodec.
24cabdff1aSopenharmony_ci */
25cabdff1aSopenharmony_ci
26cabdff1aSopenharmony_ci#include <string.h>
27cabdff1aSopenharmony_ci#include "libavutil/mem.h"
28cabdff1aSopenharmony_ci#include "avcodec.h"
29cabdff1aSopenharmony_ci#include "codec_par.h"
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_cistatic void codec_parameters_reset(AVCodecParameters *par)
32cabdff1aSopenharmony_ci{
33cabdff1aSopenharmony_ci    av_freep(&par->extradata);
34cabdff1aSopenharmony_ci    av_channel_layout_uninit(&par->ch_layout);
35cabdff1aSopenharmony_ci
36cabdff1aSopenharmony_ci    memset(par, 0, sizeof(*par));
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci    par->codec_type          = AVMEDIA_TYPE_UNKNOWN;
39cabdff1aSopenharmony_ci    par->codec_id            = AV_CODEC_ID_NONE;
40cabdff1aSopenharmony_ci    par->format              = -1;
41cabdff1aSopenharmony_ci    par->ch_layout.order     = AV_CHANNEL_ORDER_UNSPEC;
42cabdff1aSopenharmony_ci    par->field_order         = AV_FIELD_UNKNOWN;
43cabdff1aSopenharmony_ci    par->color_range         = AVCOL_RANGE_UNSPECIFIED;
44cabdff1aSopenharmony_ci    par->color_primaries     = AVCOL_PRI_UNSPECIFIED;
45cabdff1aSopenharmony_ci    par->color_trc           = AVCOL_TRC_UNSPECIFIED;
46cabdff1aSopenharmony_ci    par->color_space         = AVCOL_SPC_UNSPECIFIED;
47cabdff1aSopenharmony_ci    par->chroma_location     = AVCHROMA_LOC_UNSPECIFIED;
48cabdff1aSopenharmony_ci    par->sample_aspect_ratio = (AVRational){ 0, 1 };
49cabdff1aSopenharmony_ci    par->profile             = FF_PROFILE_UNKNOWN;
50cabdff1aSopenharmony_ci    par->level               = FF_LEVEL_UNKNOWN;
51cabdff1aSopenharmony_ci}
52cabdff1aSopenharmony_ci
53cabdff1aSopenharmony_ciAVCodecParameters *avcodec_parameters_alloc(void)
54cabdff1aSopenharmony_ci{
55cabdff1aSopenharmony_ci    AVCodecParameters *par = av_mallocz(sizeof(*par));
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci    if (!par)
58cabdff1aSopenharmony_ci        return NULL;
59cabdff1aSopenharmony_ci    codec_parameters_reset(par);
60cabdff1aSopenharmony_ci    return par;
61cabdff1aSopenharmony_ci}
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_civoid avcodec_parameters_free(AVCodecParameters **ppar)
64cabdff1aSopenharmony_ci{
65cabdff1aSopenharmony_ci    AVCodecParameters *par = *ppar;
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci    if (!par)
68cabdff1aSopenharmony_ci        return;
69cabdff1aSopenharmony_ci    codec_parameters_reset(par);
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci    av_freep(ppar);
72cabdff1aSopenharmony_ci}
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ciint avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
75cabdff1aSopenharmony_ci{
76cabdff1aSopenharmony_ci    int ret;
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_ci    codec_parameters_reset(dst);
79cabdff1aSopenharmony_ci    memcpy(dst, src, sizeof(*dst));
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci    dst->ch_layout      = (AVChannelLayout){0};
82cabdff1aSopenharmony_ci    dst->extradata      = NULL;
83cabdff1aSopenharmony_ci    dst->extradata_size = 0;
84cabdff1aSopenharmony_ci    if (src->extradata) {
85cabdff1aSopenharmony_ci        dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
86cabdff1aSopenharmony_ci        if (!dst->extradata)
87cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
88cabdff1aSopenharmony_ci        memcpy(dst->extradata, src->extradata, src->extradata_size);
89cabdff1aSopenharmony_ci        dst->extradata_size = src->extradata_size;
90cabdff1aSopenharmony_ci    }
91cabdff1aSopenharmony_ci
92cabdff1aSopenharmony_ci    ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
93cabdff1aSopenharmony_ci    if (ret < 0)
94cabdff1aSopenharmony_ci        return ret;
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_ci    return 0;
97cabdff1aSopenharmony_ci}
98cabdff1aSopenharmony_ci
99cabdff1aSopenharmony_ciint avcodec_parameters_from_context(AVCodecParameters *par,
100cabdff1aSopenharmony_ci                                    const AVCodecContext *codec)
101cabdff1aSopenharmony_ci{
102cabdff1aSopenharmony_ci    int ret;
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_ci    codec_parameters_reset(par);
105cabdff1aSopenharmony_ci
106cabdff1aSopenharmony_ci    par->codec_type = codec->codec_type;
107cabdff1aSopenharmony_ci    par->codec_id   = codec->codec_id;
108cabdff1aSopenharmony_ci    par->codec_tag  = codec->codec_tag;
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci    par->bit_rate              = codec->bit_rate;
111cabdff1aSopenharmony_ci    par->bits_per_coded_sample = codec->bits_per_coded_sample;
112cabdff1aSopenharmony_ci    par->bits_per_raw_sample   = codec->bits_per_raw_sample;
113cabdff1aSopenharmony_ci    par->profile               = codec->profile;
114cabdff1aSopenharmony_ci    par->level                 = codec->level;
115cabdff1aSopenharmony_ci
116cabdff1aSopenharmony_ci    switch (par->codec_type) {
117cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_VIDEO:
118cabdff1aSopenharmony_ci        par->format              = codec->pix_fmt;
119cabdff1aSopenharmony_ci        par->width               = codec->width;
120cabdff1aSopenharmony_ci        par->height              = codec->height;
121cabdff1aSopenharmony_ci        par->field_order         = codec->field_order;
122cabdff1aSopenharmony_ci        par->color_range         = codec->color_range;
123cabdff1aSopenharmony_ci        par->color_primaries     = codec->color_primaries;
124cabdff1aSopenharmony_ci        par->color_trc           = codec->color_trc;
125cabdff1aSopenharmony_ci        par->color_space         = codec->colorspace;
126cabdff1aSopenharmony_ci        par->chroma_location     = codec->chroma_sample_location;
127cabdff1aSopenharmony_ci        par->sample_aspect_ratio = codec->sample_aspect_ratio;
128cabdff1aSopenharmony_ci        par->video_delay         = codec->has_b_frames;
129cabdff1aSopenharmony_ci        break;
130cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_AUDIO:
131cabdff1aSopenharmony_ci        par->format           = codec->sample_fmt;
132cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT
133cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
134cabdff1aSopenharmony_ci        // if the old/new fields are set inconsistently, prefer the old ones
135cabdff1aSopenharmony_ci        if ((codec->channels && codec->channels != codec->ch_layout.nb_channels) ||
136cabdff1aSopenharmony_ci            (codec->channel_layout && (codec->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
137cabdff1aSopenharmony_ci                                       codec->ch_layout.u.mask != codec->channel_layout))) {
138cabdff1aSopenharmony_ci            if (codec->channel_layout)
139cabdff1aSopenharmony_ci                av_channel_layout_from_mask(&par->ch_layout, codec->channel_layout);
140cabdff1aSopenharmony_ci            else {
141cabdff1aSopenharmony_ci                par->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
142cabdff1aSopenharmony_ci                par->ch_layout.nb_channels = codec->channels;
143cabdff1aSopenharmony_ci            }
144cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
145cabdff1aSopenharmony_ci        } else {
146cabdff1aSopenharmony_ci#endif
147cabdff1aSopenharmony_ci        ret = av_channel_layout_copy(&par->ch_layout, &codec->ch_layout);
148cabdff1aSopenharmony_ci        if (ret < 0)
149cabdff1aSopenharmony_ci            return ret;
150cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT
151cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
152cabdff1aSopenharmony_ci        }
153cabdff1aSopenharmony_ci        par->channel_layout  = par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
154cabdff1aSopenharmony_ci                               par->ch_layout.u.mask : 0;
155cabdff1aSopenharmony_ci        par->channels        = par->ch_layout.nb_channels;
156cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
157cabdff1aSopenharmony_ci#endif
158cabdff1aSopenharmony_ci        par->sample_rate      = codec->sample_rate;
159cabdff1aSopenharmony_ci        par->block_align      = codec->block_align;
160cabdff1aSopenharmony_ci        par->frame_size       = codec->frame_size;
161cabdff1aSopenharmony_ci        par->initial_padding  = codec->initial_padding;
162cabdff1aSopenharmony_ci        par->trailing_padding = codec->trailing_padding;
163cabdff1aSopenharmony_ci        par->seek_preroll     = codec->seek_preroll;
164cabdff1aSopenharmony_ci        break;
165cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_SUBTITLE:
166cabdff1aSopenharmony_ci        par->width  = codec->width;
167cabdff1aSopenharmony_ci        par->height = codec->height;
168cabdff1aSopenharmony_ci        break;
169cabdff1aSopenharmony_ci    }
170cabdff1aSopenharmony_ci
171cabdff1aSopenharmony_ci    if (codec->extradata) {
172cabdff1aSopenharmony_ci        par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
173cabdff1aSopenharmony_ci        if (!par->extradata)
174cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
175cabdff1aSopenharmony_ci        memcpy(par->extradata, codec->extradata, codec->extradata_size);
176cabdff1aSopenharmony_ci        par->extradata_size = codec->extradata_size;
177cabdff1aSopenharmony_ci    }
178cabdff1aSopenharmony_ci
179cabdff1aSopenharmony_ci    return 0;
180cabdff1aSopenharmony_ci}
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ciint avcodec_parameters_to_context(AVCodecContext *codec,
183cabdff1aSopenharmony_ci                                  const AVCodecParameters *par)
184cabdff1aSopenharmony_ci{
185cabdff1aSopenharmony_ci    int ret;
186cabdff1aSopenharmony_ci
187cabdff1aSopenharmony_ci    codec->codec_type = par->codec_type;
188cabdff1aSopenharmony_ci    codec->codec_id   = par->codec_id;
189cabdff1aSopenharmony_ci    codec->codec_tag  = par->codec_tag;
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci    codec->bit_rate              = par->bit_rate;
192cabdff1aSopenharmony_ci    codec->bits_per_coded_sample = par->bits_per_coded_sample;
193cabdff1aSopenharmony_ci    codec->bits_per_raw_sample   = par->bits_per_raw_sample;
194cabdff1aSopenharmony_ci    codec->profile               = par->profile;
195cabdff1aSopenharmony_ci    codec->level                 = par->level;
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_ci    switch (par->codec_type) {
198cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_VIDEO:
199cabdff1aSopenharmony_ci        codec->pix_fmt                = par->format;
200cabdff1aSopenharmony_ci        codec->width                  = par->width;
201cabdff1aSopenharmony_ci        codec->height                 = par->height;
202cabdff1aSopenharmony_ci        codec->field_order            = par->field_order;
203cabdff1aSopenharmony_ci        codec->color_range            = par->color_range;
204cabdff1aSopenharmony_ci        codec->color_primaries        = par->color_primaries;
205cabdff1aSopenharmony_ci        codec->color_trc              = par->color_trc;
206cabdff1aSopenharmony_ci        codec->colorspace             = par->color_space;
207cabdff1aSopenharmony_ci        codec->chroma_sample_location = par->chroma_location;
208cabdff1aSopenharmony_ci        codec->sample_aspect_ratio    = par->sample_aspect_ratio;
209cabdff1aSopenharmony_ci        codec->has_b_frames           = par->video_delay;
210cabdff1aSopenharmony_ci        break;
211cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_AUDIO:
212cabdff1aSopenharmony_ci        codec->sample_fmt       = par->format;
213cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT
214cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
215cabdff1aSopenharmony_ci        // if the old/new fields are set inconsistently, prefer the old ones
216cabdff1aSopenharmony_ci        if ((par->channels && par->channels != par->ch_layout.nb_channels) ||
217cabdff1aSopenharmony_ci            (par->channel_layout && (par->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
218cabdff1aSopenharmony_ci                                     par->ch_layout.u.mask != par->channel_layout))) {
219cabdff1aSopenharmony_ci            if (par->channel_layout)
220cabdff1aSopenharmony_ci                av_channel_layout_from_mask(&codec->ch_layout, par->channel_layout);
221cabdff1aSopenharmony_ci            else {
222cabdff1aSopenharmony_ci                codec->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
223cabdff1aSopenharmony_ci                codec->ch_layout.nb_channels = par->channels;
224cabdff1aSopenharmony_ci            }
225cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
226cabdff1aSopenharmony_ci        } else {
227cabdff1aSopenharmony_ci#endif
228cabdff1aSopenharmony_ci        ret = av_channel_layout_copy(&codec->ch_layout, &par->ch_layout);
229cabdff1aSopenharmony_ci        if (ret < 0)
230cabdff1aSopenharmony_ci            return ret;
231cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT
232cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS
233cabdff1aSopenharmony_ci        }
234cabdff1aSopenharmony_ci        codec->channel_layout = codec->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
235cabdff1aSopenharmony_ci                                codec->ch_layout.u.mask : 0;
236cabdff1aSopenharmony_ci        codec->channels       = codec->ch_layout.nb_channels;
237cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS
238cabdff1aSopenharmony_ci#endif
239cabdff1aSopenharmony_ci        codec->sample_rate      = par->sample_rate;
240cabdff1aSopenharmony_ci        codec->block_align      = par->block_align;
241cabdff1aSopenharmony_ci        codec->frame_size       = par->frame_size;
242cabdff1aSopenharmony_ci        codec->delay            =
243cabdff1aSopenharmony_ci        codec->initial_padding  = par->initial_padding;
244cabdff1aSopenharmony_ci        codec->trailing_padding = par->trailing_padding;
245cabdff1aSopenharmony_ci        codec->seek_preroll     = par->seek_preroll;
246cabdff1aSopenharmony_ci        break;
247cabdff1aSopenharmony_ci    case AVMEDIA_TYPE_SUBTITLE:
248cabdff1aSopenharmony_ci        codec->width  = par->width;
249cabdff1aSopenharmony_ci        codec->height = par->height;
250cabdff1aSopenharmony_ci        break;
251cabdff1aSopenharmony_ci    }
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_ci    if (par->extradata) {
254cabdff1aSopenharmony_ci        av_freep(&codec->extradata);
255cabdff1aSopenharmony_ci        codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
256cabdff1aSopenharmony_ci        if (!codec->extradata)
257cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
258cabdff1aSopenharmony_ci        memcpy(codec->extradata, par->extradata, par->extradata_size);
259cabdff1aSopenharmony_ci        codec->extradata_size = par->extradata_size;
260cabdff1aSopenharmony_ci    }
261cabdff1aSopenharmony_ci
262cabdff1aSopenharmony_ci    return 0;
263cabdff1aSopenharmony_ci}
264