PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/external/mp4parser/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/EC3TrackImpl.java

https://gitlab.com/brian0218/rk3188_r-box_android4.2.2_sdk
Java | 436 lines | 376 code | 53 blank | 7 comment | 120 complexity | 1d568bfaa0f41c3771986a7790347072 MD5 | raw file
  1. package com.googlecode.mp4parser.authoring.tracks;
  2. import com.coremedia.iso.boxes.*;
  3. import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;
  4. import com.googlecode.mp4parser.authoring.AbstractTrack;
  5. import com.googlecode.mp4parser.authoring.TrackMetaData;
  6. import com.googlecode.mp4parser.boxes.EC3SpecificBox;
  7. import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;
  8. import java.io.BufferedInputStream;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.nio.ByteBuffer;
  12. import java.util.Date;
  13. import java.util.LinkedList;
  14. import java.util.List;
  15. /**
  16. * Created by IntelliJ IDEA.
  17. * User: magnus
  18. * Date: 2012-03-14
  19. * Time: 10:39
  20. * To change this template use File | Settings | File Templates.
  21. */
  22. public class EC3TrackImpl extends AbstractTrack {
  23. TrackMetaData trackMetaData = new TrackMetaData();
  24. SampleDescriptionBox sampleDescriptionBox;
  25. int samplerate;
  26. int bitrate;
  27. int frameSize;
  28. List<BitStreamInfo> entries = new LinkedList<BitStreamInfo>();
  29. private BufferedInputStream inputStream;
  30. private List<ByteBuffer> samples;
  31. List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();
  32. private String lang = "und";
  33. public EC3TrackImpl(InputStream fin, String lang) throws IOException {
  34. this.lang = lang;
  35. parse(fin);
  36. }
  37. public EC3TrackImpl(InputStream fin) throws IOException {
  38. parse(fin);
  39. }
  40. private void parse(InputStream fin) throws IOException {
  41. inputStream = new BufferedInputStream(fin);
  42. boolean done = false;
  43. inputStream.mark(10000);
  44. while (!done) {
  45. BitStreamInfo bsi = readVariables();
  46. if (bsi == null) {
  47. throw new IOException();
  48. }
  49. for (BitStreamInfo entry : entries) {
  50. if (bsi.strmtyp != 1 && entry.substreamid == bsi.substreamid) {
  51. done = true;
  52. }
  53. }
  54. if (!done) {
  55. entries.add(bsi);
  56. long skipped = inputStream.skip(bsi.frameSize);
  57. assert skipped == bsi.frameSize;
  58. }
  59. }
  60. inputStream.reset();
  61. if (entries.size() == 0) {
  62. throw new IOException();
  63. }
  64. samplerate = entries.get(0).samplerate;
  65. sampleDescriptionBox = new SampleDescriptionBox();
  66. AudioSampleEntry audioSampleEntry = new AudioSampleEntry("ec-3");
  67. audioSampleEntry.setChannelCount(2); // According to ETSI TS 102 366 Annex F
  68. audioSampleEntry.setSampleRate(samplerate);
  69. audioSampleEntry.setDataReferenceIndex(1);
  70. audioSampleEntry.setSampleSize(16);
  71. EC3SpecificBox ec3 = new EC3SpecificBox();
  72. int[] deps = new int[entries.size()];
  73. int[] chan_locs = new int[entries.size()];
  74. for (BitStreamInfo bsi : entries) {
  75. if (bsi.strmtyp == 1) {
  76. deps[bsi.substreamid]++;
  77. chan_locs[bsi.substreamid] = ((bsi.chanmap >> 6) & 0x100) | ((bsi.chanmap >> 5) & 0xff);
  78. }
  79. }
  80. for (BitStreamInfo bsi : entries) {
  81. if (bsi.strmtyp != 1) {
  82. EC3SpecificBox.Entry e = new EC3SpecificBox.Entry();
  83. e.fscod = bsi.fscod;
  84. e.bsid = bsi.bsid;
  85. e.bsmod = bsi.bsmod;
  86. e.acmod = bsi.acmod;
  87. e.lfeon = bsi.lfeon;
  88. e.reserved = 0;
  89. e.num_dep_sub = deps[bsi.substreamid];
  90. e.chan_loc = chan_locs[bsi.substreamid];
  91. e.reserved2 = 0;
  92. ec3.addEntry(e);
  93. }
  94. bitrate += bsi.bitrate;
  95. frameSize += bsi.frameSize;
  96. }
  97. ec3.setDataRate(bitrate / 1000);
  98. audioSampleEntry.addBox(ec3);
  99. sampleDescriptionBox.addBox(audioSampleEntry);
  100. trackMetaData.setCreationTime(new Date());
  101. trackMetaData.setModificationTime(new Date());
  102. trackMetaData.setLanguage(lang);
  103. trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale
  104. samples = new LinkedList<ByteBuffer>();
  105. if (!readSamples()) {
  106. throw new IOException();
  107. }
  108. }
  109. public List<ByteBuffer> getSamples() {
  110. return samples;
  111. }
  112. public SampleDescriptionBox getSampleDescriptionBox() {
  113. return sampleDescriptionBox;
  114. }
  115. public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
  116. return stts;
  117. }
  118. public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
  119. return null;
  120. }
  121. public long[] getSyncSamples() {
  122. return null;
  123. }
  124. public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
  125. return null;
  126. }
  127. public TrackMetaData getTrackMetaData() {
  128. return trackMetaData;
  129. }
  130. public String getHandler() {
  131. return "soun";
  132. }
  133. public AbstractMediaHeaderBox getMediaHeaderBox() {
  134. return new SoundMediaHeaderBox();
  135. }
  136. public SubSampleInformationBox getSubsampleInformationBox() {
  137. return null;
  138. }
  139. private BitStreamInfo readVariables() throws IOException {
  140. byte[] data = new byte[200];
  141. inputStream.mark(200);
  142. if (200 != inputStream.read(data, 0, 200)) {
  143. return null;
  144. }
  145. inputStream.reset(); // Rewind
  146. ByteBuffer bb = ByteBuffer.wrap(data);
  147. BitReaderBuffer brb = new BitReaderBuffer(bb);
  148. int syncword = brb.readBits(16);
  149. if (syncword != 0xb77) {
  150. return null;
  151. }
  152. BitStreamInfo entry = new BitStreamInfo();
  153. entry.strmtyp = brb.readBits(2);
  154. entry.substreamid = brb.readBits(3);
  155. int frmsiz = brb.readBits(11);
  156. entry.frameSize = 2 * (frmsiz + 1);
  157. entry.fscod = brb.readBits(2);
  158. int fscod2 = -1;
  159. int numblkscod;
  160. if (entry.fscod == 3) {
  161. fscod2 = brb.readBits(2);
  162. numblkscod = 3;
  163. } else {
  164. numblkscod = brb.readBits(2);
  165. }
  166. int numberOfBlocksPerSyncFrame = 0;
  167. switch (numblkscod) {
  168. case 0:
  169. numberOfBlocksPerSyncFrame = 1;
  170. break;
  171. case 1:
  172. numberOfBlocksPerSyncFrame = 2;
  173. break;
  174. case 2:
  175. numberOfBlocksPerSyncFrame = 3;
  176. break;
  177. case 3:
  178. numberOfBlocksPerSyncFrame = 6;
  179. break;
  180. }
  181. entry.frameSize *= (6 / numberOfBlocksPerSyncFrame);
  182. entry.acmod = brb.readBits(3);
  183. entry.lfeon = brb.readBits(1);
  184. entry.bsid = brb.readBits(5);
  185. brb.readBits(5);
  186. if (1 == brb.readBits(1)) {
  187. brb.readBits(8); // compr
  188. }
  189. if (0 == entry.acmod) {
  190. brb.readBits(5);
  191. if (1 == brb.readBits(1)) {
  192. brb.readBits(8);
  193. }
  194. }
  195. if (1 == entry.strmtyp) {
  196. if (1 == brb.readBits(1)) {
  197. entry.chanmap = brb.readBits(16);
  198. }
  199. }
  200. if (1 == brb.readBits(1)) { // mixing metadata
  201. if (entry.acmod > 2) {
  202. brb.readBits(2);
  203. }
  204. if (1 == (entry.acmod & 1) && entry.acmod > 2) {
  205. brb.readBits(3);
  206. brb.readBits(3);
  207. }
  208. if (0 < (entry.acmod & 4)) {
  209. brb.readBits(3);
  210. brb.readBits(3);
  211. }
  212. if (1 == entry.lfeon) {
  213. if (1 == brb.readBits(1)) {
  214. brb.readBits(5);
  215. }
  216. }
  217. if (0 == entry.strmtyp) {
  218. if (1 == brb.readBits(1)) {
  219. brb.readBits(6);
  220. }
  221. if (0 == entry.acmod) {
  222. if (1 == brb.readBits(1)) {
  223. brb.readBits(6);
  224. }
  225. }
  226. if (1 == brb.readBits(1)) {
  227. brb.readBits(6);
  228. }
  229. int mixdef = brb.readBits(2);
  230. if (1 == mixdef) {
  231. brb.readBits(5);
  232. } else if (2 == mixdef) {
  233. brb.readBits(12);
  234. } else if (3 == mixdef) {
  235. int mixdeflen = brb.readBits(5);
  236. if (1 == brb.readBits(1)) {
  237. brb.readBits(5);
  238. if (1 == brb.readBits(1)) {
  239. brb.readBits(4);
  240. }
  241. if (1 == brb.readBits(1)) {
  242. brb.readBits(4);
  243. }
  244. if (1 == brb.readBits(1)) {
  245. brb.readBits(4);
  246. }
  247. if (1 == brb.readBits(1)) {
  248. brb.readBits(4);
  249. }
  250. if (1 == brb.readBits(1)) {
  251. brb.readBits(4);
  252. }
  253. if (1 == brb.readBits(1)) {
  254. brb.readBits(4);
  255. }
  256. if (1 == brb.readBits(1)) {
  257. brb.readBits(4);
  258. }
  259. if (1 == brb.readBits(1)) {
  260. if (1 == brb.readBits(1)) {
  261. brb.readBits(4);
  262. }
  263. if (1 == brb.readBits(1)) {
  264. brb.readBits(4);
  265. }
  266. }
  267. }
  268. if (1 == brb.readBits(1)) {
  269. brb.readBits(5);
  270. if (1 == brb.readBits(1)) {
  271. brb.readBits(7);
  272. if (1 == brb.readBits(1)) {
  273. brb.readBits(8);
  274. }
  275. }
  276. }
  277. for (int i = 0; i < (mixdeflen + 2); i++) {
  278. brb.readBits(8);
  279. }
  280. brb.byteSync();
  281. }
  282. if (entry.acmod < 2) {
  283. if (1 == brb.readBits(1)) {
  284. brb.readBits(14);
  285. }
  286. if (0 == entry.acmod) {
  287. if (1 == brb.readBits(1)) {
  288. brb.readBits(14);
  289. }
  290. }
  291. if (1 == brb.readBits(1)) {
  292. if (numblkscod == 0) {
  293. brb.readBits(5);
  294. } else {
  295. for (int i = 0; i < numberOfBlocksPerSyncFrame; i++) {
  296. if (1 == brb.readBits(1)) {
  297. brb.readBits(5);
  298. }
  299. }
  300. }
  301. }
  302. }
  303. }
  304. }
  305. if (1 == brb.readBits(1)) { // infomdate
  306. entry.bsmod = brb.readBits(3);
  307. }
  308. switch (entry.fscod) {
  309. case 0:
  310. entry.samplerate = 48000;
  311. break;
  312. case 1:
  313. entry.samplerate = 44100;
  314. break;
  315. case 2:
  316. entry.samplerate = 32000;
  317. break;
  318. case 3: {
  319. switch (fscod2) {
  320. case 0:
  321. entry.samplerate = 24000;
  322. break;
  323. case 1:
  324. entry.samplerate = 22050;
  325. break;
  326. case 2:
  327. entry.samplerate = 16000;
  328. break;
  329. case 3:
  330. entry.samplerate = 0;
  331. break;
  332. }
  333. break;
  334. }
  335. }
  336. if (entry.samplerate == 0) {
  337. return null;
  338. }
  339. entry.bitrate = (int) (((double) entry.samplerate) / 1536.0 * entry.frameSize * 8);
  340. return entry;
  341. }
  342. private boolean readSamples() throws IOException {
  343. int read = frameSize;
  344. boolean ret = false;
  345. while (frameSize == read) {
  346. ret = true;
  347. byte[] data = new byte[frameSize];
  348. read = inputStream.read(data);
  349. if (read == frameSize) {
  350. samples.add(ByteBuffer.wrap(data));
  351. stts.add(new TimeToSampleBox.Entry(1, 1536));
  352. }
  353. }
  354. return ret;
  355. }
  356. public static class BitStreamInfo extends EC3SpecificBox.Entry {
  357. public int frameSize;
  358. public int substreamid;
  359. public int bitrate;
  360. public int samplerate;
  361. public int strmtyp;
  362. public int chanmap;
  363. @Override
  364. public String toString() {
  365. return "BitStreamInfo{" +
  366. "frameSize=" + frameSize +
  367. ", substreamid=" + substreamid +
  368. ", bitrate=" + bitrate +
  369. ", samplerate=" + samplerate +
  370. ", strmtyp=" + strmtyp +
  371. ", chanmap=" + chanmap +
  372. '}';
  373. }
  374. }
  375. @Override
  376. public String toString() {
  377. return "EC3TrackImpl{" +
  378. "bitrate=" + bitrate +
  379. ", samplerate=" + samplerate +
  380. ", entries=" + entries +
  381. '}';
  382. }
  383. }