codec_par.c (9301B)
1 /* 2 * AVCodecParameters functions for libavcodec 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 * AVCodecParameters functions for libavcodec. 24 */ 25 26 #include <string.h> 27 #include "libavutil/mem.h" 28 #include "avcodec.h" 29 #include "codec_par.h" 30 #include "packet.h" 31 32 static void codec_parameters_reset(AVCodecParameters *par) 33 { 34 av_freep(&par->extradata); 35 av_channel_layout_uninit(&par->ch_layout); 36 av_packet_side_data_free(&par->coded_side_data, &par->nb_coded_side_data); 37 38 memset(par, 0, sizeof(*par)); 39 40 par->codec_type = AVMEDIA_TYPE_UNKNOWN; 41 par->codec_id = AV_CODEC_ID_NONE; 42 par->format = -1; 43 par->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 44 par->field_order = AV_FIELD_UNKNOWN; 45 par->color_range = AVCOL_RANGE_UNSPECIFIED; 46 par->color_primaries = AVCOL_PRI_UNSPECIFIED; 47 par->color_trc = AVCOL_TRC_UNSPECIFIED; 48 par->color_space = AVCOL_SPC_UNSPECIFIED; 49 par->chroma_location = AVCHROMA_LOC_UNSPECIFIED; 50 par->sample_aspect_ratio = (AVRational){ 0, 1 }; 51 par->framerate = (AVRational){ 0, 1 }; 52 par->profile = AV_PROFILE_UNKNOWN; 53 par->level = AV_LEVEL_UNKNOWN; 54 } 55 56 AVCodecParameters *avcodec_parameters_alloc(void) 57 { 58 AVCodecParameters *par = av_mallocz(sizeof(*par)); 59 60 if (!par) 61 return NULL; 62 codec_parameters_reset(par); 63 return par; 64 } 65 66 void avcodec_parameters_free(AVCodecParameters **ppar) 67 { 68 AVCodecParameters *par = *ppar; 69 70 if (!par) 71 return; 72 codec_parameters_reset(par); 73 74 av_freep(ppar); 75 } 76 77 static int codec_parameters_copy_side_data(AVPacketSideData **pdst, int *pnb_dst, 78 const AVPacketSideData *src, int nb_src) 79 { 80 AVPacketSideData *dst; 81 int nb_dst = *pnb_dst; 82 83 if (!src) 84 return 0; 85 86 *pdst = dst = av_calloc(nb_src, sizeof(*dst)); 87 if (!dst) 88 return AVERROR(ENOMEM); 89 90 for (int i = 0; i < nb_src; i++) { 91 const AVPacketSideData *src_sd = &src[i]; 92 AVPacketSideData *dst_sd = &dst[i]; 93 94 dst_sd->data = av_memdup(src_sd->data, src_sd->size); 95 if (!dst_sd->data) 96 return AVERROR(ENOMEM); 97 98 dst_sd->type = src_sd->type; 99 dst_sd->size = src_sd->size; 100 *pnb_dst = ++nb_dst; 101 } 102 103 return 0; 104 } 105 106 int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src) 107 { 108 int ret; 109 110 codec_parameters_reset(dst); 111 memcpy(dst, src, sizeof(*dst)); 112 113 dst->ch_layout = (AVChannelLayout){0}; 114 dst->extradata = NULL; 115 dst->extradata_size = 0; 116 dst->coded_side_data = NULL; 117 dst->nb_coded_side_data = 0; 118 if (src->extradata) { 119 dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 120 if (!dst->extradata) 121 return AVERROR(ENOMEM); 122 memcpy(dst->extradata, src->extradata, src->extradata_size); 123 dst->extradata_size = src->extradata_size; 124 } 125 ret = codec_parameters_copy_side_data(&dst->coded_side_data, &dst->nb_coded_side_data, 126 src->coded_side_data, src->nb_coded_side_data); 127 if (ret < 0) 128 return ret; 129 130 ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); 131 if (ret < 0) 132 return ret; 133 134 return 0; 135 } 136 137 int avcodec_parameters_from_context(AVCodecParameters *par, 138 const AVCodecContext *codec) 139 { 140 int ret; 141 142 codec_parameters_reset(par); 143 144 par->codec_type = codec->codec_type; 145 par->codec_id = codec->codec_id; 146 par->codec_tag = codec->codec_tag; 147 148 par->bit_rate = codec->bit_rate; 149 par->bits_per_coded_sample = codec->bits_per_coded_sample; 150 par->bits_per_raw_sample = codec->bits_per_raw_sample; 151 par->profile = codec->profile; 152 par->level = codec->level; 153 154 switch (par->codec_type) { 155 case AVMEDIA_TYPE_VIDEO: 156 par->format = codec->pix_fmt; 157 par->width = codec->width; 158 par->height = codec->height; 159 par->field_order = codec->field_order; 160 par->color_range = codec->color_range; 161 par->color_primaries = codec->color_primaries; 162 par->color_trc = codec->color_trc; 163 par->color_space = codec->colorspace; 164 par->chroma_location = codec->chroma_sample_location; 165 par->sample_aspect_ratio = codec->sample_aspect_ratio; 166 par->video_delay = codec->has_b_frames; 167 par->framerate = codec->framerate; 168 break; 169 case AVMEDIA_TYPE_AUDIO: 170 par->format = codec->sample_fmt; 171 ret = av_channel_layout_copy(&par->ch_layout, &codec->ch_layout); 172 if (ret < 0) 173 return ret; 174 par->sample_rate = codec->sample_rate; 175 par->block_align = codec->block_align; 176 par->frame_size = codec->frame_size; 177 par->initial_padding = codec->initial_padding; 178 par->trailing_padding = codec->trailing_padding; 179 par->seek_preroll = codec->seek_preroll; 180 break; 181 case AVMEDIA_TYPE_SUBTITLE: 182 par->width = codec->width; 183 par->height = codec->height; 184 break; 185 } 186 187 if (codec->extradata) { 188 par->extradata = av_mallocz(codec->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 189 if (!par->extradata) 190 return AVERROR(ENOMEM); 191 memcpy(par->extradata, codec->extradata, codec->extradata_size); 192 par->extradata_size = codec->extradata_size; 193 } 194 195 ret = codec_parameters_copy_side_data(&par->coded_side_data, &par->nb_coded_side_data, 196 codec->coded_side_data, codec->nb_coded_side_data); 197 if (ret < 0) 198 return ret; 199 200 return 0; 201 } 202 203 int avcodec_parameters_to_context(AVCodecContext *codec, 204 const AVCodecParameters *par) 205 { 206 int ret; 207 208 codec->codec_type = par->codec_type; 209 codec->codec_id = par->codec_id; 210 codec->codec_tag = par->codec_tag; 211 212 codec->bit_rate = par->bit_rate; 213 codec->bits_per_coded_sample = par->bits_per_coded_sample; 214 codec->bits_per_raw_sample = par->bits_per_raw_sample; 215 codec->profile = par->profile; 216 codec->level = par->level; 217 218 switch (par->codec_type) { 219 case AVMEDIA_TYPE_VIDEO: 220 codec->pix_fmt = par->format; 221 codec->width = par->width; 222 codec->height = par->height; 223 codec->field_order = par->field_order; 224 codec->color_range = par->color_range; 225 codec->color_primaries = par->color_primaries; 226 codec->color_trc = par->color_trc; 227 codec->colorspace = par->color_space; 228 codec->chroma_sample_location = par->chroma_location; 229 codec->sample_aspect_ratio = par->sample_aspect_ratio; 230 codec->has_b_frames = par->video_delay; 231 codec->framerate = par->framerate; 232 break; 233 case AVMEDIA_TYPE_AUDIO: 234 codec->sample_fmt = par->format; 235 ret = av_channel_layout_copy(&codec->ch_layout, &par->ch_layout); 236 if (ret < 0) 237 return ret; 238 codec->sample_rate = par->sample_rate; 239 codec->block_align = par->block_align; 240 codec->frame_size = par->frame_size; 241 codec->delay = 242 codec->initial_padding = par->initial_padding; 243 codec->trailing_padding = par->trailing_padding; 244 codec->seek_preroll = par->seek_preroll; 245 break; 246 case AVMEDIA_TYPE_SUBTITLE: 247 codec->width = par->width; 248 codec->height = par->height; 249 break; 250 } 251 252 av_freep(&codec->extradata); 253 codec->extradata_size = 0; 254 if (par->extradata) { 255 codec->extradata = av_mallocz(par->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 256 if (!codec->extradata) 257 return AVERROR(ENOMEM); 258 memcpy(codec->extradata, par->extradata, par->extradata_size); 259 codec->extradata_size = par->extradata_size; 260 } 261 262 av_packet_side_data_free(&codec->coded_side_data, &codec->nb_coded_side_data); 263 ret = codec_parameters_copy_side_data(&codec->coded_side_data, &codec->nb_coded_side_data, 264 par->coded_side_data, par->nb_coded_side_data); 265 if (ret < 0) 266 return ret; 267 268 return 0; 269 }