Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2017-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / filters sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/filters.h>
27 : #include <gpac/constants.h>
28 :
29 : typedef struct
30 : {
31 : //codec ID
32 : u32 codecid;
33 : //not defined (0) if codecid>255
34 : u8 mpeg4_oti;
35 : //stream type
36 : u32 stream_type;
37 : //log name
38 : const char *name;
39 : //short name(s) for identifying codec - first value is used as default file ext
40 : const char *sname;
41 : //default name for isobmff/RFC6381
42 : const char *rfc_4cc;
43 : //mime type of raw format
44 : const char *mime_type;
45 : //alternate codecid name
46 : u32 alt_codecid;
47 : } CodecIDReg;
48 :
49 : CodecIDReg CodecRegistry [] = {
50 : {GF_CODECID_BIFS, GF_CODECID_BIFS, GF_STREAM_SCENE, "MPEG-4 BIFS v1 Scene Description", "bifs", "mp4s", "application/bifs"},
51 : {GF_CODECID_BIFS_V2, GF_CODECID_BIFS_V2, GF_STREAM_SCENE, "MPEG-4 BIFS v2 Scene Description", "bifs2", "mp4s", "application/bifs"},
52 : {GF_CODECID_BIFS_EXTENDED, GF_CODECID_BIFS_EXTENDED, GF_STREAM_SCENE, "MPEG-4 BIFS Extended Scene Description", "bifsX", "mp4s", "application/bifs"},
53 : {GF_CODECID_OD_V1, GF_CODECID_OD_V1, GF_STREAM_OD, "MPEG-4 ObjectDescriptor v1", "od", "mp4s", "application/od"},
54 : {GF_CODECID_OD_V2, GF_CODECID_OD_V2, GF_STREAM_OD, "MPEG-4 ObjectDescriptor v2", "od2", "mp4s", "application/od"},
55 : {GF_CODECID_INTERACT, GF_CODECID_INTERACT, GF_STREAM_INTERACT, "MPEG-4 Interaction Stream", "interact", "mp4s", "application/x-mpeg4-interact"},
56 : {GF_CODECID_AFX, GF_CODECID_AFX, GF_STREAM_SCENE, "MPEG-4 AFX Stream", "afx", "mp4s", "application/x-mpeg4-afx"},
57 : {GF_CODECID_FONT, GF_CODECID_FONT, GF_STREAM_FONT, "MPEG-4 Font Stream", "font", "mp4s", "application/x-mpeg4-font"},
58 : {GF_CODECID_SYNTHESIZED_TEXTURE, GF_CODECID_SYNTHESIZED_TEXTURE, GF_STREAM_VISUAL, "MPEG-4 Synthetized Texture", "syntex", "mp4s", "application/x-mpeg4-synth"},
59 : {GF_CODECID_TEXT_MPEG4, GF_CODECID_TEXT_MPEG4, GF_STREAM_TEXT, "MPEG-4 Streaming Text", "m4txt", "text", "application/x-mpeg4-text"},
60 : {GF_CODECID_LASER, GF_CODECID_LASER, GF_STREAM_SCENE, "MPEG-4 LASeR", "laser", "lsr1", "application/x-laser"},
61 : {GF_CODECID_SAF, GF_CODECID_SAF, GF_STREAM_SCENE, "MPEG-4 Simple Aggregation Format", "saf", "mp4s", "application/saf"},
62 : {GF_CODECID_MPEG4_PART2, GF_CODECID_MPEG4_PART2, GF_STREAM_VISUAL, "MPEG-4 Visual part 2", "cmp|m4ve|m4v", "mp4v", "video/mp4v-es"},
63 : {GF_CODECID_AVC, GF_CODECID_AVC, GF_STREAM_VISUAL, "MPEG-4 AVC|H264 Video", "264|avc|h264", "avc1", "video/avc"},
64 : {GF_CODECID_AVC_PS, GF_CODECID_AVC_PS, GF_STREAM_VISUAL, "MPEG-4 AVC|H264 Video Parameter Sets", "avcps", "avcp", "video/avc"},
65 : {GF_CODECID_SVC, GF_CODECID_SVC, GF_STREAM_VISUAL, "MPEG-4 AVC|H264 Scalable Video Coding", "svc|avc|264|h264", "svc1", "video/svc"},
66 : {GF_CODECID_MVC, GF_CODECID_MVC, GF_STREAM_VISUAL, "MPEG-4 AVC|H264 Multiview Video Coding", "mvc", "mvc1", "video/mvc"},
67 : {GF_CODECID_HEVC, GF_CODECID_HEVC, GF_STREAM_VISUAL, "HEVC Video", "hvc|hevc|h265", "hvc1", "video/hevc"},
68 : {GF_CODECID_LHVC, GF_CODECID_LHVC, GF_STREAM_VISUAL, "HEVC Video Layered Extensions", "lhvc|shvc|mhvc", "lhc1", "video/lhvc"},
69 : {GF_CODECID_MPEG2_SIMPLE, GF_CODECID_MPEG2_SIMPLE, GF_STREAM_VISUAL, "MPEG-2 Visual Simple", "m2vs", "mp2v", "video/mp2v-es"},
70 : {GF_CODECID_MPEG2_MAIN, GF_CODECID_MPEG2_MAIN, GF_STREAM_VISUAL, "MPEG-2 Visual Main", "m2v", "mp2v", "video/mp2v-es", GF_CODECID_MPEG2_SIMPLE},
71 : {GF_CODECID_MPEG2_SNR, GF_CODECID_MPEG2_SNR, GF_STREAM_VISUAL, "MPEG-2 Visual SNR", "m2v|m2vsnr", "mp2v", "video/mp2v-es", GF_CODECID_MPEG2_SIMPLE},
72 : {GF_CODECID_MPEG2_SPATIAL, GF_CODECID_MPEG2_SPATIAL, GF_STREAM_VISUAL, "MPEG-2 Visual Spatial", "m2v|m2vspat", "mp2v", "video/mp2v-es", GF_CODECID_MPEG2_SIMPLE},
73 : {GF_CODECID_MPEG2_HIGH, GF_CODECID_MPEG2_HIGH, GF_STREAM_VISUAL, "MPEG-2 Visual High", "m2v|m2vh", "mp2v", "video/mp2v-es", GF_CODECID_MPEG2_SIMPLE},
74 : {GF_CODECID_MPEG2_422, GF_CODECID_MPEG2_422, GF_STREAM_VISUAL, "MPEG-2 Visual 422", "m2v|m2v4", "mp2v", "video/mp2v-es", GF_CODECID_MPEG2_SIMPLE},
75 : {GF_CODECID_MPEG1, GF_CODECID_MPEG1, GF_STREAM_VISUAL, "MPEG-1 Video", "m1v", "mp1v", "video/mp1v-es"},
76 : {GF_CODECID_JPEG, GF_CODECID_JPEG, GF_STREAM_VISUAL, "JPEG Image", "jpg|jpeg", "jpeg", "image/jpeg"},
77 : {GF_CODECID_PNG, GF_CODECID_PNG, GF_STREAM_VISUAL, "PNG Image", "png", "png ", "image/png"},
78 : {GF_CODECID_J2K, 0x6E, GF_STREAM_VISUAL, "JPEG2000 Image", "jp2|j2k", "mjp2", "image/jp2"},
79 : {GF_CODECID_AAC_MPEG4, GF_CODECID_AAC_MPEG4, GF_STREAM_AUDIO, "MPEG-4 AAC Audio", "aac", "mp4a", "audio/aac"},
80 : {GF_CODECID_AAC_MPEG2_MP, GF_CODECID_AAC_MPEG2_MP, GF_STREAM_AUDIO, "MPEG-2 AAC Audio Main", "aac|aac2m", "mp4a", "audio/aac", GF_CODECID_AAC_MPEG4},
81 : {GF_CODECID_AAC_MPEG2_LCP, GF_CODECID_AAC_MPEG2_LCP, GF_STREAM_AUDIO, "MPEG-2 AAC Audio Low Complexity", "aac|aac2l", "mp4a", "audio/aac", GF_CODECID_AAC_MPEG4},
82 : {GF_CODECID_AAC_MPEG2_SSRP, GF_CODECID_AAC_MPEG2_SSRP, GF_STREAM_AUDIO, "MPEG-2 AAC Audio Scalable Sampling Rate", "aac|aac2s", "mp4a", "audio/aac", GF_CODECID_AAC_MPEG4},
83 : {GF_CODECID_MPEG_AUDIO, GF_CODECID_MPEG_AUDIO, GF_STREAM_AUDIO, "MPEG-1 Audio", "mp3|m1a", ".mp3", "audio/mp3"},
84 : {GF_CODECID_MPEG2_PART3, GF_CODECID_MPEG2_PART3, GF_STREAM_AUDIO, "MPEG-2 Audio", "mp3|m2a", ".mp3", "audio/mp3"},
85 : {GF_CODECID_S263, 0, GF_STREAM_VISUAL, "H263 Video", "h263", "s263", "video/h263", .alt_codecid=GF_CODECID_H263},
86 : {GF_CODECID_H263, 0, GF_STREAM_VISUAL, "H263 Video", "h263", "h263", "video/h263", .alt_codecid=GF_CODECID_S263},
87 : {GF_CODECID_HEVC_TILES, 0, GF_STREAM_VISUAL, "HEVC tiles Video", "hvt1", "hvt1", "video/x-hevc-tiles", .alt_codecid=GF_CODECID_HEVC},
88 :
89 : {GF_CODECID_EVRC, 0xA0, GF_STREAM_AUDIO, "EVRC Voice", "evc|evrc", "sevc", "audio/evrc"},
90 : {GF_CODECID_SMV, 0xA1, GF_STREAM_AUDIO, "SMV Voice", "smv", "ssmv", "audio/smv"},
91 : {GF_CODECID_QCELP, 0xE1, GF_STREAM_AUDIO, "QCELP Voice", "qcp|qcelp", "sqcp", "audio/qcelp"},
92 : {GF_CODECID_AMR, 0, GF_STREAM_AUDIO, "AMR Audio", "amr", "samr", "audio/amr"},
93 : {GF_CODECID_AMR_WB, 0, GF_STREAM_AUDIO, "AMR WideBand Audio", "amr|amrwb", "sawb", "audio/amr"},
94 : {GF_CODECID_EVRC_PV, 0, GF_STREAM_AUDIO, "EVRC (PacketVideo MUX) Audio", "qcp|evrcpv", "sevc", "audio/evrc"},
95 : {GF_CODECID_SMPTE_VC1, 0xA3, GF_STREAM_VISUAL, "SMPTE VC-1 Video", "vc1", "vc1 ", "video/vc1"},
96 : {GF_CODECID_DIRAC, 0xA4, GF_STREAM_VISUAL, "Dirac Video", "dirac", NULL, "video/dirac"},
97 : {GF_CODECID_AC3, 0xA5, GF_STREAM_AUDIO, "AC3 Audio", "ac3", "ac-3", "audio/ac3"},
98 : {GF_CODECID_EAC3, 0xA6, GF_STREAM_AUDIO, "Enhanced AC3 Audio", "eac3", "ec-3", "audio/eac3"},
99 : {GF_CODECID_TRUEHD, 0, GF_STREAM_AUDIO, "Dolby TrueHD", "mlp", "mlpa", "audio/truehd"},
100 : {GF_CODECID_DRA, 0xA7, GF_STREAM_AUDIO, "DRA Audio", "dra", NULL, "audio/dra"},
101 : {GF_CODECID_G719, 0xA8, GF_STREAM_AUDIO, "G719 Audio", "g719", NULL, "audio/g719"},
102 : {GF_CODECID_DTS_CA, 0xA9, GF_STREAM_AUDIO, "DTS Coherent Acoustics Audio", "dstca", NULL, "audio/dts"},
103 : {GF_CODECID_DTS_HD_HR, 0xAA, GF_STREAM_AUDIO, "DTS-HD High Resolution Audio", "dtsh", NULL, "audio/dts"},
104 : {GF_CODECID_DTS_HD_MASTER, 0xAB, GF_STREAM_AUDIO, "DTS-HD Master Audio", "dstm", NULL, "audio/dts"},
105 : {GF_CODECID_DTS_LBR, 0xAC, GF_STREAM_AUDIO, "DTS Express low bit rate Audio", "dtsl", NULL, "audio/dts"},
106 : {GF_CODECID_OPUS, 0xAD, GF_STREAM_AUDIO, "Opus Audio", "opus", NULL, "audio/opus"},
107 : {GF_CODECID_DVB_EIT, 0, GF_STREAM_PRIVATE_SCENE, "DVB Event Information", "eti", NULL, "application/x-dvb-eit"},
108 : {GF_CODECID_SVG, 0, GF_STREAM_PRIVATE_SCENE, "SVG over RTP", "svgr", NULL, "application/x-svg-rtp"},
109 : {GF_CODECID_SVG_GZ, 0, GF_STREAM_PRIVATE_SCENE, "SVG+gz over RTP", "svgzr", NULL, "application/x-svgz-rtp"},
110 : {GF_CODECID_DIMS, 0, GF_STREAM_PRIVATE_SCENE, "3GPP DIMS Scene", "dims", NULL, "application/3gpp-dims"},
111 : {GF_CODECID_WEBVTT, 0, GF_STREAM_TEXT, "WebVTT Text", "vtt", "wvtt", "text/webtvv"},
112 : {GF_CODECID_SIMPLE_TEXT, 0, GF_STREAM_TEXT, "Simple Text Stream", "txt", "stxt", "text/subtitle"},
113 : {GF_CODECID_META_TEXT, 0, GF_STREAM_METADATA, "Metadata Text Stream", "mtxt", "mett", "application/text"},
114 : {GF_CODECID_META_XML, 0, GF_STREAM_METADATA, "Metadata XML Stream", "mxml", "metx", "application/text+xml"},
115 : {GF_CODECID_SUBS_TEXT, 0, GF_STREAM_TEXT, "Subtitle text Stream", "subs", "sbtt", "text/text"},
116 : {GF_CODECID_SUBS_XML, 0, GF_STREAM_TEXT, "Subtitle XML Stream", "subx", "stpp", "text/text+xml"},
117 : {GF_CODECID_TX3G, 0, GF_STREAM_TEXT, "Subtitle/text 3GPP/Apple Stream", "tx3g", "tx3g", "quicktime/text"},
118 : {GF_CODECID_THEORA, 0xDF, GF_STREAM_VISUAL, "Theora Video", "theo|theora", NULL, "video/theora"},
119 : {GF_CODECID_VORBIS, 0xDD, GF_STREAM_AUDIO, "Vorbis Audio", "vorb|vorbis", NULL, "audio/vorbis"},
120 : {GF_CODECID_OPUS, 0xDE, GF_STREAM_AUDIO, "Opus Audio", "opus", NULL, "audio/opus"},
121 : {GF_CODECID_FLAC, 0, GF_STREAM_AUDIO, "Flac Audio", "flac", "fLaC", "audio/flac"},
122 : {GF_CODECID_SPEEX, 0, GF_STREAM_AUDIO, "Speex Audio", "spx|speex", NULL, "audio/speex"},
123 : {GF_CODECID_SUBPIC, 0xE0, GF_STREAM_TEXT, "VobSub Subtitle", "vobsub", NULL, "text/x-vobsub"},
124 : {GF_CODECID_SUBPIC, 0xE0, GF_STREAM_ND_SUBPIC, "VobSub Subtitle", "vobsub", NULL, "text/x-vobsub"},
125 : {GF_CODECID_ADPCM, 0, GF_STREAM_AUDIO, "AD-PCM", "adpcm", NULL, "audio/pcm"},
126 : {GF_CODECID_IBM_CVSD, 0, GF_STREAM_AUDIO, "IBM CSVD", "csvd", NULL, "audio/pcm"},
127 : {GF_CODECID_ALAW, 0, GF_STREAM_AUDIO, "ALAW", "alaw", NULL, "audio/pcm"},
128 : {GF_CODECID_MULAW, 0, GF_STREAM_AUDIO, "MULAW", "mulaw", NULL, "audio/pcm"},
129 : {GF_CODECID_OKI_ADPCM, 0, GF_STREAM_AUDIO, "OKI ADPCM", "okiadpcm", NULL, "audio/pcm"},
130 : {GF_CODECID_DVI_ADPCM, 0, GF_STREAM_AUDIO, "DVI ADPCM", "dviadpcm", NULL, "audio/pcm"},
131 : {GF_CODECID_DIGISTD, 0, GF_STREAM_AUDIO, "DIGISTD", "digistd", NULL, "audio/pcm"},
132 : {GF_CODECID_YAMAHA_ADPCM, 0, GF_STREAM_AUDIO, "YAMAHA ADPCM", "yamadpcm", NULL, "audio/pcm"},
133 : {GF_CODECID_DSP_TRUESPEECH, 0, GF_STREAM_AUDIO, "DSP TrueSpeech", "truespeech", NULL, "audio/pcm"},
134 : {GF_CODECID_GSM610, 0, GF_STREAM_AUDIO, "GSM 610", "g610", NULL, "audio/pcm"},
135 : {GF_CODECID_IBM_MULAW, 0, GF_STREAM_AUDIO, "IBM MULAW", "imulaw", NULL, "audio/pcm"},
136 : {GF_CODECID_IBM_ALAW, 0, GF_STREAM_AUDIO, "IBM ALAW", "ialaw", NULL, "audio/pcm"},
137 : {GF_CODECID_IBM_ADPCM, 0, GF_STREAM_AUDIO, "IBM ADPCL", "iadpcl", NULL, "audio/pcm"},
138 : {GF_CODECID_FLASH, 0, GF_STREAM_SCENE, "Adobe Flash", "swf", NULL, "audio/pcm"},
139 : {GF_CODECID_RAW, 0, GF_STREAM_UNKNOWN, "Raw media", "raw", NULL, "*/*"},
140 :
141 : {GF_CODECID_AV1, 0, GF_STREAM_VISUAL, "AOM AV1 Video", "av1|ivf|obu|av1b", NULL, "video/av1"},
142 : {GF_CODECID_VP8, 0, GF_STREAM_VISUAL, "VP8 Video", "vp8|ivf", NULL, "video/vp8"},
143 : {GF_CODECID_VP9, 0, GF_STREAM_VISUAL, "VP9 Video", "vp9|ivf", NULL, "video/vp9"},
144 : {GF_CODECID_VP10, 0, GF_STREAM_VISUAL, "VP10 Video", "vp10|ivf", NULL, "video/vp10"},
145 :
146 : {GF_CODECID_MPHA, 0, GF_STREAM_AUDIO, "MPEG-H Audio", "mhas", "mha1", "audio/x-mpegh"},
147 : {GF_CODECID_MHAS, 0, GF_STREAM_AUDIO, "MPEG-H AudioMux", "mhas", "mhm1", "audio/x-mhas"},
148 :
149 : {GF_CODECID_APCH, 0, GF_STREAM_VISUAL, "ProRes Video 422 HQ", "prores|apch", "apch", "video/prores"},
150 : {GF_CODECID_APCO, 0, GF_STREAM_VISUAL, "ProRes Video 422 Proxy", "prores|apco", "apco", "video/prores", GF_CODECID_APCH},
151 : {GF_CODECID_APCN, 0, GF_STREAM_VISUAL, "ProRes Video 422 STD", "prores|apcn", "apcn", "video/prores", GF_CODECID_APCH},
152 : {GF_CODECID_APCS, 0, GF_STREAM_VISUAL, "ProRes Video 422 LT", "prores|apcs", "apcs", "video/prores", GF_CODECID_APCH},
153 : {GF_CODECID_AP4X, 0, GF_STREAM_VISUAL, "ProRes Video 4444 XQ", "prores|ap4x", "ap4x", "video/prores", GF_CODECID_APCH},
154 : {GF_CODECID_AP4H, 0, GF_STREAM_VISUAL, "ProRes Video 4444", "prores|ap4h", "ap4h", "video/prores", GF_CODECID_APCH},
155 : {GF_CODECID_FFMPEG, 0, GF_STREAM_UNKNOWN, "FFMPEG unmapped codec", "ffmpeg", NULL, NULL},
156 :
157 : {GF_CODECID_TMCD, 0, GF_STREAM_METADATA, "QT TimeCode", "tmcd", NULL, NULL},
158 : {GF_CODECID_VVC, 0, GF_STREAM_VISUAL, "VVC Video", "vvc|266|h266", "vvc1", "video/vvc"},
159 : {GF_CODECID_USAC, GF_CODECID_AAC_MPEG4, GF_STREAM_AUDIO, "xHEAAC / USAC Audio", "usac|xheaac", "mp4a", "audio/x-xheaac"},
160 : {GF_CODECID_V210, 0, GF_STREAM_VISUAL, "v210 YUV 422 10 bits", "v210", "v210", "video/x-raw-v210"},
161 :
162 :
163 : };
164 :
165 :
166 : GF_EXPORT
167 94 : GF_CodecID gf_codecid_parse(const char *cname)
168 : {
169 94 : u32 ilen = (u32) strlen(cname);
170 : u32 i, count = sizeof(CodecRegistry) / sizeof(CodecIDReg);
171 5931 : for (i=0; i<count; i++) {
172 5931 : const char *n = CodecRegistry[i].sname;
173 13843 : while (n) {
174 7912 : char *sep = strchr(n, '|');
175 : u32 len;
176 7912 : if (sep)
177 2005 : len = sep - n;
178 : else
179 5907 : len = (u32) strlen(n);
180 :
181 : //allow case insensitive names
182 7912 : if ((len==ilen) && !strnicmp(n, cname, len))
183 94 : return CodecRegistry[i].codecid;
184 7818 : if (!sep) break;
185 1981 : n = sep+1;
186 : }
187 : }
188 : return GF_CODECID_NONE;
189 : }
190 :
191 :
192 : #include <gpac/internal/isomedia_dev.h>
193 :
194 : GF_EXPORT
195 398 : GF_CodecID gf_codec_id_from_isobmf(u32 isobmftype)
196 : {
197 398 : switch (isobmftype) {
198 : case GF_ISOM_SUBTYPE_DVHE:
199 : return GF_CODECID_HEVC;
200 6 : case GF_ISOM_SUBTYPE_3GP_AMR:
201 6 : return GF_CODECID_AMR;
202 4 : case GF_ISOM_SUBTYPE_3GP_AMR_WB:
203 4 : return GF_CODECID_AMR_WB;
204 6 : case GF_ISOM_SUBTYPE_3GP_H263:
205 : case GF_ISOM_SUBTYPE_H263:
206 6 : return GF_CODECID_H263;
207 0 : case GF_ISOM_SUBTYPE_XDVB:
208 0 : return GF_CODECID_MPEG2_MAIN;
209 0 : case GF_ISOM_MEDIA_FLASH:
210 0 : return GF_CODECID_FLASH;
211 4 : case GF_ISOM_SUBTYPE_AC3:
212 4 : return GF_CODECID_AC3;
213 2 : case GF_ISOM_SUBTYPE_EC3:
214 2 : return GF_CODECID_EAC3;
215 2 : case GF_ISOM_SUBTYPE_FLAC:
216 2 : return GF_CODECID_FLAC;
217 36 : case GF_ISOM_SUBTYPE_MP3:
218 36 : return GF_CODECID_MPEG_AUDIO;
219 11 : case GF_ISOM_SUBTYPE_JPEG:
220 11 : return GF_CODECID_JPEG;
221 7 : case GF_ISOM_SUBTYPE_PNG:
222 7 : return GF_CODECID_PNG;
223 0 : case GF_ISOM_SUBTYPE_JP2K:
224 0 : return GF_CODECID_J2K;
225 15 : case GF_ISOM_SUBTYPE_STXT:
226 15 : return GF_CODECID_SIMPLE_TEXT;
227 20 : case GF_ISOM_SUBTYPE_METT:
228 20 : return GF_CODECID_META_TEXT;
229 5 : case GF_ISOM_SUBTYPE_METX:
230 5 : return GF_CODECID_META_XML;
231 10 : case GF_ISOM_SUBTYPE_SBTT:
232 10 : return GF_CODECID_SUBS_TEXT;
233 19 : case GF_ISOM_SUBTYPE_STPP:
234 19 : return GF_CODECID_SUBS_XML;
235 3 : case GF_ISOM_SUBTYPE_WVTT:
236 3 : return GF_CODECID_WEBVTT;
237 0 : case GF_ISOM_SUBTYPE_3GP_DIMS:
238 0 : return GF_CODECID_DIMS;
239 0 : case GF_ISOM_SUBTYPE_HVT1:
240 0 : return GF_CODECID_HEVC_TILES;
241 57 : case GF_ISOM_SUBTYPE_TEXT:
242 : case GF_ISOM_SUBTYPE_TX3G:
243 57 : return GF_CODECID_TX3G;
244 0 : case GF_ISOM_SUBTYPE_VVC1:
245 : case GF_ISOM_SUBTYPE_VVI1:
246 0 : return GF_CODECID_VVC;
247 0 : case GF_QT_SUBTYPE_YUV422_10:
248 0 : return GF_CODECID_V210;
249 :
250 7 : case GF_QT_SUBTYPE_APCH:
251 7 : return GF_CODECID_APCH;
252 0 : case GF_QT_SUBTYPE_APCO:
253 0 : return GF_CODECID_APCO;
254 0 : case GF_QT_SUBTYPE_APCN:
255 0 : return GF_CODECID_APCN;
256 0 : case GF_QT_SUBTYPE_APCS:
257 0 : return GF_CODECID_APCS;
258 0 : case GF_QT_SUBTYPE_AP4X:
259 0 : return GF_CODECID_AP4X;
260 0 : case GF_QT_SUBTYPE_AP4H:
261 0 : return GF_CODECID_AP4H;
262 0 : case GF_QT_SUBTYPE_TWOS:
263 0 : return GF_CODECID_RAW;
264 0 : case GF_QT_SUBTYPE_SOWT:
265 0 : return GF_CODECID_RAW;
266 0 : case GF_QT_SUBTYPE_FL32:
267 0 : return GF_CODECID_RAW;
268 0 : case GF_QT_SUBTYPE_FL64:
269 0 : return GF_CODECID_RAW;
270 16 : case GF_QT_SUBTYPE_IN24:
271 16 : return GF_CODECID_RAW;
272 0 : case GF_QT_SUBTYPE_IN32:
273 0 : return GF_CODECID_RAW;
274 2 : case GF_ISOM_SUBTYPE_MLPA:
275 2 : return GF_CODECID_TRUEHD;
276 : default:
277 : break;
278 : }
279 166 : return 0;
280 : }
281 :
282 :
283 : static CodecIDReg *gf_codecid_reg_find(u32 codecid)
284 : {
285 : u32 i, count = sizeof(CodecRegistry) / sizeof(CodecIDReg);
286 787373 : for (i=0; i<count; i++) {
287 797668 : if (CodecRegistry[i].codecid==codecid) return &CodecRegistry[i];
288 : }
289 : return NULL;
290 : }
291 :
292 : static CodecIDReg *gf_codecid_reg_find_oti(u32 stream_type, u32 oti)
293 : {
294 : u32 i, count = sizeof(CodecRegistry) / sizeof(CodecIDReg);
295 14294 : for (i=0; i<count; i++) {
296 15092 : if (CodecRegistry[i].stream_type != stream_type) continue;
297 2653 : if (CodecRegistry[i].mpeg4_oti != oti) continue;
298 798 : return &CodecRegistry[i];
299 : }
300 : return NULL;
301 : }
302 :
303 : GF_EXPORT
304 5595 : const char *gf_codecid_name(GF_CodecID codecid)
305 : {
306 : CodecIDReg *r = gf_codecid_reg_find(codecid);
307 5595 : if (!r) return "Codec Not Supported";
308 4658 : return r->name;
309 : }
310 :
311 : GF_EXPORT
312 1833 : const char *gf_codecid_file_ext(GF_CodecID codecid)
313 : {
314 : CodecIDReg *r = gf_codecid_reg_find(codecid);
315 1833 : u32 global_ext_count = gf_opts_get_key_count("file_extensions");
316 1833 : if (r && r->mime_type && global_ext_count) {
317 0 : const char *name = gf_opts_get_key("file_extensions", r->mime_type);
318 0 : if (name) return name;
319 : }
320 1833 : if (r && r->sname) return r->sname;
321 0 : if (r && r->rfc_4cc) return r->rfc_4cc;
322 : return "raw";
323 : }
324 :
325 : GF_EXPORT
326 1998 : const char *gf_codecid_mime(GF_CodecID codecid)
327 : {
328 : CodecIDReg *r = gf_codecid_reg_find(codecid);
329 1998 : if (r && r->mime_type) return r->mime_type;
330 : return "application/octet-string";
331 : }
332 :
333 : GF_EXPORT
334 428 : GF_CodecID gf_codecid_enum(u32 idx, const char **short_name, const char **long_name)
335 : {
336 : u32 count = sizeof(CodecRegistry) / sizeof(CodecIDReg);
337 428 : if (idx >= count) return GF_CODECID_NONE;
338 424 : if (short_name) *short_name = CodecRegistry[idx].sname;
339 424 : if (long_name) *long_name = CodecRegistry[idx].name;
340 424 : return CodecRegistry[idx].codecid;
341 : }
342 :
343 :
344 : GF_EXPORT
345 707 : u32 gf_codecid_type(GF_CodecID codecid)
346 : {
347 : CodecIDReg *r = gf_codecid_reg_find(codecid);
348 707 : if (!r) return GF_STREAM_UNKNOWN;
349 707 : return r->stream_type;
350 : }
351 :
352 : GF_EXPORT
353 106 : GF_CodecID gf_codecid_alt(GF_CodecID codecid)
354 : {
355 : CodecIDReg *r = gf_codecid_reg_find(codecid);
356 106 : if (!r) return GF_CODECID_NONE;
357 106 : return r->alt_codecid;
358 : }
359 :
360 : GF_EXPORT
361 798 : GF_CodecID gf_codecid_from_oti(u32 stream_type, u32 oti)
362 : {
363 : CodecIDReg *r;
364 798 : if (!oti) {
365 0 : if ((stream_type==GF_STREAM_OD) || (stream_type==GF_STREAM_SCENE))
366 : oti = 1;
367 : }
368 : r = gf_codecid_reg_find_oti(stream_type, oti);
369 798 : if (!r) return GF_CODECID_NONE;
370 798 : return r->codecid;
371 : }
372 :
373 : GF_EXPORT
374 994 : u8 gf_codecid_oti(GF_CodecID codecid)
375 : {
376 : CodecIDReg *r = gf_codecid_reg_find(codecid);
377 994 : if (!r) return 0;
378 993 : return r->mpeg4_oti;
379 : }
380 :
381 : GF_EXPORT
382 114 : u32 gf_codecid_4cc_type(GF_CodecID codecid)
383 : {
384 : u32 i, count = sizeof(CodecRegistry) / sizeof(CodecIDReg);
385 6006 : for (i=0; i<count; i++) {
386 6006 : if (CodecRegistry[i].codecid==codecid) {
387 114 : const char *n = CodecRegistry[i].rfc_4cc;
388 114 : if (!n) return 0;
389 75 : return GF_4CC(n[0], n[1], n[2], n[3]);
390 : }
391 : }
392 : return 0;
393 : }
394 :
395 : typedef struct
396 : {
397 : u32 st;
398 : const char *name;
399 : const char *desc;
400 : const char *sname;
401 : const char *alt_name;
402 : } GF_StreamTypeDesc;
403 :
404 : static const GF_StreamTypeDesc GF_StreamTypes[] =
405 : {
406 : {GF_STREAM_VISUAL, "Visual", "Video or Image stream", "video", "Video"},
407 : {GF_STREAM_AUDIO, "Audio", "Audio stream", "audio"},
408 : {GF_STREAM_SCENE, "SceneDescription", "Scene stream", "scene"},
409 : {GF_STREAM_TEXT, "Text", "Text or subtitle stream", "text"},
410 : {GF_STREAM_METADATA, "Metadata", "Metadata stream", "meta"},
411 : {GF_STREAM_FILE, "File", "Raw file stream", "file"},
412 : {GF_STREAM_ENCRYPTED, "Encrypted", "Encrypted media stream", "crypt"},
413 : {GF_STREAM_OD, "ObjectDescriptor", "MPEG-4 ObjectDescriptor stream", "od"},
414 : {GF_STREAM_OCR, "ClockReference", "MPEG-4 Clock Reference stream", "ocr"},
415 : {GF_STREAM_MPEG7, "MPEG7", "MPEG-7 description stream", "mpeg7"},
416 : {GF_STREAM_IPMP, "IPMP", "MPEG-4 IPMP/DRM stream", "ipmp"},
417 : {GF_STREAM_OCI, "OCI", "MPEG-4 ObjectContentInformation stream", "oci"},
418 : {GF_STREAM_MPEGJ, "MPEGJ", "MPEG-4 JAVA stream", "mpegj"},
419 : {GF_STREAM_INTERACT, "Interaction", "MPEG-4 Interaction Sensor stream", "interact"},
420 : {GF_STREAM_FONT, "Font", "MPEG-4 Font stream", "font"}
421 : };
422 :
423 : GF_EXPORT
424 3805 : const char *gf_stream_type_name(u32 streamType)
425 : {
426 : u32 i, nb_st = sizeof(GF_StreamTypes) / sizeof(GF_StreamTypeDesc);
427 7847 : for (i=0; i<nb_st; i++) {
428 7819 : if (GF_StreamTypes[i].st == streamType)
429 3777 : return GF_StreamTypes[i].name;
430 : }
431 : return "Unknown";
432 : }
433 :
434 : GF_EXPORT
435 0 : const char *gf_stream_type_short_name(u32 streamType)
436 : {
437 : u32 i, nb_st = sizeof(GF_StreamTypes) / sizeof(GF_StreamTypeDesc);
438 0 : for (i=0; i<nb_st; i++) {
439 0 : if (GF_StreamTypes[i].st == streamType)
440 0 : return GF_StreamTypes[i].sname;
441 : }
442 : return "unkn";
443 : }
444 :
445 : GF_EXPORT
446 77 : u32 gf_stream_type_by_name(const char *val)
447 : {
448 : u32 i, nb_st = sizeof(GF_StreamTypes) / sizeof(GF_StreamTypeDesc);
449 139 : for (i=0; i<nb_st; i++) {
450 139 : if (!stricmp(GF_StreamTypes[i].name, val))
451 43 : return GF_StreamTypes[i].st;
452 96 : if (GF_StreamTypes[i].alt_name && !stricmp(GF_StreamTypes[i].alt_name, val))
453 34 : return GF_StreamTypes[i].st;
454 : }
455 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unknow stream type %s\n", val));
456 : return GF_STREAM_UNKNOWN;
457 : }
458 :
459 : #if 0
460 : static char szAllStreamTypes[500] = {0};
461 :
462 : /*! Gets the list of names of all stream types defined
463 : \return names of all stream types defined
464 : */
465 : const char *gf_stream_type_all_names()
466 : {
467 : if (!szAllStreamTypes[0]) {
468 : u32 i, nb_st = sizeof(GF_StreamTypes) / sizeof(GF_StreamTypeDesc);
469 : u32 tot_len=0;
470 : strcpy(szAllStreamTypes, "");
471 : for (i=0; i<nb_st; i++) {
472 : u32 len = (u32) strlen(GF_StreamTypes[i].name);
473 : if (len+tot_len+2>=500) {
474 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Not enough memory to hold all stream types!!\n"));
475 : break;
476 : }
477 : if (i) {
478 : strcat((char *)szAllStreamTypes, ",");
479 : tot_len += 1;
480 : }
481 : strcat((char *)szAllStreamTypes, GF_StreamTypes[i].name);
482 : tot_len += len;
483 : }
484 : }
485 : return szAllStreamTypes;
486 : }
487 : #endif
488 :
489 :
490 : GF_EXPORT
491 32 : u32 gf_stream_types_enum(u32 *idx, const char **name, const char **desc)
492 : {
493 : u32 stype;
494 : u32 nb_sfmt = sizeof(GF_StreamTypes) / sizeof(GF_StreamTypeDesc);
495 32 : if (*idx >= nb_sfmt) return GF_STREAM_UNKNOWN;
496 30 : if (!GF_StreamTypes[*idx].st) return GF_STREAM_UNKNOWN;
497 :
498 30 : *name = GF_StreamTypes[*idx].name;
499 30 : *desc = GF_StreamTypes[*idx].desc;
500 30 : stype = GF_StreamTypes[*idx].st;
501 30 : (*idx)++;
502 30 : return stype;
503 : }
504 :
505 : GF_EXPORT
506 1 : const char *gf_stream_type_afx_name(u8 afx_code)
507 : {
508 1 : switch (afx_code) {
509 : case GPAC_AFX_3DMC:
510 : return "AFX 3D Mesh Compression";
511 0 : case GPAC_AFX_WAVELET_SUBDIVISION:
512 0 : return "AFX Wavelet Subdivision Surface";
513 0 : case GPAC_AFX_MESHGRID:
514 0 : return "AFX Mesh Grid";
515 0 : case GPAC_AFX_COORDINATE_INTERPOLATOR:
516 0 : return "AFX Coordinate Interpolator";
517 0 : case GPAC_AFX_ORIENTATION_INTERPOLATOR:
518 0 : return "AFX Orientation Interpolator";
519 0 : case GPAC_AFX_POSITION_INTERPOLATOR:
520 0 : return "AFX Position Interpolator";
521 0 : case GPAC_AFX_OCTREE_IMAGE:
522 0 : return "AFX Octree Image";
523 0 : case GPAC_AFX_BBA:
524 0 : return "AFX BBA";
525 0 : case GPAC_AFX_POINT_TEXTURE:
526 0 : return "AFX Point Texture";
527 0 : case GPAC_AFX_3DMC_EXT:
528 0 : return "AFX 3D Mesh Compression Extension";
529 0 : case GPAC_AFX_FOOTPRINT:
530 0 : return "AFX FootPrint Representation";
531 0 : case GPAC_AFX_ANIMATED_MESH:
532 0 : return "AFX Animated Mesh Compression";
533 0 : case GPAC_AFX_SCALABLE_COMPLEXITY:
534 0 : return "AFX Scalable Complexity Representation";
535 : default:
536 : break;
537 : }
538 0 : return "AFX Unknown";
539 : }
540 :
541 :
542 : typedef struct
543 : {
544 : GF_AudioFormat sfmt;
545 : const char *name; //as used in gpac
546 : const char *desc;
547 : const char *sname; //short name, as used in gpac
548 : } GF_AudioFmt;
549 :
550 : static const GF_AudioFmt GF_AudioFormats[] =
551 : {
552 : {GF_AUDIO_FMT_U8, "u8", "8 bit PCM", "pc8"},
553 : {GF_AUDIO_FMT_S16, "s16", "16 bit PCM Little Endian", "pcm"},
554 : {GF_AUDIO_FMT_S24, "s24", "24 bit PCM"},
555 : {GF_AUDIO_FMT_S32, "s32", "32 bit PCM Little Endian"},
556 : {GF_AUDIO_FMT_FLT, "flt", "32-bit floating point PCM"},
557 : {GF_AUDIO_FMT_DBL, "dbl", "64-bit floating point PCM"},
558 : {GF_AUDIO_FMT_U8P, "u8p", "8 bit PCM planar", "pc8p"},
559 : {GF_AUDIO_FMT_S16P, "s16p", "16 bit PCM Little Endian planar", "pcmp"},
560 : {GF_AUDIO_FMT_S24P, "s24p", "24 bit PCM planar"},
561 : {GF_AUDIO_FMT_S32P, "s32p", "32 bit PCM Little Endian planar"},
562 : {GF_AUDIO_FMT_FLTP, "fltp", "32-bit floating point PCM planar"},
563 : {GF_AUDIO_FMT_DBLP, "dblp", "64-bit floating point PCM planar"},
564 : {0}
565 : };
566 :
567 :
568 : GF_EXPORT
569 1778 : GF_AudioFormat gf_audio_fmt_parse(const char *af_name)
570 : {
571 : u32 i=0;
572 1778 : if (!af_name || !strcmp(af_name, "none")) return 0;
573 1732 : while (!i || GF_AudioFormats[i].sfmt) {
574 1732 : if (!strcmp(GF_AudioFormats[i].name, af_name))
575 645 : return GF_AudioFormats[i].sfmt;
576 1087 : if (GF_AudioFormats[i].sname && !strcmp(GF_AudioFormats[i].sname, af_name))
577 105 : return GF_AudioFormats[i].sfmt;
578 982 : i++;
579 : }
580 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported audio format %s\n", af_name));
581 : return 0;
582 : }
583 :
584 : GF_EXPORT
585 33 : const char *gf_audio_fmt_name(GF_AudioFormat sfmt)
586 : {
587 : u32 i=0;
588 204 : while (!i || GF_AudioFormats[i].sfmt) {
589 168 : if (GF_AudioFormats[i].sfmt==sfmt) return GF_AudioFormats[i].name;
590 138 : i++;
591 : }
592 3 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported audio format %d\n", sfmt ));
593 : return "unknown";
594 : }
595 : GF_EXPORT
596 239 : const char *gf_audio_fmt_sname(GF_AudioFormat sfmt)
597 : {
598 : u32 i=0;
599 1124 : while (!i || GF_AudioFormats[i].sfmt) {
600 885 : if (GF_AudioFormats[i].sfmt==sfmt) {
601 239 : if (GF_AudioFormats[i].sname)
602 : return GF_AudioFormats[i].sname;
603 56 : return GF_AudioFormats[i].name;
604 : }
605 646 : i++;
606 : }
607 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported audio format %d\n", sfmt ));
608 : return "unknown";
609 : }
610 :
611 : static char szAllAudioFormats[500] = {0};
612 :
613 : GF_EXPORT
614 8495 : const char *gf_audio_fmt_all_names()
615 : {
616 8495 : if (!szAllAudioFormats[0]) {
617 : u32 i=0;
618 : u32 tot_len=4;
619 : strcpy(szAllAudioFormats, "none");
620 35633 : while (!i || GF_AudioFormats[i].sfmt) {
621 32892 : u32 len = (u32) strlen(GF_AudioFormats[i].name);
622 32892 : if (len+tot_len+2>=500) {
623 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Not enough memory to hold all audio formats!!\n"));
624 : break;
625 : }
626 : strcat((char *)szAllAudioFormats, ",");
627 32892 : tot_len += 1;
628 : strcat((char *)szAllAudioFormats, GF_AudioFormats[i].name);
629 32892 : tot_len += len;
630 32892 : i++;
631 : }
632 : }
633 8495 : return szAllAudioFormats;
634 : }
635 :
636 : static char szAllShortAudioFormats[500] = {0};
637 :
638 : GF_EXPORT
639 5618 : const char *gf_audio_fmt_all_shortnames()
640 : {
641 5618 : if (!szAllShortAudioFormats[0]) {
642 : u32 i=0;
643 : u32 tot_len=0;
644 : memset(szAllShortAudioFormats, 0, sizeof(char)*500);
645 35633 : while (!i || GF_AudioFormats[i].sfmt) {
646 32892 : const char * n = GF_AudioFormats[i].sname ? GF_AudioFormats[i].sname : GF_AudioFormats[i].name;
647 32892 : u32 len = (u32) strlen(n);
648 32892 : if (len+tot_len+1>=500) {
649 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Not enough memory to hold all audio formats!!\n"));
650 : break;
651 : }
652 32892 : if (i) {
653 : strcat((char *)szAllShortAudioFormats, "|");
654 30151 : tot_len += 1;
655 : strcat((char *)szAllShortAudioFormats, n);
656 : } else {
657 : strcpy((char *)szAllShortAudioFormats, n);
658 : }
659 32892 : tot_len += len;
660 32892 : i++;
661 : }
662 2741 : szAllShortAudioFormats[tot_len] = 0;
663 : }
664 5618 : return szAllShortAudioFormats;
665 : }
666 :
667 : GF_EXPORT
668 26 : GF_AudioFormat gf_audio_fmt_enum(u32 *idx, const char **name, const char **fileext, const char **desc)
669 : {
670 : GF_AudioFormat afmt;
671 : u32 nb_afmt = sizeof(GF_AudioFormats) / sizeof(GF_AudioFmt);
672 26 : if (*idx >= nb_afmt) return 0;
673 26 : if (!GF_AudioFormats[*idx].sfmt) return 0;
674 :
675 24 : *name = GF_AudioFormats[*idx].name;
676 24 : *desc = GF_AudioFormats[*idx].desc;
677 :
678 24 : *fileext = GF_AudioFormats[*idx].sname;
679 24 : if (! *fileext) *fileext = *name;
680 24 : afmt = GF_AudioFormats[*idx].sfmt;
681 24 : (*idx)++;
682 24 : return afmt;
683 : }
684 :
685 : GF_EXPORT
686 6590 : u32 gf_audio_fmt_bit_depth(GF_AudioFormat audio_fmt)
687 : {
688 : switch (audio_fmt) {
689 : case GF_AUDIO_FMT_U8P:
690 : case GF_AUDIO_FMT_U8: return 8;
691 :
692 : case GF_AUDIO_FMT_S16P:
693 : case GF_AUDIO_FMT_S16: return 16;
694 :
695 : case GF_AUDIO_FMT_S32P:
696 : case GF_AUDIO_FMT_S32: return 32;
697 :
698 : case GF_AUDIO_FMT_FLTP:
699 : case GF_AUDIO_FMT_FLT: return 32;
700 :
701 : case GF_AUDIO_FMT_DBLP:
702 : case GF_AUDIO_FMT_DBL: return 64;
703 :
704 : case GF_AUDIO_FMT_S24P:
705 : case GF_AUDIO_FMT_S24: return 24;
706 :
707 : default:
708 : break;
709 : }
710 : return 0;
711 : }
712 :
713 : GF_EXPORT
714 189 : Bool gf_audio_fmt_is_planar(GF_AudioFormat audio_fmt)
715 : {
716 189 : switch (audio_fmt) {
717 : case GF_AUDIO_FMT_U8P:
718 : case GF_AUDIO_FMT_S16P:
719 : case GF_AUDIO_FMT_S32P:
720 : case GF_AUDIO_FMT_FLTP:
721 : case GF_AUDIO_FMT_DBLP:
722 : case GF_AUDIO_FMT_S24P:
723 : return GF_TRUE;
724 : default:
725 : break;
726 : }
727 103 : return GF_FALSE;
728 : }
729 :
730 : GF_EXPORT
731 69 : GF_AudioFormat gf_audio_fmt_from_isobmf(u32 msubtype)
732 : {
733 69 : switch (msubtype) {
734 : case GF_QT_SUBTYPE_TWOS:
735 : return GF_AUDIO_FMT_S16;
736 : case GF_QT_SUBTYPE_SOWT:
737 : return GF_AUDIO_FMT_S16;
738 0 : case GF_QT_SUBTYPE_FL32:
739 0 : return GF_AUDIO_FMT_FLT;
740 0 : case GF_QT_SUBTYPE_FL64:
741 0 : return GF_AUDIO_FMT_DBL;
742 64 : case GF_QT_SUBTYPE_IN24:
743 64 : return GF_AUDIO_FMT_S24;
744 0 : case GF_QT_SUBTYPE_IN32:
745 0 : return GF_AUDIO_FMT_S32;
746 : }
747 5 : return 0;
748 : }
749 :
750 : GF_EXPORT
751 6 : u32 gf_audio_fmt_get_cicp_layout(u32 nb_chan, u32 nb_surr, u32 nb_lfe)
752 : {
753 6 : if ( !nb_chan && !nb_surr && !nb_lfe) return 0;
754 6 : else if ((nb_chan==1) && !nb_surr && !nb_lfe) return 1;
755 6 : else if ((nb_chan==2) && !nb_surr && !nb_lfe) return 2;
756 1 : else if ((nb_chan==3) && !nb_surr && !nb_lfe) return 3;
757 1 : else if ((nb_chan==3) && (nb_surr==1) && !nb_lfe) return 4;
758 1 : else if ((nb_chan==3) && (nb_surr==2) && !nb_lfe) return 5;
759 1 : else if ((nb_chan==3) && (nb_surr==2) && (nb_lfe==1)) return 6;
760 1 : else if ((nb_chan==5) && (nb_surr==0) && (nb_lfe==1)) return 6;
761 :
762 1 : else if ((nb_chan==5) && (nb_surr==2) && (nb_lfe==1)) return 7;
763 1 : else if ((nb_chan==2) && (nb_surr==1) && !nb_lfe) return 9;
764 1 : else if ((nb_chan==2) && (nb_surr==2) && !nb_lfe) return 10;
765 1 : else if ((nb_chan==3) && (nb_surr==3) && (nb_lfe==1)) return 11;
766 1 : else if ((nb_chan==3) && (nb_surr==4) && (nb_lfe==1)) return 12;
767 1 : else if ((nb_chan==11) && (nb_surr==11) && (nb_lfe==2)) return 13;
768 : //we miss left / right front center vs left / right front vertical to signal this one
769 : // else if ((nb_chan==5) && (nb_surr==2) && (nb_lfe==1)) return 14;
770 1 : else if ((nb_chan==5) && (nb_surr==5) && (nb_lfe==2)) return 15;
771 1 : else if ((nb_chan==5) && (nb_surr==4) && (nb_lfe==1)) return 16;
772 1 : else if ((nb_surr==5) && (nb_lfe==1) && (nb_chan==6)) return 17;
773 1 : else if ((nb_surr==7) && (nb_lfe==1) && (nb_chan==6)) return 18;
774 1 : else if ((nb_chan==5) && (nb_surr==6) && (nb_lfe==1)) return 19;
775 1 : else if ((nb_chan==7) && (nb_surr==6) && (nb_lfe==1)) return 20;
776 :
777 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unkown CICP mapping for channel config %d/%d.%d\n", nb_chan, nb_surr, nb_lfe));
778 : return 0;
779 : }
780 :
781 : typedef struct
782 : {
783 : u32 cicp;
784 : const char *name;
785 : u64 channel_mask;
786 : } GF_CICPAudioLayout;
787 :
788 : static const GF_CICPAudioLayout GF_CICPLayouts[] =
789 : {
790 : {1, "mono"/*"1/0.0"*/, GF_AUDIO_CH_FRONT_CENTER },
791 : {2, "stereo"/*"2/0.0"*/, GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT },
792 : {3, "3/0.0", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER },
793 : {4, "3/1.0", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_CENTER },
794 : {5, "3/2.0", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT },
795 : {6, "3/2.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE },
796 : {7, "5/2.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE },
797 : {8, "1+1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT },
798 : {9, "2/1.0", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_REAR_CENTER },
799 : {10, "2/2.0", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT },
800 : {11, "3/3.1", GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT | GF_AUDIO_CH_REAR_CENTER | GF_AUDIO_CH_LFE },
801 : {12, "3/4.1", GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE },
802 : {13, "11/11.2", GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER_LEFT | GF_AUDIO_CH_FRONT_CENTER_RIGHT | GF_AUDIO_CH_SIDE_SURROUND_LEFT | GF_AUDIO_CH_SIDE_SURROUND_RIGHT | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_REAR_CENTER | GF_AUDIO_CH_LFE | GF_AUDIO_CH_LFE2 | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_FRONT_TOP_CENTER | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT | GF_AUDIO_CH_REAR_CENTER_TOP | GF_AUDIO_CH_SIDE_SURROUND_TOP_LEFT | GF_AUDIO_CH_SIDE_SURROUND_TOP_RIGHT | GF_AUDIO_CH_CENTER_SURROUND_TOP | GF_AUDIO_CH_FRONT_BOTTOM_CENTER | GF_AUDIO_CH_FRONT_BOTTOM_LEFT | GF_AUDIO_CH_FRONT_BOTTOM_RIGHT },
803 : {14, "5/2.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT },
804 : {15, "5/5.2", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_SIDE_SURROUND_LEFT | GF_AUDIO_CH_SIDE_SURROUND_RIGHT | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_CENTER_SURROUND_TOP | GF_AUDIO_CH_LFE | GF_AUDIO_CH_LFE2 },
805 : {16, "5/4.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT },
806 : {17, "6/5.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_FRONT_TOP_CENTER | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT | GF_AUDIO_CH_CENTER_SURROUND_TOP },
807 : {18, "6/7.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_SURROUND_LEFT | GF_AUDIO_CH_SURROUND_RIGHT | GF_AUDIO_CH_BACK_SURROUND_LEFT | GF_AUDIO_CH_BACK_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_FRONT_TOP_CENTER | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT | GF_AUDIO_CH_CENTER_SURROUND_TOP },
808 : {19, "5/6.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_SIDE_SURROUND_LEFT | GF_AUDIO_CH_SIDE_SURROUND_RIGHT | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT },
809 : {20, "7/6.1", GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT | GF_AUDIO_CH_FRONT_CENTER | GF_AUDIO_CH_SCREEN_EDGE_LEFT | GF_AUDIO_CH_SCREEN_EDGE_RIGHT | GF_AUDIO_CH_SIDE_SURROUND_LEFT | GF_AUDIO_CH_SIDE_SURROUND_RIGHT | GF_AUDIO_CH_REAR_SURROUND_LEFT | GF_AUDIO_CH_REAR_SURROUND_RIGHT | GF_AUDIO_CH_LFE | GF_AUDIO_CH_FRONT_TOP_LEFT | GF_AUDIO_CH_FRONT_TOP_RIGHT | GF_AUDIO_CH_SURROUND_TOP_LEFT | GF_AUDIO_CH_SURROUND_TOP_RIGHT }
810 : };
811 :
812 : GF_EXPORT
813 9 : u64 gf_audio_fmt_get_layout_from_cicp(u32 cicp_layout)
814 : {
815 : u32 i, nb_cicp = sizeof(GF_CICPLayouts) / sizeof(GF_CICPAudioLayout);
816 14 : for (i = 0; i < nb_cicp; i++) {
817 14 : if (GF_CICPLayouts[i].cicp == cicp_layout) return GF_CICPLayouts[i].channel_mask;
818 : }
819 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unsupported cicp audio layout value %d\n", cicp_layout));
820 : return 0;
821 : }
822 :
823 : GF_EXPORT
824 1 : const char *gf_audio_fmt_get_layout_name_from_cicp(u32 cicp_layout)
825 : {
826 : u32 i, nb_cicp = sizeof(GF_CICPLayouts) / sizeof(GF_CICPAudioLayout);
827 3 : for (i = 0; i < nb_cicp; i++) {
828 3 : if (GF_CICPLayouts[i].cicp == cicp_layout) return GF_CICPLayouts[i].name;
829 : }
830 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unsupported cicp audio layout value %d\n", cicp_layout));
831 : return "unknwon";
832 : }
833 :
834 : GF_EXPORT
835 1 : const char *gf_audio_fmt_get_layout_name(u64 ch_layout)
836 : {
837 : u32 i, nb_cicp = sizeof(GF_CICPLayouts) / sizeof(GF_CICPAudioLayout);
838 1 : for (i = 0; i < nb_cicp; i++) {
839 1 : if (GF_CICPLayouts[i].channel_mask == ch_layout) return GF_CICPLayouts[i].name;
840 : }
841 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unsupported audio layout value "LLU"\n", ch_layout));
842 : return "unknwon";
843 : }
844 :
845 : GF_EXPORT
846 1 : u64 gf_audio_fmt_get_layout_from_name(const char *name)
847 : {
848 : u32 i, nb_cicp = sizeof(GF_CICPLayouts) / sizeof(GF_CICPAudioLayout);
849 1 : if (!name) return 0;
850 5 : for (i = 0; i < nb_cicp; i++) {
851 6 : if (!strcmp(GF_CICPLayouts[i].name, name))
852 1 : return GF_CICPLayouts[i].channel_mask;
853 : }
854 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unsupported audio layout name %s\n", name));
855 : return 0;
856 : }
857 :
858 : GF_EXPORT
859 1 : u32 gf_audio_fmt_get_cicp_from_layout(u64 chan_layout)
860 : {
861 : u32 i, nb_cicp = sizeof(GF_CICPLayouts) / sizeof(GF_CICPAudioLayout);
862 2 : for (i = 0; i < nb_cicp; i++) {
863 2 : if (GF_CICPLayouts[i].channel_mask == chan_layout) return GF_CICPLayouts[i].cicp;
864 : }
865 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Unsupported cicp audio layout for channel layout "LLU"\n", chan_layout));
866 : return 255;
867 : }
868 :
869 : GF_EXPORT
870 5 : u32 gf_audio_fmt_get_num_channels_from_layout(u64 chan_layout)
871 : {
872 : u32 i, nb_chan = 0;
873 325 : for (i=0; i<64; i++) {
874 320 : nb_chan += (chan_layout&1) ? 1 : 0;
875 320 : chan_layout>>=1;
876 : }
877 5 : return nb_chan;
878 : }
879 :
880 : GF_EXPORT
881 1 : u16 gf_audio_fmt_get_dolby_chanmap(u32 cicp)
882 : {
883 : u16 res = 0;
884 1 : u64 layout = gf_audio_fmt_get_layout_from_cicp(cicp);
885 :
886 1 : if (layout & GF_AUDIO_CH_FRONT_LEFT) res |= (1<<15); // 0
887 1 : if (layout & GF_AUDIO_CH_FRONT_CENTER) res |= (1<<14); //1
888 1 : if (layout & GF_AUDIO_CH_FRONT_RIGHT) res |= (1<<13); //2
889 1 : if (layout & GF_AUDIO_CH_REAR_SURROUND_LEFT) res |= (1<<12); //3
890 1 : if (layout & GF_AUDIO_CH_REAR_SURROUND_RIGHT) res |= (1<<11); //4
891 : //Lc/Rc
892 1 : if (layout & GF_AUDIO_CH_FRONT_CENTER_LEFT) res |= (1<<11); //5
893 : //Lrs/Rrs
894 1 : if (layout & GF_AUDIO_CH_SURROUND_LEFT) res |= (1<<9); //6
895 : //Cs
896 1 : if (layout & GF_AUDIO_CH_REAR_CENTER) res |= (1<<8); //7
897 : //Ts
898 1 : if (layout & GF_AUDIO_CH_REAR_CENTER_TOP) res |= (1<<7); //8
899 : //Lsd/Rsd
900 1 : if (layout & GF_AUDIO_CH_SIDE_SURROUND_LEFT) res |= (1<<6); //9
901 : //Lw/Rw
902 1 : if (layout & GF_AUDIO_CH_FRONT_CENTER_LEFT) res |= (1<<5); //10
903 : //Vhl/Vhr
904 1 : if (layout & GF_AUDIO_CH_FRONT_TOP_LEFT) res |= (1<<4); //11
905 : //Vhc
906 1 : if (layout & GF_AUDIO_CH_FRONT_TOP_CENTER) res |= (1<<3); //12
907 : //Lts/Rts
908 1 : if (layout & GF_AUDIO_CH_SURROUND_TOP_LEFT) res |= (1<<2); //13
909 : //LFE2
910 1 : if (layout & GF_AUDIO_CH_LFE2) res |= (1<<1); //14
911 : //LFE
912 1 : if (layout & GF_AUDIO_CH_LFE) res |= (1); //15
913 1 : return res;
914 :
915 : }
916 :
917 :
918 : typedef struct
919 : {
920 : GF_PixelFormat pixfmt;
921 : const char *name; //as used in gpac
922 : const char *desc; //as used in gpac
923 : const char *sname; //short name, as used in gpac
924 : } GF_PixFmt;
925 :
926 : //DO NOT CHANGE ORDER, YUV formats first !
927 : static const GF_PixFmt GF_PixelFormats[] =
928 : {
929 : {GF_PIXEL_YUV, "yuv420", "Planar YUV 420 8 bit", "yuv"},
930 : {GF_PIXEL_YVU, "yvu420", "Planar YVU 420 8 bit", "yvu"},
931 : {GF_PIXEL_YUV_10, "yuv420_10", "Planar YUV 420 10 bit", "yuvl"},
932 : {GF_PIXEL_YUV422, "yuv422", "Planar YUV 422 8 bit", "yuv2"},
933 : {GF_PIXEL_YUV422_10, "yuv422_10", "Planar YUV 422 10 bit", "yp2l"},
934 : {GF_PIXEL_YUV444, "yuv444", "Planar YUV 444 8 bit", "yuv4"},
935 : {GF_PIXEL_YUV444_10, "yuv444_10", "Planar YUV 444 10 bit", "yp4l"},
936 : {GF_PIXEL_UYVY, "uyvy", "Packed UYVY 422 8 bit"},
937 : {GF_PIXEL_VYUY, "vyuy", "Packed VYUV 422 8 bit"},
938 : {GF_PIXEL_YUYV, "yuyv", "Packed YUYV 422 8 bit"},
939 : {GF_PIXEL_YVYU, "yvyu", "Packed YVYU 422 8 bit"},
940 : {GF_PIXEL_UYVY_10, "uyvl", "Packed UYVY 422 10->16 bit"},
941 : {GF_PIXEL_VYUY_10, "vyul", "Packed VYUV 422 10->16 bit"},
942 : {GF_PIXEL_YUYV_10, "yuyl", "Packed YUYV 422 10->16 bit"},
943 : {GF_PIXEL_YVYU_10, "yvyl", "Packed YVYU 422 10->16 bit"},
944 : {GF_PIXEL_NV12, "nv12", "Semi-planar YUV 420 8 bit, Y plane and UV packed plane"},
945 : {GF_PIXEL_NV21, "nv21", "Semi-planar YUV 420 8 bit, Y plane and VU packed plane"},
946 : {GF_PIXEL_NV12_10, "nv1l", "Semi-planar YUV 420 10 bit, Y plane and UV plane"},
947 : {GF_PIXEL_NV21_10, "nv2l", "Semi-planar YUV 420 8 bit, Y plane and VU plane"},
948 : {GF_PIXEL_YUVA, "yuva", "Planar YUV+alpha 420 8 bit"},
949 : {GF_PIXEL_YUVD, "yuvd", "Planar YUV+depth 420 8 bit"},
950 : {GF_PIXEL_YUVA444, "yuv444a", "Planar YUV+alpha 444 8 bit", "yp4a"},
951 : {GF_PIXEL_YUV444_PACK, "yuv444p", "Packed YUV 444 8 bit", "yv4p"},
952 : {GF_PIXEL_YUVA444_PACK, "yuv444ap", "Packed YUV+alpha 444 8 bit", "y4ap"},
953 : {GF_PIXEL_YUV444_10_PACK, "yuv444p_10", "Packed YUV 444 10 bit", "y4lp"},
954 :
955 : //first non-yuv format
956 : {GF_PIXEL_GREYSCALE, "grey", "Greyscale 8 bit"},
957 : {GF_PIXEL_ALPHAGREY, "algr", "Alpha+Grey 8 bit"},
958 : {GF_PIXEL_GREYALPHA, "gral", "Grey+Alpha 8 bit"},
959 : {GF_PIXEL_RGB_444, "rgb4", "RGB 444, 12 bits (16 stored) / pixel"},
960 : {GF_PIXEL_RGB_555, "rgb5", "RGB 555, 15 bits (16 stored) / pixel"},
961 : {GF_PIXEL_RGB_565, "rgb6", "RGB 555, 16 bits / pixel"},
962 : {GF_PIXEL_RGBA, "rgba", "RGBA 32 bits (8 bits / component)"},
963 : {GF_PIXEL_ARGB, "argb", "ARGB 32 bits (8 bits / component)"},
964 : {GF_PIXEL_BGRA, "bgra", "BGRA 32 bits (8 bits / component)"},
965 : {GF_PIXEL_ABGR, "abgr", "ABGR 32 bits (8 bits / component)"},
966 : {GF_PIXEL_RGB, "rgb", "RGB 24 bits (8 bits / component)"},
967 : {GF_PIXEL_BGR, "bgr", "BGR 24 bits (8 bits / component)"},
968 : {GF_PIXEL_XRGB, "xrgb", "xRGB 32 bits (8 bits / component)"},
969 : {GF_PIXEL_RGBX, "rgbx", "RGBx 32 bits (8 bits / component)"},
970 : {GF_PIXEL_XBGR, "xbgr", "xBGR 32 bits (8 bits / component)"},
971 : {GF_PIXEL_BGRX, "bgrx", "BGRx 32 bits (8 bits / component)"},
972 : {GF_PIXEL_RGBD, "rgbd", "RGB+depth 32 bits (8 bits / component)"},
973 : {GF_PIXEL_RGBDS, "rgbds", "RGB+depth+bit shape (8 bits / RGB component, 7 bit depth (low bits) + 1 bit shape)"},
974 : {GF_PIXEL_RGBS, "rgbs", "RGB 24 bits stereo (side-by-side) - to be removed\n"},
975 : {GF_PIXEL_RGBAS, "rgbas", "RGBA 32 bits stereo (side-by-side) - to be removed\n"},
976 : {GF_PIXEL_GL_EXTERNAL, "extgl", "External OpenGL texture of unknown format, to be used with samplerExternalOES\n"},
977 : {0}
978 : };
979 :
980 : GF_EXPORT
981 3991 : GF_PixelFormat gf_pixel_fmt_parse(const char *pf_name)
982 : {
983 : u32 i=0;
984 3991 : if (!pf_name || !strcmp(pf_name, "none")) return 0;
985 56663 : while (GF_PixelFormats[i].pixfmt) {
986 56663 : if (!strcmp(GF_PixelFormats[i].name, pf_name))
987 : return GF_PixelFormats[i].pixfmt;
988 54955 : if (GF_PixelFormats[i].sname && !strcmp(GF_PixelFormats[i].sname, pf_name))
989 : return GF_PixelFormats[i].pixfmt;
990 54602 : i++;
991 : }
992 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %s\n", pf_name));
993 : return 0;
994 : }
995 : GF_EXPORT
996 121 : const char *gf_pixel_fmt_name(GF_PixelFormat pfmt)
997 : {
998 : u32 i=0;
999 3582 : while (GF_PixelFormats[i].pixfmt) {
1000 3458 : if (GF_PixelFormats[i].pixfmt==pfmt) return GF_PixelFormats[i].name;
1001 3340 : i++;
1002 : }
1003 3 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %d (%s)\n", pfmt, gf_4cc_to_str(pfmt) ));
1004 : return "unknown";
1005 : }
1006 : GF_EXPORT
1007 3051 : const char *gf_pixel_fmt_sname(GF_PixelFormat pfmt)
1008 : {
1009 : u32 i=0;
1010 89749 : while (GF_PixelFormats[i].pixfmt) {
1011 86698 : if (GF_PixelFormats[i].pixfmt==pfmt) {
1012 3051 : if (GF_PixelFormats[i].sname)
1013 : return GF_PixelFormats[i].sname;
1014 2553 : return GF_PixelFormats[i].name;
1015 : }
1016 83647 : i++;
1017 : }
1018 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %d (%s)\n", pfmt, gf_4cc_to_str(pfmt) ));
1019 : return "unknown";
1020 :
1021 : }
1022 :
1023 : GF_EXPORT
1024 94 : GF_PixelFormat gf_pixel_fmt_enum(u32 *idx, const char **name, const char **fileext, const char **description)
1025 : {
1026 : u32 nb_pfmt = sizeof(GF_PixelFormats) / sizeof(GF_PixFmt);
1027 94 : if (*idx >= nb_pfmt) return 0;
1028 94 : if (! GF_PixelFormats[*idx].pixfmt) return 0;
1029 :
1030 92 : *name = GF_PixelFormats[*idx].name;
1031 92 : *fileext = GF_PixelFormats[*idx].sname;
1032 92 : if (! *fileext) *fileext = *name;
1033 92 : *description = GF_PixelFormats[*idx].desc;
1034 92 : nb_pfmt = GF_PixelFormats[*idx].pixfmt;
1035 92 : (*idx)++;
1036 92 : return nb_pfmt;
1037 : }
1038 :
1039 :
1040 : GF_EXPORT
1041 3592 : Bool gf_pixel_fmt_is_yuv(GF_PixelFormat pfmt)
1042 : {
1043 : u32 i=0;
1044 11548 : while (GF_PixelFormats[i].pixfmt) {
1045 7956 : if (GF_PixelFormats[i].pixfmt==pfmt) return GF_TRUE;
1046 4508 : if (GF_PixelFormats[i].pixfmt==GF_PIXEL_GREYSCALE) return GF_FALSE;
1047 4364 : i++;
1048 : }
1049 : return GF_FALSE;
1050 : }
1051 :
1052 : static char szAllPixelFormats[5000] = {0};
1053 :
1054 : GF_EXPORT
1055 11373 : const char *gf_pixel_fmt_all_names()
1056 : {
1057 11373 : if (!szAllPixelFormats[0]) {
1058 : u32 i=0;
1059 : u32 tot_len=4;
1060 : strcpy(szAllPixelFormats, "none");
1061 128827 : while (GF_PixelFormats[i].pixfmt) {
1062 : u32 len;
1063 :
1064 : //we don't expose this one
1065 126086 : if (GF_PixelFormats[i].pixfmt==GF_PIXEL_GL_EXTERNAL) {
1066 2741 : i++;
1067 2741 : continue;
1068 : }
1069 :
1070 123345 : len = (u32) strlen(GF_PixelFormats[i].name);
1071 123345 : if (len+tot_len+2>=5000) {
1072 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Not enough memory to hold all pixel formats!!\n"));
1073 : break;
1074 : }
1075 : strcat((char *)szAllPixelFormats, ",");
1076 123345 : tot_len += 1;
1077 : strcat((char *)szAllPixelFormats, GF_PixelFormats[i].name);
1078 123345 : tot_len += len;
1079 123345 : i++;
1080 : }
1081 : }
1082 11373 : return szAllPixelFormats;
1083 : }
1084 :
1085 : static char szAllShortPixelFormats[5000] = {0};
1086 :
1087 : GF_EXPORT
1088 5619 : const char *gf_pixel_fmt_all_shortnames()
1089 : {
1090 5619 : if (!szAllShortPixelFormats[0]) {
1091 : u32 i=0;
1092 : u32 tot_len=0;
1093 128827 : while (GF_PixelFormats[i].pixfmt) {
1094 : u32 len;
1095 : const char *n;
1096 : //we don't expose this one
1097 126086 : if (GF_PixelFormats[i].pixfmt==GF_PIXEL_GL_EXTERNAL) {
1098 2741 : i++;
1099 2741 : continue;
1100 : }
1101 123345 : n = GF_PixelFormats[i].sname ? GF_PixelFormats[i].sname : GF_PixelFormats[i].name;
1102 123345 : len = (u32) strlen(n);
1103 123345 : if (len+tot_len+1>=5000) {
1104 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Not enough memory to hold all pixel formats!!\n"));
1105 : break;
1106 : }
1107 123345 : if (i) {
1108 : strcat((char *)szAllShortPixelFormats, "|");
1109 120604 : tot_len += 1;
1110 : strcat((char *)szAllShortPixelFormats, n);
1111 : } else {
1112 : strcpy((char *)szAllShortPixelFormats, n);
1113 : }
1114 123345 : tot_len += len;
1115 123345 : i++;
1116 : }
1117 : }
1118 5619 : return szAllShortPixelFormats;
1119 : }
1120 :
1121 : GF_EXPORT
1122 128283 : Bool gf_pixel_get_size_info(GF_PixelFormat pixfmt, u32 width, u32 height, u32 *out_size, u32 *out_stride, u32 *out_stride_uv, u32 *out_planes, u32 *out_plane_uv_height)
1123 : {
1124 : u32 stride=0, stride_uv=0, size=0, planes=0, uv_height=0;
1125 128283 : Bool no_in_stride = (!out_stride || (*out_stride==0)) ? GF_TRUE : GF_FALSE;
1126 128283 : Bool no_in_stride_uv = (!out_stride_uv || (*out_stride_uv==0)) ? GF_TRUE : GF_FALSE;
1127 :
1128 128283 : switch (pixfmt) {
1129 80 : case GF_PIXEL_GREYSCALE:
1130 80 : stride = no_in_stride ? width : *out_stride;
1131 80 : size = stride * height;
1132 : planes=1;
1133 80 : break;
1134 64 : case GF_PIXEL_ALPHAGREY:
1135 : case GF_PIXEL_GREYALPHA:
1136 64 : stride = no_in_stride ? 2*width : *out_stride;
1137 64 : size = stride * height;
1138 : planes=1;
1139 64 : break;
1140 88 : case GF_PIXEL_RGB_444:
1141 : case GF_PIXEL_RGB_555:
1142 : case GF_PIXEL_RGB_565:
1143 88 : stride = no_in_stride ? 2*width : *out_stride;
1144 88 : size = stride * height;
1145 : planes=1;
1146 88 : break;
1147 599 : case GF_PIXEL_ARGB:
1148 : case GF_PIXEL_RGBA:
1149 : case GF_PIXEL_BGRA:
1150 : case GF_PIXEL_ABGR:
1151 : case GF_PIXEL_RGBX:
1152 : case GF_PIXEL_BGRX:
1153 : case GF_PIXEL_XRGB:
1154 : case GF_PIXEL_XBGR:
1155 : case GF_PIXEL_RGBD:
1156 : case GF_PIXEL_RGBDS:
1157 : case GF_PIXEL_RGBAS:
1158 599 : stride = no_in_stride ? 4*width : *out_stride;
1159 599 : size = stride * height;
1160 : planes=1;
1161 599 : break;
1162 0 : case GF_PIXEL_RGB_DEPTH:
1163 0 : stride = no_in_stride ? 3*width : *out_stride;
1164 0 : stride_uv = no_in_stride_uv ? width : *out_stride_uv;
1165 0 : size = 4 * width * height;
1166 : planes=1;
1167 0 : break;
1168 44244 : case GF_PIXEL_RGB:
1169 : case GF_PIXEL_BGR:
1170 : case GF_PIXEL_RGBS:
1171 44244 : stride = no_in_stride ? 3*width : *out_stride;
1172 44244 : size = stride * height;
1173 : planes=1;
1174 44244 : break;
1175 7095 : case GF_PIXEL_YUV:
1176 : case GF_PIXEL_YVU:
1177 7095 : stride = no_in_stride ? width : *out_stride;
1178 7095 : uv_height = height / 2;
1179 7095 : if (height % 2) uv_height++;
1180 7095 : stride_uv = no_in_stride_uv ? stride/2 : *out_stride_uv;
1181 7095 : if (no_in_stride_uv && (stride%2) )
1182 0 : stride_uv+=1;
1183 : planes=3;
1184 7095 : size = stride * height + stride_uv * uv_height * 2;
1185 7095 : break;
1186 1 : case GF_PIXEL_YUVA:
1187 : case GF_PIXEL_YUVD:
1188 1 : stride = no_in_stride ? width : *out_stride;
1189 1 : uv_height = height / 2;
1190 1 : if (height % 2) uv_height++;
1191 1 : stride_uv = no_in_stride_uv ? stride/2 : *out_stride_uv;
1192 1 : if (no_in_stride_uv && (stride%2) )
1193 0 : stride_uv+=1;
1194 : planes=4;
1195 1 : size = 2*stride * height + stride_uv * uv_height * 2;
1196 1 : break;
1197 15101 : case GF_PIXEL_YUV_10:
1198 15101 : stride = no_in_stride ? 2*width : *out_stride;
1199 15101 : uv_height = height / 2;
1200 15101 : if (height % 2) uv_height++;
1201 15101 : stride_uv = no_in_stride_uv ? stride/2 : *out_stride_uv;
1202 15101 : if (no_in_stride_uv && (stride%2) )
1203 0 : stride_uv+=1;
1204 : planes=3;
1205 15101 : size = stride * height + stride_uv * uv_height * 2;
1206 15101 : break;
1207 15131 : case GF_PIXEL_YUV422:
1208 15131 : stride = no_in_stride ? width : *out_stride;
1209 : uv_height = height;
1210 15131 : stride_uv = no_in_stride_uv ? stride/2 : *out_stride_uv;
1211 15131 : if (no_in_stride_uv && (stride%2) )
1212 0 : stride_uv+=1;
1213 : planes=3;
1214 15131 : size = stride * height + stride_uv * height * 2;
1215 15131 : break;
1216 15100 : case GF_PIXEL_YUV422_10:
1217 15100 : stride = no_in_stride ? 2*width : *out_stride;
1218 : uv_height = height;
1219 15100 : stride_uv = no_in_stride_uv ? stride/2 : *out_stride_uv;
1220 15100 : if (no_in_stride_uv && (stride%2) )
1221 0 : stride_uv+=1;
1222 : planes=3;
1223 15100 : size = stride * height + stride_uv * height * 2;
1224 15100 : break;
1225 15131 : case GF_PIXEL_YUV444:
1226 15131 : stride = no_in_stride ? width : *out_stride;
1227 : uv_height = height;
1228 15131 : stride_uv = no_in_stride_uv ? stride : *out_stride_uv;
1229 : planes=3;
1230 15131 : size = stride * height * 3;
1231 15131 : break;
1232 1 : case GF_PIXEL_YUVA444:
1233 1 : stride = no_in_stride ? width : *out_stride;
1234 : uv_height = height;
1235 1 : stride_uv = no_in_stride_uv ? stride : *out_stride_uv;
1236 : planes=4;
1237 1 : size = stride * height * 4;
1238 1 : break;
1239 15100 : case GF_PIXEL_YUV444_10:
1240 15100 : stride = no_in_stride ? 2*width : *out_stride;
1241 : uv_height = height;
1242 15100 : stride_uv = no_in_stride_uv ? stride : *out_stride_uv;
1243 : planes=3;
1244 15100 : size = stride * height * 3;
1245 15100 : break;
1246 158 : case GF_PIXEL_NV12:
1247 : case GF_PIXEL_NV21:
1248 158 : stride = no_in_stride ? width : *out_stride;
1249 158 : size = 3 * stride * height / 2;
1250 158 : uv_height = height/2;
1251 158 : stride_uv = no_in_stride_uv ? stride : *out_stride_uv;
1252 : planes=2;
1253 : break;
1254 74 : case GF_PIXEL_NV12_10:
1255 : case GF_PIXEL_NV21_10:
1256 74 : stride = no_in_stride ? 2*width : *out_stride;
1257 74 : uv_height = height/2;
1258 74 : if (height % 2) uv_height++;
1259 74 : stride_uv = no_in_stride_uv ? stride : *out_stride_uv;
1260 : planes=2;
1261 74 : size = 3 * stride * height / 2;
1262 74 : break;
1263 316 : case GF_PIXEL_UYVY:
1264 : case GF_PIXEL_VYUY:
1265 : case GF_PIXEL_YUYV:
1266 : case GF_PIXEL_YVYU:
1267 316 : stride = no_in_stride ? 2*width : *out_stride;
1268 : planes=1;
1269 316 : size = height * stride;
1270 316 : break;
1271 0 : case GF_PIXEL_UYVY_10:
1272 : case GF_PIXEL_VYUY_10:
1273 : case GF_PIXEL_YUYV_10:
1274 : case GF_PIXEL_YVYU_10:
1275 0 : stride = no_in_stride ? 4*width : *out_stride;
1276 : planes=1;
1277 0 : size = height * stride;
1278 0 : break;
1279 0 : case GF_PIXEL_YUV444_PACK:
1280 0 : stride = no_in_stride ? 3 * width : *out_stride;
1281 : planes=1;
1282 0 : size = height * stride;
1283 0 : break;
1284 0 : case GF_PIXEL_YUVA444_PACK:
1285 0 : stride = no_in_stride ? 4 * width : *out_stride;
1286 : planes=1;
1287 0 : size = height * stride;
1288 0 : break;
1289 0 : case GF_PIXEL_YUV444_10_PACK:
1290 0 : stride = no_in_stride ? 4 * width : *out_stride;
1291 : planes = 1;
1292 0 : size = height * stride;
1293 0 : break;
1294 :
1295 : case GF_PIXEL_GL_EXTERNAL:
1296 : planes = 1;
1297 : size = 0;
1298 : stride = 0;
1299 : stride_uv = 0;
1300 : uv_height = 0;
1301 : break;
1302 0 : default:
1303 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %s, cannot get size info\n", gf_pixel_fmt_name(pixfmt) ));
1304 : return GF_FALSE;
1305 : }
1306 128283 : if (out_size) *out_size = size;
1307 128283 : if (out_stride) *out_stride = stride;
1308 128283 : if (out_stride_uv) *out_stride_uv = stride_uv;
1309 128283 : if (out_planes) *out_planes = planes;
1310 128283 : if (out_plane_uv_height) *out_plane_uv_height = uv_height;
1311 : return GF_TRUE;
1312 : }
1313 :
1314 : GF_EXPORT
1315 39130 : u32 gf_pixel_get_bytes_per_pixel(GF_PixelFormat pixfmt)
1316 : {
1317 39130 : switch (pixfmt) {
1318 : case GF_PIXEL_GREYSCALE:
1319 : return 1;
1320 77 : case GF_PIXEL_ALPHAGREY:
1321 : case GF_PIXEL_GREYALPHA:
1322 : case GF_PIXEL_RGB_444:
1323 : case GF_PIXEL_RGB_555:
1324 : case GF_PIXEL_RGB_565:
1325 77 : return 2;
1326 547 : case GF_PIXEL_RGBX:
1327 : case GF_PIXEL_BGRX:
1328 : case GF_PIXEL_XRGB:
1329 : case GF_PIXEL_XBGR:
1330 : case GF_PIXEL_ARGB:
1331 : case GF_PIXEL_RGBA:
1332 : case GF_PIXEL_BGRA:
1333 : case GF_PIXEL_ABGR:
1334 : case GF_PIXEL_RGBD:
1335 : case GF_PIXEL_RGBDS:
1336 : case GF_PIXEL_RGBAS:
1337 : case GF_PIXEL_RGB_DEPTH:
1338 547 : return 4;
1339 36514 : case GF_PIXEL_RGB:
1340 : case GF_PIXEL_BGR:
1341 : case GF_PIXEL_RGBS:
1342 36514 : return 3;
1343 : case GF_PIXEL_YUV:
1344 : case GF_PIXEL_YVU:
1345 : case GF_PIXEL_YUVA:
1346 : case GF_PIXEL_YUVA444:
1347 : case GF_PIXEL_YUVD:
1348 : return 1;
1349 124 : case GF_PIXEL_YUV_10:
1350 124 : return 2;
1351 : case GF_PIXEL_YUV422:
1352 : return 1;
1353 124 : case GF_PIXEL_YUV422_10:
1354 124 : return 2;
1355 : case GF_PIXEL_YUV444:
1356 : return 1;
1357 124 : case GF_PIXEL_YUV444_10:
1358 124 : return 2;
1359 : case GF_PIXEL_NV12:
1360 : case GF_PIXEL_NV21:
1361 : return 1;
1362 32 : case GF_PIXEL_NV12_10:
1363 : case GF_PIXEL_NV21_10:
1364 32 : return 2;
1365 : case GF_PIXEL_UYVY:
1366 : case GF_PIXEL_VYUY:
1367 : case GF_PIXEL_YUYV:
1368 : case GF_PIXEL_YVYU:
1369 : return 1;
1370 0 : case GF_PIXEL_UYVY_10:
1371 : case GF_PIXEL_VYUY_10:
1372 : case GF_PIXEL_YUYV_10:
1373 : case GF_PIXEL_YVYU_10:
1374 0 : return 2;
1375 : case GF_PIXEL_YUV444_PACK:
1376 : case GF_PIXEL_YUVA444_PACK:
1377 : case GF_PIXEL_YUV444_10_PACK:
1378 : return 1;
1379 :
1380 : case GF_PIXEL_GL_EXTERNAL:
1381 : return 1;
1382 0 : default:
1383 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %s, cannot get bytes per pixel info\n", gf_pixel_fmt_name(pixfmt) ));
1384 : break;
1385 : }
1386 : return 0;
1387 : }
1388 :
1389 : GF_EXPORT
1390 243 : u32 gf_pixel_get_nb_comp(GF_PixelFormat pixfmt)
1391 : {
1392 243 : switch (pixfmt) {
1393 : case GF_PIXEL_GREYSCALE:
1394 : return 1;
1395 0 : case GF_PIXEL_ALPHAGREY:
1396 : case GF_PIXEL_GREYALPHA:
1397 0 : return 2;
1398 0 : case GF_PIXEL_RGB_444:
1399 : case GF_PIXEL_RGB_555:
1400 : case GF_PIXEL_RGB_565:
1401 : case GF_PIXEL_RGBX:
1402 : case GF_PIXEL_BGRX:
1403 : case GF_PIXEL_XRGB:
1404 : case GF_PIXEL_XBGR:
1405 0 : return 3;
1406 30 : case GF_PIXEL_ARGB:
1407 : case GF_PIXEL_RGBA:
1408 : case GF_PIXEL_BGRA:
1409 : case GF_PIXEL_ABGR:
1410 30 : return 4;
1411 0 : case GF_PIXEL_RGBD:
1412 0 : return 4;
1413 0 : case GF_PIXEL_RGBDS:
1414 0 : return 5;
1415 0 : case GF_PIXEL_RGBAS:
1416 0 : return 5;
1417 0 : case GF_PIXEL_RGB_DEPTH:
1418 0 : return 4;
1419 4 : case GF_PIXEL_RGB:
1420 : case GF_PIXEL_BGR:
1421 4 : return 3;
1422 0 : case GF_PIXEL_RGBS:
1423 0 : return 4;
1424 202 : case GF_PIXEL_YUV:
1425 : case GF_PIXEL_YVU:
1426 202 : return 3;
1427 2 : case GF_PIXEL_YUVA:
1428 : case GF_PIXEL_YUVA444:
1429 2 : return 4;
1430 0 : case GF_PIXEL_YUVD:
1431 0 : return 4;
1432 1 : case GF_PIXEL_YUV_10:
1433 1 : return 3;
1434 0 : case GF_PIXEL_YUV422:
1435 0 : return 3;
1436 1 : case GF_PIXEL_YUV422_10:
1437 1 : return 3;
1438 0 : case GF_PIXEL_YUV444:
1439 0 : return 3;
1440 1 : case GF_PIXEL_YUV444_10:
1441 1 : return 3;
1442 0 : case GF_PIXEL_NV12:
1443 : case GF_PIXEL_NV21:
1444 0 : return 3;
1445 2 : case GF_PIXEL_NV12_10:
1446 : case GF_PIXEL_NV21_10:
1447 2 : return 3;
1448 0 : case GF_PIXEL_UYVY:
1449 : case GF_PIXEL_VYUY:
1450 : case GF_PIXEL_YUYV:
1451 : case GF_PIXEL_YVYU:
1452 0 : return 3;
1453 0 : case GF_PIXEL_UYVY_10:
1454 : case GF_PIXEL_VYUY_10:
1455 : case GF_PIXEL_YUYV_10:
1456 : case GF_PIXEL_YVYU_10:
1457 0 : return 3;
1458 0 : case GF_PIXEL_YUV444_PACK:
1459 0 : return 3;
1460 0 : case GF_PIXEL_YUVA444_PACK:
1461 0 : return 4;
1462 0 : case GF_PIXEL_YUV444_10_PACK:
1463 0 : return 3;
1464 :
1465 : case GF_PIXEL_GL_EXTERNAL:
1466 : return 1;
1467 0 : default:
1468 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unsupported pixel format %s, cannot get number of components per pixel info\n", gf_pixel_fmt_name(pixfmt) ));
1469 : break;
1470 : }
1471 : return 0;
1472 : }
1473 :
1474 : static struct pixfmt_to_qt
1475 : {
1476 : GF_PixelFormat pfmt;
1477 : u32 qt4cc;
1478 : } PixelsToQT[] = {
1479 : {GF_PIXEL_RGB, GF_QT_SUBTYPE_RAW},
1480 : {GF_PIXEL_YUYV, GF_QT_SUBTYPE_YUYV},
1481 : {GF_PIXEL_UYVY, GF_QT_SUBTYPE_UYVY},
1482 : {GF_PIXEL_YUV444_PACK, GF_QT_SUBTYPE_YUV444},
1483 : {GF_PIXEL_YUVA444_PACK, GF_QT_SUBTYPE_YUVA444},
1484 : {GF_PIXEL_UYVY_10, GF_QT_SUBTYPE_YUV422_16},
1485 : {GF_PIXEL_YVYU, GF_QT_SUBTYPE_YVYU},
1486 : {GF_PIXEL_YUV444_10_PACK, GF_QT_SUBTYPE_YUV444_10},
1487 : {GF_PIXEL_YUV, GF_QT_SUBTYPE_YUV420},
1488 : {GF_PIXEL_YUV, GF_QT_SUBTYPE_I420},
1489 : {GF_PIXEL_YUV, GF_QT_SUBTYPE_IYUV},
1490 : {GF_PIXEL_YVU, GF_QT_SUBTYPE_YV12},
1491 : {GF_PIXEL_RGBA, GF_QT_SUBTYPE_RGBA},
1492 : {GF_PIXEL_ABGR, GF_QT_SUBTYPE_ABGR}
1493 : };
1494 :
1495 : GF_EXPORT
1496 222 : GF_PixelFormat gf_pixel_fmt_from_qt_type(u32 qt_code)
1497 : {
1498 : u32 i, count = GF_ARRAY_LENGTH(PixelsToQT);
1499 3330 : for (i=0; i<count; i++) {
1500 3108 : if (PixelsToQT[i].qt4cc==qt_code) return PixelsToQT[i].pfmt;
1501 : }
1502 : return 0;
1503 : }
1504 :
1505 : GF_EXPORT
1506 47 : u32 gf_pixel_fmt_to_qt_type(GF_PixelFormat pix_fmt)
1507 : {
1508 : u32 i, count = GF_ARRAY_LENGTH(PixelsToQT);
1509 607 : for (i=0; i<count; i++) {
1510 573 : if (PixelsToQT[i].pfmt==pix_fmt) return PixelsToQT[i].qt4cc;
1511 : }
1512 34 : GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("Unknown mapping to QT/ISOBMFF for pixel format %s\n", gf_pixel_fmt_name(pix_fmt)));
1513 : return 0;
1514 : }
1515 :
1516 :
1517 : static struct _itags {
1518 : const char *name;
1519 : const char *alt_name;
1520 : u32 itag;
1521 : u32 id3tag;
1522 : u32 type;
1523 : Bool match_substr;
1524 : } itunes_tags[] = {
1525 :
1526 : {"title", "name", GF_ISOM_ITUNE_NAME, GF_ID3V2_FRAME_TIT2, GF_ITAG_STR, 0},
1527 : {"artist", NULL, GF_ISOM_ITUNE_ARTIST, GF_ID3V2_FRAME_TPE1, GF_ITAG_STR, 0},
1528 : {"album_artist", "albumArtist", GF_ISOM_ITUNE_ALBUM_ARTIST, GF_ID3V2_FRAME_TPE2, GF_ITAG_STR, 1},
1529 : {"album", NULL, GF_ISOM_ITUNE_ALBUM, GF_ID3V2_FRAME_TALB, GF_ITAG_STR, 0},
1530 : {"group", "grouping", GF_ISOM_ITUNE_GROUP, GF_ID3V2_FRAME_TIT1, GF_ITAG_STR, 0},
1531 : {"composer", NULL, GF_ISOM_ITUNE_COMPOSER, GF_ID3V2_FRAME_TCOM, GF_ITAG_STR, 0},
1532 : {"writer", NULL, GF_ISOM_ITUNE_WRITER, GF_ID3V2_FRAME_TEXT, GF_ITAG_STR, 0},
1533 : {"conductor", NULL, GF_ISOM_ITUNE_CONDUCTOR, GF_ID3V2_FRAME_TPE3, GF_ITAG_STR, 0},
1534 : {"comment", "comments", GF_ISOM_ITUNE_COMMENT, GF_ID3V2_FRAME_COMM, GF_ITAG_STR, 1},
1535 : //mapped dynamically to GF_ISOM_ITUNE_GENRE or GF_ISOM_ITUNE_GENRE_USER
1536 : {"genre", NULL, GF_ISOM_ITUNE_GENRE, GF_ID3V2_FRAME_TCON, GF_ITAG_ID3_GENRE, 0},
1537 : {"created", "releaseDate", GF_ISOM_ITUNE_CREATED, GF_ID3V2_FRAME_TYER, GF_ITAG_STR, 1},
1538 : {"track", NULL, GF_ISOM_ITUNE_TRACK, 0, GF_ITAG_STR, 0},
1539 : {"tracknum", NULL, GF_ISOM_ITUNE_TRACKNUMBER, GF_ID3V2_FRAME_TRCK, GF_ITAG_FRAC8, 0},
1540 : {"disk", NULL, GF_ISOM_ITUNE_DISK, GF_ID3V2_FRAME_TPOS, GF_ITAG_FRAC6, 0},
1541 : {"tempo", NULL, GF_ISOM_ITUNE_TEMPO, GF_ID3V2_FRAME_TBPM, GF_ITAG_INT16, 0},
1542 : {"compilation", NULL, GF_ISOM_ITUNE_COMPILATION, GF_ID3V2_FRAME_TCMP, GF_ITAG_BOOL, 0},
1543 : {"show", "tvShow", GF_ISOM_ITUNE_TV_SHOW, 0, GF_ITAG_STR, 0},
1544 : {"episode_id", "tvEpisodeID", GF_ISOM_ITUNE_TV_EPISODE, 0, GF_ITAG_STR, 0},
1545 : {"season", "tvSeason", GF_ISOM_ITUNE_TV_SEASON, 0, GF_ITAG_INT32, 0},
1546 : {"episode", "tvEPisode", GF_ISOM_ITUNE_TV_EPISODE_NUM, 0, GF_ITAG_INT32, 0},
1547 : {"network", "tvNetwork", GF_ISOM_ITUNE_TV_NETWORK, 0, GF_ITAG_STR, 0},
1548 : {"sdesc", "description", GF_ISOM_ITUNE_DESCRIPTION, 0, GF_ITAG_STR, 0},
1549 : {"ldesc", "longDescription", GF_ISOM_ITUNE_LONG_DESCRIPTION, GF_ID3V2_FRAME_TDES, GF_ITAG_STR, 0},
1550 : {"lyrics", NULL, GF_ISOM_ITUNE_LYRICS, GF_ID3V2_FRAME_USLT, GF_ITAG_STR, 0},
1551 : {"sort_name", "sortName", GF_ISOM_ITUNE_SORT_NAME, GF_ID3V2_FRAME_TSOT, GF_ITAG_STR, 0},
1552 : {"sort_artist", "sortArtist", GF_ISOM_ITUNE_SORT_ARTIST, GF_ID3V2_FRAME_TSOP, GF_ITAG_STR, 0},
1553 : {"sort_album_artist", "sortAlbumArtist", GF_ISOM_ITUNE_SORT_ALB_ARTIST, GF_ID3V2_FRAME_TSO2, GF_ITAG_STR, 0},
1554 : {"sort_album", "sortAlbum", GF_ISOM_ITUNE_SORT_ALBUM, GF_ID3V2_FRAME_TSOA, GF_ITAG_STR, 0},
1555 : {"sort_composer", "sortComposer", GF_ISOM_ITUNE_SORT_COMPOSER, GF_ID3V2_FRAME_TSOC, GF_ITAG_STR, 0},
1556 : {"sort_show", "sortShow", GF_ISOM_ITUNE_SORT_SHOW, 0, GF_ITAG_STR, 0},
1557 : {"cover", "artwork", GF_ISOM_ITUNE_COVER_ART, 0, GF_ITAG_FILE, 0},
1558 : {"copyright", NULL, GF_ISOM_ITUNE_COPYRIGHT, GF_ID3V2_FRAME_TCOP, GF_ITAG_STR, 0},
1559 : {"tool", "encodingTool", GF_ISOM_ITUNE_TOOL, 0, GF_ITAG_STR, 0},
1560 : {"encoder", "encodedBy", GF_ISOM_ITUNE_ENCODER, GF_ID3V2_FRAME_TENC, GF_ITAG_STR, 0},
1561 : {"pdate", "purchaseDate", GF_ISOM_ITUNE_PURCHASE_DATE, 0, GF_ITAG_STR, 0},
1562 : {"podcast", NULL, GF_ISOM_ITUNE_PODCAST, 0, GF_ITAG_BOOL, 0},
1563 : {"url", "podcastURL", GF_ISOM_ITUNE_PODCAST_URL, 0, GF_ITAG_STR, 0},
1564 : {"keywords", NULL, GF_ISOM_ITUNE_KEYWORDS, GF_ID3V2_FRAME_TKWD, GF_ITAG_STR, 0},
1565 : {"category", NULL, GF_ISOM_ITUNE_CATEGORY, GF_ID3V2_FRAME_TCAT, GF_ITAG_STR, 0},
1566 : {"hdvideo", NULL, GF_ISOM_ITUNE_HD_VIDEO, 0, GF_ITAG_INT8, 0},
1567 : {"media", "mediaType", GF_ISOM_ITUNE_MEDIA_TYPE, 0, GF_ITAG_INT8, 0},
1568 : {"rating", "contentRating", GF_ISOM_ITUNE_RATING, 0, GF_ITAG_INT8, 0},
1569 : {"gapless", NULL, GF_ISOM_ITUNE_GAPLESS, 0, GF_ITAG_BOOL, 0},
1570 : {"art_director", NULL, GF_ISOM_ITUNE_ART_DIRECTOR, 0, GF_ITAG_STR, 0},
1571 : {"arranger", NULL, GF_ISOM_ITUNE_ARRANGER, 0, GF_ITAG_STR, 0},
1572 : {"lyricist", NULL, GF_ISOM_ITUNE_LYRICIST, 0, GF_ITAG_STR, 0},
1573 : {"acknowledgement", NULL, GF_ISOM_ITUNE_COPY_ACK, 0, GF_ITAG_STR, 0},
1574 : {"song_description", NULL, GF_ISOM_ITUNE_SONG_DESC, 0, GF_ITAG_STR, 0},
1575 : {"director", NULL, GF_ISOM_ITUNE_DIRECTOR, 0, GF_ITAG_STR, 0},
1576 : {"equalizer", NULL, GF_ISOM_ITUNE_EQ_PRESET, 0, GF_ITAG_STR, 0},
1577 : {"liner", NULL, GF_ISOM_ITUNE_LINER_NOTES, 0, GF_ITAG_STR, 0},
1578 : {"record_company", NULL, GF_ISOM_ITUNE_REC_COMPANY, 0, GF_ITAG_STR, 0},
1579 : {"original_artist", NULL, GF_ISOM_ITUNE_ORIG_ARTIST, 0, GF_ITAG_STR, 0},
1580 : {"phono_rights", NULL, GF_ISOM_ITUNE_PHONO_RIGHTS, 0, GF_ITAG_STR, 0},
1581 : {"producer", NULL, GF_ISOM_ITUNE_PRODUCER, 0, GF_ITAG_STR, 0},
1582 : {"performer", NULL, GF_ISOM_ITUNE_PERFORMER, 0, GF_ITAG_STR, 0},
1583 : {"publisher", NULL, GF_ISOM_ITUNE_PUBLISHER, 0, GF_ITAG_STR, 0},
1584 : {"sound_engineer", NULL, GF_ISOM_ITUNE_SOUND_ENG, 0, GF_ITAG_STR, 0},
1585 : {"soloist", NULL, GF_ISOM_ITUNE_SOLOIST, 0, GF_ITAG_STR, 0},
1586 : {"credits", NULL, GF_ISOM_ITUNE_CREDITS, 0, GF_ITAG_STR, 0},
1587 : {"thanks", NULL, GF_ISOM_ITUNE_THANKS, 0, GF_ITAG_STR, 0},
1588 : {"online_info", NULL, GF_ISOM_ITUNE_ONLINE, 0, GF_ITAG_STR, 0},
1589 : {"exec_producer", NULL, GF_ISOM_ITUNE_EXEC_PRODUCER, 0, GF_ITAG_STR, 0},
1590 :
1591 : };
1592 :
1593 : GF_EXPORT
1594 4 : s32 gf_itags_find_by_id3tag(u32 id3tag)
1595 : {
1596 : u32 i, count = GF_ARRAY_LENGTH(itunes_tags);
1597 4 : if (id3tag==GF_ID3V2_FRAME_TYER) id3tag = GF_ID3V2_FRAME_TDRC;
1598 20 : for (i=0; i<count; i++) {
1599 20 : if (itunes_tags[i].id3tag == id3tag) return i;
1600 : }
1601 : return -1;
1602 : }
1603 :
1604 : GF_EXPORT
1605 80 : s32 gf_itags_find_by_itag(u32 itag)
1606 : {
1607 : u32 i, count = GF_ARRAY_LENGTH(itunes_tags);
1608 1073 : for (i=0; i<count; i++) {
1609 1073 : if (itunes_tags[i].itag == itag) return i;
1610 : }
1611 : return -1;
1612 : }
1613 :
1614 : GF_EXPORT
1615 291 : s32 gf_itags_find_by_name(const char *tag_name)
1616 : {
1617 : u32 i, count = GF_ARRAY_LENGTH(itunes_tags);
1618 18483 : for (i=0; i<count; i++) {
1619 18195 : if (!strcmp(tag_name, itunes_tags[i].name)) {
1620 3 : return i;
1621 18192 : } else if (itunes_tags[i].match_substr && !strnicmp(tag_name, itunes_tags[i].name, strlen(itunes_tags[i].name) )) {
1622 0 : return i;
1623 : }
1624 : }
1625 : return -1;
1626 : }
1627 :
1628 : GF_EXPORT
1629 257 : s32 gf_itags_get_type(u32 tag_idx)
1630 : {
1631 : u32 count = GF_ARRAY_LENGTH(itunes_tags);
1632 257 : if (tag_idx>=count) return -1;
1633 254 : return itunes_tags[tag_idx].type;
1634 : }
1635 :
1636 : GF_EXPORT
1637 246 : const char *gf_itags_get_name(u32 tag_idx)
1638 : {
1639 : u32 count = GF_ARRAY_LENGTH(itunes_tags);
1640 246 : if (tag_idx>=count) return NULL;
1641 246 : return itunes_tags[tag_idx].name;
1642 : }
1643 :
1644 : GF_EXPORT
1645 189 : const char *gf_itags_get_alt_name(u32 tag_idx)
1646 : {
1647 : u32 count = GF_ARRAY_LENGTH(itunes_tags);
1648 189 : if (tag_idx>=count) return NULL;
1649 189 : return itunes_tags[tag_idx].alt_name;
1650 : }
1651 :
1652 : GF_EXPORT
1653 191 : u32 gf_itags_get_itag(u32 tag_idx)
1654 : {
1655 : u32 count = GF_ARRAY_LENGTH(itunes_tags);
1656 191 : if (tag_idx>=count) return 0;
1657 191 : return itunes_tags[tag_idx].itag;
1658 : }
1659 :
1660 : GF_EXPORT
1661 1 : u32 gf_itags_get_id3tag(u32 tag_idx)
1662 : {
1663 : u32 count = GF_ARRAY_LENGTH(itunes_tags);
1664 1 : if (tag_idx>=count) return 0;
1665 1 : return itunes_tags[tag_idx].id3tag;
1666 : }
1667 :
1668 : GF_EXPORT
1669 1 : const char *gf_itags_enum_tags(u32 *idx, u32 *itag, u32 *id3tag, u32 *type)
1670 : {
1671 : u32 i, count = GF_ARRAY_LENGTH(itunes_tags);
1672 1 : if (!idx || (count<= *idx)) return NULL;
1673 : i = *idx;
1674 1 : (*idx) ++;
1675 1 : if (itag) *itag = itunes_tags[i].itag;
1676 1 : if (id3tag) *id3tag = itunes_tags[i].id3tag;
1677 1 : if (type) *type = itunes_tags[i].type;
1678 1 : return itunes_tags[i].name;
1679 : }
1680 :
1681 :
1682 : static const char* ID3v1Genres[] = {
1683 : "Blues", "Classic Rock", "Country", "Dance", "Disco",
1684 : "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal",
1685 : "New Age", "Oldies", "Other", "Pop", "R&B",
1686 : "Rap", "Reggae", "Rock", "Techno", "Industrial",
1687 : "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack",
1688 : "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
1689 : "Fusion", "Trance", "Classical", "Instrumental", "Acid",
1690 : "House", "Game", "Sound Clip", "Gospel", "Noise",
1691 : "AlternRock", "Bass", "Soul", "Punk", "Space",
1692 : "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic",
1693 : "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance",
1694 : "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
1695 : "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American",
1696 : "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes",
1697 : "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz",
1698 : "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
1699 : "Folk", "Folk/Rock", "National Folk", "Swing",
1700 : };
1701 :
1702 : GF_EXPORT
1703 1 : const char *gf_id3_get_genre(u32 tag)
1704 : {
1705 1 : if ((tag>0) && (tag <= (sizeof(ID3v1Genres)/sizeof(const char *)) )) {
1706 0 : return ID3v1Genres[tag-1];
1707 : }
1708 : return "Unknown";
1709 : }
1710 : GF_EXPORT
1711 1 : u32 gf_id3_get_genre_tag(const char *name)
1712 : {
1713 : u32 i, count = sizeof(ID3v1Genres)/sizeof(const char *);
1714 1 : if (!name) return 0;
1715 36 : for (i=0; i<count; i++) {
1716 37 : if (!stricmp(ID3v1Genres[i], name)) return i+1;
1717 : }
1718 : return 0;
1719 : }
1720 :
1721 : struct cicp_prim
1722 : {
1723 : u32 code;
1724 : const char *name;
1725 : } CICPColorPrimaries[] = {
1726 : {GF_CICP_PRIM_RESERVED_0, "reserved0"},
1727 : {GF_CICP_PRIM_BT709, "BT709"},
1728 : {GF_CICP_PRIM_UNSPECIFIED, "undef"},
1729 : {GF_CICP_PRIM_RESERVED_3, "reserved3"},
1730 : {GF_CICP_PRIM_BT470M, "BT470M"},
1731 : {GF_CICP_PRIM_BT470G, "BT470G"},
1732 : {GF_CICP_PRIM_SMPTE170, "SMPTE170"},
1733 : {GF_CICP_PRIM_SMPTE240, "SMPTE240"},
1734 : {GF_CICP_PRIM_FILM, "FILM"},
1735 : {GF_CICP_PRIM_BT2020, "BT2020"},
1736 : {GF_CICP_PRIM_SMPTE428, "SMPTE428"},
1737 : {GF_CICP_PRIM_SMPTE431, "SMPTE431"},
1738 : {GF_CICP_PRIM_SMPTE432, "SMPTE432"},
1739 : {GF_CICP_PRIM_EBU3213, "EBU3213"},
1740 : };
1741 :
1742 24 : static void cicp_parse_int(const char *val, u32 *ival)
1743 : {
1744 24 : if (sscanf(val, "%u", ival)!=1) {
1745 0 : *ival = (u32) -1;
1746 : } else {
1747 : char szCoef[100];
1748 24 : sprintf(szCoef, "%u", *ival);
1749 24 : if (stricmp(szCoef, val))
1750 21 : *ival = -1;
1751 : }
1752 24 : }
1753 :
1754 : GF_EXPORT
1755 8 : u32 gf_cicp_parse_color_primaries(const char *val)
1756 : {
1757 : u32 i, ival, count = GF_ARRAY_LENGTH(CICPColorPrimaries);
1758 8 : cicp_parse_int(val, &ival);
1759 107 : for (i=0; i<count; i++) {
1760 100 : if (!stricmp(val, CICPColorPrimaries[i].name) || (ival==CICPColorPrimaries[i].code)) {
1761 1 : return CICPColorPrimaries[i].code;
1762 : }
1763 : }
1764 7 : if (strcmp(val, "-1")) {
1765 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unknow CICP color primaries type %s\n", val));
1766 : }
1767 : return (u32) -1;
1768 : }
1769 :
1770 : GF_EXPORT
1771 52 : const char *gf_cicp_color_primaries_name(u32 cicp_mx)
1772 : {
1773 : u32 i, count = GF_ARRAY_LENGTH(CICPColorPrimaries);
1774 496 : for (i=0; i<count; i++) {
1775 478 : if (CICPColorPrimaries[i].code==cicp_mx) {
1776 34 : return CICPColorPrimaries[i].name;
1777 : }
1778 : }
1779 : return "unknwon";
1780 : }
1781 :
1782 : static char szCICPPrimAllNames[1024];
1783 :
1784 : GF_EXPORT
1785 32 : const char *gf_cicp_color_primaries_all_names()
1786 : {
1787 32 : if (szCICPPrimAllNames[0] == 0) {
1788 : u32 i, count = GF_ARRAY_LENGTH(CICPColorPrimaries);
1789 448 : for (i=0; i<count; i++) {
1790 448 : if (i) strcat(szCICPPrimAllNames, ",");
1791 448 : strcat(szCICPPrimAllNames, CICPColorPrimaries[i].name);
1792 : }
1793 : }
1794 32 : return szCICPPrimAllNames;
1795 : }
1796 :
1797 :
1798 : struct cicp_trans
1799 : {
1800 : u32 code;
1801 : const char *name;
1802 : } CICPColorTransfer[] = {
1803 : {GF_CICP_TRANSFER_RESERVED_0, "reserved0"},
1804 : {GF_CICP_TRANSFER_BT709, "BT709"},
1805 : {GF_CICP_TRANSFER_UNSPECIFIED, "undef"},
1806 : {GF_CICP_TRANSFER_RESERVED_3, "reserved3"},
1807 : {GF_CICP_TRANSFER_BT470M, "BT470M"},
1808 : {GF_CICP_TRANSFER_BT470BG, "BT470BG"},
1809 : {GF_CICP_TRANSFER_SMPTE170, "SMPTE170"},
1810 : {GF_CICP_TRANSFER_SMPTE240, "SMPTE249"},
1811 : {GF_CICP_TRANSFER_LINEAR, "Linear"},
1812 : {GF_CICP_TRANSFER_LOG100, "Log100"},
1813 : {GF_CICP_TRANSFER_LOG316, "Log316"},
1814 : {GF_CICP_TRANSFER_IEC61966, "IEC61966"},
1815 : {GF_CICP_TRANSFER_BT1361, "BT1361"},
1816 : {GF_CICP_TRANSFER_SRGB, "sRGB"},
1817 : {GF_CICP_TRANSFER_BT2020_10, "BT2020_10"},
1818 : {GF_CICP_TRANSFER_BT2020_12, "BT2020_12"},
1819 : {GF_CICP_TRANSFER_SMPTE2084, "SMPTE2084"},
1820 : {GF_CICP_TRANSFER_SMPTE428, "SMPTE428"},
1821 : {GF_CICP_TRANSFER_STDB67, "STDB67"}
1822 : };
1823 :
1824 : GF_EXPORT
1825 8 : u32 gf_cicp_parse_color_transfer(const char *val)
1826 : {
1827 : u32 i, ival, count = GF_ARRAY_LENGTH(CICPColorTransfer);
1828 8 : cicp_parse_int(val, &ival);
1829 142 : for (i=0; i<count; i++) {
1830 135 : if (!stricmp(val, CICPColorTransfer[i].name) || (CICPColorTransfer[i].code==ival)) {
1831 1 : return CICPColorTransfer[i].code;
1832 : }
1833 : }
1834 7 : if (strcmp(val, "-1")) {
1835 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unknow CICP color transfer type %s\n", val));
1836 : }
1837 : return (u32) -1;
1838 : }
1839 :
1840 : GF_EXPORT
1841 44 : const char *gf_cicp_color_transfer_name(u32 cicp_mx)
1842 : {
1843 : u32 i, count = GF_ARRAY_LENGTH(CICPColorTransfer);
1844 391 : for (i=0; i<count; i++) {
1845 391 : if (CICPColorTransfer[i].code==cicp_mx) {
1846 44 : return CICPColorTransfer[i].name;
1847 : }
1848 : }
1849 : return "unknwon";
1850 : }
1851 :
1852 : static char szCICPTFCAllNames[1024];
1853 :
1854 : GF_EXPORT
1855 32 : const char *gf_cicp_color_transfer_all_names()
1856 : {
1857 32 : if (szCICPTFCAllNames[0] == 0) {
1858 : u32 i, count = GF_ARRAY_LENGTH(CICPColorTransfer);
1859 608 : for (i=0; i<count; i++) {
1860 608 : if (i) strcat(szCICPTFCAllNames, ",");
1861 608 : strcat(szCICPTFCAllNames, CICPColorTransfer[i].name);
1862 : }
1863 : }
1864 32 : return szCICPTFCAllNames;
1865 : }
1866 :
1867 : struct cicp_mx
1868 : {
1869 : u32 code;
1870 : const char *name;
1871 : } CICPColorMatrixCoefficients[] = {
1872 : {GF_CICP_MX_IDENTITY, "GBR"},
1873 : {GF_CICP_MX_BT709, "BT709"},
1874 : {GF_CICP_MX_UNSPECIFIED, "undef"},
1875 : {GF_CICP_MX_FCC47, "FCC"},
1876 : {GF_CICP_MX_BT601_625, "BT601"},
1877 : {GF_CICP_MX_SMPTE170, "SMPTE170"},
1878 : {GF_CICP_MX_SMPTE240, "SMPTE240"},
1879 : {GF_CICP_MX_YCgCo, "YCgCo"},
1880 : {GF_CICP_MX_BT2020, "BT2020"},
1881 : {GF_CICP_MX_BT2020_CL, "BT2020cl"},
1882 : {GF_CICP_MX_YDzDx, "YDzDx"},
1883 : };
1884 :
1885 : GF_EXPORT
1886 8 : u32 gf_cicp_parse_color_matrix(const char *val)
1887 : {
1888 : u32 i, ival, count = GF_ARRAY_LENGTH(CICPColorMatrixCoefficients);
1889 8 : cicp_parse_int(val, &ival);
1890 86 : for (i=0; i<count; i++) {
1891 79 : if (!stricmp(val, CICPColorMatrixCoefficients[i].name) || (ival==CICPColorMatrixCoefficients[i].code)) {
1892 1 : return CICPColorMatrixCoefficients[i].code;
1893 : }
1894 : }
1895 7 : if (strcmp(val, "-1")) {
1896 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Unknow CICP color matrix type %s\n", val));
1897 : }
1898 : return (u32) -1;
1899 : }
1900 :
1901 : GF_EXPORT
1902 30 : const char *gf_cicp_color_matrix_name(u32 cicp_mx)
1903 : {
1904 : u32 i, count = GF_ARRAY_LENGTH(CICPColorMatrixCoefficients);
1905 171 : for (i=0; i<count; i++) {
1906 169 : if (CICPColorMatrixCoefficients[i].code==cicp_mx) {
1907 28 : return CICPColorMatrixCoefficients[i].name;
1908 : }
1909 : }
1910 : return "unknwon";
1911 : }
1912 :
1913 : static char szCICPMXAllNames[1024];
1914 : GF_EXPORT
1915 32 : const char *gf_cicp_color_matrix_all_names()
1916 : {
1917 32 : if (szCICPMXAllNames[0] == 0) {
1918 : u32 i, count = GF_ARRAY_LENGTH(CICPColorMatrixCoefficients);
1919 352 : for (i=0; i<count; i++) {
1920 352 : if (i) strcat(szCICPMXAllNames, ",");
1921 352 : strcat(szCICPMXAllNames, CICPColorMatrixCoefficients[i].name);
1922 : }
1923 : }
1924 32 : return szCICPMXAllNames;
1925 : }
|