AVPKit
ContainerFormat.cpp
1 /*******************************************************************************
2  * Copyright (c) 2024, 2026, Olivier Ayache. All rights reserved.
3  *
4  * This file is part of AVPKit.
5  *
6  * AVPKit is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * AVPKit 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
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with AVPKit. If not, see <http://www.gnu.org/licenses/>.
18  *******************************************************************************/
19 
20 #include <com/avpkit/core/ContainerFormat.h>
21 
22 #define VS_FFMPEG_GOT_OFF_THEIR_BUTT_AND_EXPOSED_THIS
23 #ifdef VS_FFMPEG_GOT_OFF_THEIR_BUTT_AND_EXPOSED_THIS
24 /*
25  * Sigh; this hack is necessary because FFMPEG doesn't actually
26  * expose the AVCodecTag structure. This might break if they
27  * change the structure, but by placing it here it should
28  * at least cause a compiler error.
29  */
30 struct AVCodecTag
31 {
32  int32_t id;
33  uint32_t tag;
34 };
35 #endif
36 
37 namespace com { namespace avpkit { namespace core
38 {
39 
40  ContainerFormat :: ContainerFormat()
41  {
42  mInputFormat = NULL;
43  mOutputFormat = NULL;
44  }
45 
46  ContainerFormat :: ~ContainerFormat()
47  {
48  }
49 
50  int32_t
51  ContainerFormat :: setInputFormat(const char *shortName)
52  {
53  if (shortName && *shortName)
54  {
55  mInputFormat = av_find_input_format(shortName);
56  } else {
57  mInputFormat = NULL;
58  }
59  return (mInputFormat == NULL ? -1 : 0);
60  }
61  int32_t
62  ContainerFormat :: setOutputFormat(const char*shortName,
63  const char*url,
64  const char* mimeType)
65  {
66  if ((shortName && *shortName) ||
67  (url && *url) ||
68  (mimeType && *mimeType))
69  {
70  mOutputFormat = av_guess_format(shortName, url, mimeType);
71  } else {
72  mOutputFormat = NULL;
73  }
74  return (mOutputFormat == NULL ? -1 : 0);
75  }
76  const char*
78  {
79  return (mInputFormat ? mInputFormat->name : 0);
80  }
81  const char*
83  {
84  return (mInputFormat ? mInputFormat->long_name : 0);
85  }
86  const char *
88  {
89  return (mOutputFormat ? mOutputFormat->name : 0);
90  }
91  const char *
93  {
94  return (mOutputFormat ? mOutputFormat->long_name : 0);
95  }
96  const char *
98  {
99  return (mOutputFormat ? mOutputFormat->mime_type : 0);
100  }
101  AVInputFormat*
102  ContainerFormat :: getInputFormat()
103  {
104  return mInputFormat;
105  }
106  AVOutputFormat*
107  ContainerFormat :: getOutputFormat()
108  {
109  return mOutputFormat;
110  }
111  void
112  ContainerFormat :: setInputFormat(AVInputFormat* fmt)
113  {
114  mInputFormat = fmt;
115  }
116  void
117  ContainerFormat :: setOutputFormat(AVOutputFormat* fmt)
118  {
119  mOutputFormat = fmt;
120  }
121 
122  int32_t
124  {
125  return (mInputFormat ? mInputFormat->flags : 0);
126  }
127 
128  void
130  {
131  if (mInputFormat)
132  mInputFormat->flags = newFlags;
133  }
134 
135  bool
136  ContainerFormat :: getInputFlag(IContainerFormat::Flags flag)
137  {
138  bool result = false;
139  if (mInputFormat)
140  result = mInputFormat->flags & flag;
141  return result;
142  }
143 
144  void
145  ContainerFormat :: setInputFlag(IContainerFormat::Flags flag, bool value)
146  {
147  if (mInputFormat)
148  {
149  if (value)
150  {
151  mInputFormat->flags |= flag;
152  }
153  else
154  {
155  mInputFormat->flags &= (~flag);
156  }
157  }
158  }
159 
160  int32_t
162  {
163  return (mOutputFormat ? mOutputFormat->flags : 0);
164  }
165 
166  void
168  {
169  if (mOutputFormat)
170  mOutputFormat->flags = newFlags;
171  }
172 
173  bool
174  ContainerFormat :: getOutputFlag(IContainerFormat::Flags flag)
175  {
176  bool result = false;
177  if (mOutputFormat)
178  result = mOutputFormat->flags & flag;
179  return result;
180  }
181 
182  void
183  ContainerFormat :: setOutputFlag(IContainerFormat::Flags flag, bool value)
184  {
185  if (mOutputFormat)
186  {
187  if (value)
188  {
189  mOutputFormat->flags |= flag;
190  }
191  else
192  {
193  mOutputFormat->flags &= (~flag);
194  }
195  }
196  }
197  bool
199  {
200  return mOutputFormat;
201  }
202 
203  bool
205  {
206  return mInputFormat;
207  }
208 
209  const char *
211  {
212  if (!mOutputFormat || !mOutputFormat->extensions ||
213  !*mOutputFormat->extensions)
214  return 0;
215  return mOutputFormat->extensions;
216  }
217 
218  ICodec::ID
220  {
221  if (!mOutputFormat)
222  return ICodec::AV_CODEC_ID_NONE;
223  return (ICodec::ID)mOutputFormat->audio_codec;
224  }
225 
226  ICodec::ID
228  {
229  if (!mOutputFormat)
230  return ICodec::AV_CODEC_ID_NONE;
231  return (ICodec::ID)mOutputFormat->video_codec;
232  }
233 
234  ICodec::ID
236  {
237  if (!mOutputFormat)
238  return ICodec::AV_CODEC_ID_NONE;
239  return (ICodec::ID)mOutputFormat->subtitle_codec;
240  }
241 
242  int32_t
244  {
245  if (!mOutputFormat)
246  return 0;
247 
248  const struct AVCodecTag * const*tags = mOutputFormat->codec_tag;
249  if (!tags)
250  return 0;
251 
252  int numCodecs = 0;
253 
254  for(int i = 0;
255  tags[i];
256  i++)
257  {
258  for(const struct AVCodecTag * tag = tags[i];
259  tag && tag->id != ICodec::AV_CODEC_ID_NONE;
260  ++tag)
261  {
262  ++numCodecs;
263  }
264  }
265  return numCodecs;
266  }
267  ICodec::ID
269  {
270  if (index < 0)
271  return ICodec::AV_CODEC_ID_NONE;
272 
273  const struct AVCodecTag * const*tags = mOutputFormat->codec_tag;
274  if (!tags)
275  return ICodec::AV_CODEC_ID_NONE;
276 
277  int numCodecs = 0;
278 
279  for(int i = 0;
280  tags[i];
281  i++)
282  {
283  for(
284  const struct AVCodecTag * tag = tags[i];
285  tag && tag->id != ICodec::AV_CODEC_ID_NONE;
286  ++tag, ++numCodecs)
287  {
288  if (numCodecs == index)
289  return (ICodec::ID)tag->id;
290  }
291  }
292  return ICodec::AV_CODEC_ID_NONE;
293  }
294 
295  int32_t
297  {
298  if (index < 0)
299  return ICodec::AV_CODEC_ID_NONE;
300 
301  const struct AVCodecTag * const*tags = mOutputFormat->codec_tag;
302  if (!tags)
303  return ICodec::AV_CODEC_ID_NONE;
304 
305  int numCodecs = 0;
306 
307  for(int i = 0;
308  tags[i];
309  i++)
310  {
311  for(
312  const struct AVCodecTag * tag = tags[i];
313  tag && tag->id != ICodec::AV_CODEC_ID_NONE;
314  ++tag, ++numCodecs)
315  {
316  if (numCodecs == index)
317  return tag->tag;
318  }
319  }
320  return ICodec::AV_CODEC_ID_NONE;
321  }
322 
323  bool
325  {
326  return getOutputCodecTag(id);
327  }
328 
329  int32_t
331  {
332  if (!mOutputFormat)
333  return 0;
334  return (int32_t)av_codec_get_tag(mOutputFormat->codec_tag,
335  (enum AVCodecID)id);
336 
337  }
338 
339 }}}
virtual int32_t getOutputNumCodecsSupported()
Gets the number of different codecs this container can include for encoding.
virtual const char * getOutputFormatLongName()
Get the long name for the output format.
virtual ICodec::ID getOutputDefaultSubtitleCodec()
Get the default subtitle codec this container prefers, if known.
virtual bool isCodecSupportedForOutput(ICodec::ID id)
Returns true if this container format can output media encoded with the given codec.
virtual int32_t getOutputCodecTag(int32_t index)
Queries for a supported codec tag from the list of codecs that can be encoded into this ContainerForm...
virtual int32_t setInputFormat(const char *shortName)
Sets the input format for this container.
virtual int32_t setOutputFormat(const char *shortName, const char *url, const char *mimeType)
Sets the output format for this container.
virtual bool isInput()
Is this an input container format?
virtual const char * getOutputFormatMimeType()
Get the mime type for the output format.
virtual bool isOutput()
Is this an output container format?
virtual const char * getInputFormatLongName()
Get the long name for the input format.
virtual bool getInputFlag(Flags flag)
Get the input setting for the specified flag.
virtual void setInputFlag(Flags flag, bool value)
Set the input flag.
virtual int32_t getInputFlags()
Get the input flags associated with this object.
virtual bool getOutputFlag(Flags flag)
Get the output setting for the specified flag.
virtual const char * getOutputExtensions()
Get the filename extensions that this output format prefers (most common first).
virtual ICodec::ID getOutputDefaultAudioCodec()
Get the default audio codec this container prefers, if known.
virtual ICodec::ID getOutputDefaultVideoCodec()
Get the default video codec this container prefers, if known.
virtual void setOutputFlag(Flags flag, bool value)
Set the output flag.
virtual const char * getInputFormatShortName()
Get the short name for the input format.
virtual ICodec::ID getOutputCodecID(int32_t index)
Queries for a supported codec id from the list of codecs that can be encoded into this ContainerForma...
virtual int32_t getOutputFlags()
Get the output flags associated with this object.
virtual const char * getOutputFormatShortName()
Get the short name for the output format.
virtual void setInputFlags(int32_t newFlags)
Set the input flags to use with this object.
virtual void setOutputFlags(int32_t newFlags)
Set the output flags to use with this object.
ID
These are the codecs this library currently supports.
Definition: ICodec.h:61
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...