1 /*
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * The Original Code is MPEG4IP.
13  *
14  * The Initial Developer of the Original Code is Cisco Systems Inc.
15  * Portions created by Cisco Systems Inc. are
16  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
17  *
18  * 3GPP features implementation is based on 3GPP's TS26.234-v5.60,
19  * and was contributed by Ximpo Group Ltd.
20  *
21  * Portions created by Ximpo Group Ltd. are
22  * Copyright (C) Ximpo Group Ltd. 2003, 2004.  All Rights Reserved.
23  *
24  * Contributor(s):
25  *              Ximpo Group Ltd.          mp4v2@ximpo.com
26  */
27 
28 #include "mp4common.h"
29 
30 #define _3GP_MAJOR_BRAND "3gp5"
31 #define _3GP_MINOR_VERSION 0x0001
32 
Make3GPCompliant(const char * fileName,char * majorBrand,u_int32_t minorVersion,char ** supportedBrands,u_int32_t supportedBrandsCount,bool deleteIodsAtom)33 void MP4File::Make3GPCompliant(const char* fileName,  char* majorBrand, u_int32_t minorVersion, char** supportedBrands, u_int32_t supportedBrandsCount, bool deleteIodsAtom)
34 {
35 	char brand[5] = "3gp5";
36 	char* _3gpSupportedBrands[1] = { (char*)&brand };
37 
38 	if (majorBrand) {
39 		if (!supportedBrands || !supportedBrandsCount) {
40 			throw new MP4Error("Invalid parameters", "MP4File::Make3GPCompliant");
41 		}
42 	}
43 
44 	MakeFtypAtom(
45 			majorBrand ? majorBrand : (char*)brand,
46 			majorBrand ? minorVersion  : _3GP_MINOR_VERSION,
47 			majorBrand ? supportedBrands : (char**)_3gpSupportedBrands,
48 			majorBrand ? supportedBrandsCount : 1);
49 
50 	if (deleteIodsAtom) {
51 		// Delete the iods atom, if it exists....
52 		MP4Atom* iodsAtom = m_pRootAtom->FindAtom("moov.iods");
53 		if (iodsAtom) {
54 			MP4Atom* moovAtom = m_pRootAtom->FindAtom("moov");
55 			ASSERT(moovAtom);
56 
57 			moovAtom->DeleteChildAtom(iodsAtom);
58 		}
59 	}
60 
61 }
62 
MakeFtypAtom(char * majorBrand,u_int32_t minorVersion,char ** supportedBrands,u_int32_t supportedBrandsCount)63 void MP4File::MakeFtypAtom(char* majorBrand, u_int32_t minorVersion, char** supportedBrands, u_int32_t supportedBrandsCount)
64 {
65 	bool rewriteNeeded = false;
66 	u_int32_t currentSupportedBrandsCount;
67 	u_int32_t i;
68 
69 
70 	MP4Atom* ftypAtom = m_pRootAtom->FindAtom("ftyp");
71 	if (ftypAtom == NULL) {
72 	  ftypAtom = InsertChildAtom(m_pRootAtom, "ftyp", 0);
73 	}
74 	if (majorBrand == NULL)
75 	  return;
76 	MP4StringProperty* pMajorBrandProperty;
77 	if (!ftypAtom->FindProperty(
78 				   "ftyp.majorBrand",
79 				   (MP4Property**)&pMajorBrandProperty))
80 	  return;
81 
82 	pMajorBrandProperty->SetValue(majorBrand);
83 
84 
85 	MP4Integer32Property* pMinorVersionProperty;
86 	if (!ftypAtom->FindProperty(
87 				   "ftype.minorVersion",
88 				   (MP4Property**)&pMinorVersionProperty))
89 	  return;
90 
91 	pMinorVersionProperty->SetValue(minorVersion);
92 
93 	MP4Integer32Property* pCompatibleBrandsCountProperty;
94 	if (!ftypAtom->FindProperty(
95 		"ftyp.compatibleBrandsCount",
96 		(MP4Property**)&pCompatibleBrandsCountProperty)) return;
97 
98 	currentSupportedBrandsCount = pCompatibleBrandsCountProperty->GetValue();
99 
100 	MP4TableProperty* pCompatibleBrandsProperty;
101 	if (!ftypAtom->FindProperty(
102 		"ftyp.compatibleBrands",
103 		(MP4Property**)&pCompatibleBrandsProperty)) return;
104 
105 	MP4StringProperty* pBrandProperty = (MP4StringProperty*)
106 		pCompatibleBrandsProperty->GetProperty(0);
107 	ASSERT(pBrandProperty);
108 
109 	for (i = 0 ; i < ((currentSupportedBrandsCount > supportedBrandsCount) ? supportedBrandsCount : currentSupportedBrandsCount) ; i++) {
110 		pBrandProperty->SetValue(supportedBrands[i], i);
111 
112 	}
113 
114 	if (i < supportedBrandsCount) {
115 		for ( ; i < supportedBrandsCount ; i++) {
116 			pBrandProperty->AddValue(supportedBrands[i]);
117 		}
118 	}
119 
120 	if (currentSupportedBrandsCount != supportedBrandsCount) {
121 		rewriteNeeded = true;
122 		pBrandProperty->SetCount(supportedBrandsCount);
123 		pCompatibleBrandsCountProperty->SetReadOnly(false);
124 		pCompatibleBrandsCountProperty->SetValue(supportedBrandsCount);
125 		pCompatibleBrandsCountProperty->SetReadOnly(true);
126 	}
127 
128 }
129