PageRenderTime 279ms CodeModel.GetById 45ms RepoModel.GetById 17ms app.codeStats 0ms

/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp

https://gitlab.com/jhalayashraj/android_frameworks_av4
C++ | 433 lines | 326 code | 89 blank | 18 comment | 82 complexity | 4d3a3aa544bbc044eef23dffaf8cebda MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //#define LOG_NDEBUG 0
  17. #define LOG_TAG "AMPEG4ElementaryAssembler"
  18. #include <utils/Log.h>
  19. #include "AMPEG4ElementaryAssembler.h"
  20. #include "ARTPSource.h"
  21. #include "ASessionDescription.h"
  22. #include <media/stagefright/foundation/ABitReader.h>
  23. #include <media/stagefright/foundation/ABuffer.h>
  24. #include <media/stagefright/foundation/ADebug.h>
  25. #include <media/stagefright/foundation/AMessage.h>
  26. #include <media/stagefright/foundation/hexdump.h>
  27. #include <media/stagefright/Utils.h>
  28. #include <ctype.h>
  29. #include <stdint.h>
  30. namespace android {
  31. static bool GetAttribute(const char *s, const char *key, AString *value) {
  32. value->clear();
  33. size_t keyLen = strlen(key);
  34. for (;;) {
  35. while (isspace(*s)) {
  36. ++s;
  37. }
  38. const char *colonPos = strchr(s, ';');
  39. size_t len =
  40. (colonPos == NULL) ? strlen(s) : colonPos - s;
  41. if (len >= keyLen + 1 && s[keyLen] == '='
  42. && !strncasecmp(s, key, keyLen)) {
  43. value->setTo(&s[keyLen + 1], len - keyLen - 1);
  44. return true;
  45. }
  46. if (colonPos == NULL) {
  47. return false;
  48. }
  49. s = colonPos + 1;
  50. }
  51. }
  52. static bool GetIntegerAttribute(
  53. const char *s, const char *key, unsigned *x) {
  54. *x = 0;
  55. AString val;
  56. if (!GetAttribute(s, key, &val)) {
  57. return false;
  58. }
  59. s = val.c_str();
  60. char *end;
  61. unsigned y = strtoul(s, &end, 10);
  62. if (end == s || *end != '\0') {
  63. return false;
  64. }
  65. *x = y;
  66. return true;
  67. }
  68. static bool GetSampleRateIndex(int32_t sampleRate, size_t *tableIndex) {
  69. static const int32_t kSampleRateTable[] = {
  70. 96000, 88200, 64000, 48000, 44100, 32000,
  71. 24000, 22050, 16000, 12000, 11025, 8000
  72. };
  73. const size_t kNumSampleRates =
  74. sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
  75. *tableIndex = 0;
  76. for (size_t index = 0; index < kNumSampleRates; ++index) {
  77. if (sampleRate == kSampleRateTable[index]) {
  78. *tableIndex = index;
  79. return true;
  80. }
  81. }
  82. return false;
  83. }
  84. // static
  85. AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
  86. const sp<AMessage> &notify, const AString &desc, const AString &params)
  87. : mNotifyMsg(notify),
  88. mIsGeneric(false),
  89. mParams(params),
  90. mSizeLength(0),
  91. mIndexLength(0),
  92. mIndexDeltaLength(0),
  93. mCTSDeltaLength(0),
  94. mDTSDeltaLength(0),
  95. mRandomAccessIndication(false),
  96. mStreamStateIndication(0),
  97. mAuxiliaryDataSizeLength(0),
  98. mHasAUHeader(false),
  99. mChannelConfig(0),
  100. mSampleRateIndex(0),
  101. mAccessUnitRTPTime(0),
  102. mNextExpectedSeqNoValid(false),
  103. mNextExpectedSeqNo(0),
  104. mAccessUnitDamaged(false) {
  105. mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
  106. if (mIsGeneric) {
  107. AString value;
  108. CHECK(GetAttribute(params.c_str(), "mode", &value));
  109. if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
  110. mSizeLength = 0;
  111. }
  112. if (!GetIntegerAttribute(
  113. params.c_str(), "indexLength", &mIndexLength)) {
  114. mIndexLength = 0;
  115. }
  116. if (!GetIntegerAttribute(
  117. params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
  118. mIndexDeltaLength = 0;
  119. }
  120. if (!GetIntegerAttribute(
  121. params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
  122. mCTSDeltaLength = 0;
  123. }
  124. if (!GetIntegerAttribute(
  125. params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
  126. mDTSDeltaLength = 0;
  127. }
  128. unsigned x;
  129. if (!GetIntegerAttribute(
  130. params.c_str(), "randomAccessIndication", &x)) {
  131. mRandomAccessIndication = false;
  132. } else {
  133. CHECK(x == 0 || x == 1);
  134. mRandomAccessIndication = (x != 0);
  135. }
  136. if (!GetIntegerAttribute(
  137. params.c_str(), "streamStateIndication",
  138. &mStreamStateIndication)) {
  139. mStreamStateIndication = 0;
  140. }
  141. if (!GetIntegerAttribute(
  142. params.c_str(), "auxiliaryDataSizeLength",
  143. &mAuxiliaryDataSizeLength)) {
  144. mAuxiliaryDataSizeLength = 0;
  145. }
  146. mHasAUHeader =
  147. mSizeLength > 0
  148. || mIndexLength > 0
  149. || mIndexDeltaLength > 0
  150. || mCTSDeltaLength > 0
  151. || mDTSDeltaLength > 0
  152. || mRandomAccessIndication
  153. || mStreamStateIndication > 0;
  154. int32_t sampleRate, numChannels;
  155. ASessionDescription::ParseFormatDesc(
  156. desc.c_str(), &sampleRate, &numChannels);
  157. mChannelConfig = numChannels;
  158. CHECK(GetSampleRateIndex(sampleRate, &mSampleRateIndex));
  159. }
  160. }
  161. AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
  162. }
  163. struct AUHeader {
  164. unsigned mSize;
  165. unsigned mSerial;
  166. };
  167. ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
  168. const sp<ARTPSource> &source) {
  169. List<sp<ABuffer> > *queue = source->queue();
  170. if (queue->empty()) {
  171. return NOT_ENOUGH_DATA;
  172. }
  173. if (mNextExpectedSeqNoValid) {
  174. List<sp<ABuffer> >::iterator it = queue->begin();
  175. while (it != queue->end()) {
  176. if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
  177. break;
  178. }
  179. it = queue->erase(it);
  180. }
  181. if (queue->empty()) {
  182. return NOT_ENOUGH_DATA;
  183. }
  184. }
  185. sp<ABuffer> buffer = *queue->begin();
  186. if (!mNextExpectedSeqNoValid) {
  187. mNextExpectedSeqNoValid = true;
  188. mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
  189. } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
  190. ALOGV("Not the sequence number I expected");
  191. return WRONG_SEQUENCE_NUMBER;
  192. }
  193. uint32_t rtpTime;
  194. CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
  195. if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
  196. submitAccessUnit();
  197. }
  198. mAccessUnitRTPTime = rtpTime;
  199. if (!mIsGeneric) {
  200. mPackets.push_back(buffer);
  201. } else {
  202. // hexdump(buffer->data(), buffer->size());
  203. if (buffer->size() < 2) {
  204. return MALFORMED_PACKET;
  205. }
  206. unsigned AU_headers_length = U16_AT(buffer->data()); // in bits
  207. if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
  208. return MALFORMED_PACKET;
  209. }
  210. List<AUHeader> headers;
  211. ABitReader bits(buffer->data() + 2, buffer->size() - 2);
  212. unsigned numBitsLeft = AU_headers_length;
  213. unsigned AU_serial = 0;
  214. for (;;) {
  215. if (numBitsLeft < mSizeLength) { break; }
  216. unsigned AU_size = bits.getBits(mSizeLength);
  217. numBitsLeft -= mSizeLength;
  218. size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
  219. if (numBitsLeft < n) { break; }
  220. unsigned AU_index = bits.getBits(n);
  221. numBitsLeft -= n;
  222. if (headers.empty()) {
  223. AU_serial = AU_index;
  224. } else {
  225. AU_serial += 1 + AU_index;
  226. }
  227. if (mCTSDeltaLength > 0) {
  228. if (numBitsLeft < 1) {
  229. break;
  230. }
  231. --numBitsLeft;
  232. if (bits.getBits(1)) {
  233. if (numBitsLeft < mCTSDeltaLength) {
  234. break;
  235. }
  236. bits.skipBits(mCTSDeltaLength);
  237. numBitsLeft -= mCTSDeltaLength;
  238. }
  239. }
  240. if (mDTSDeltaLength > 0) {
  241. if (numBitsLeft < 1) {
  242. break;
  243. }
  244. --numBitsLeft;
  245. if (bits.getBits(1)) {
  246. if (numBitsLeft < mDTSDeltaLength) {
  247. break;
  248. }
  249. bits.skipBits(mDTSDeltaLength);
  250. numBitsLeft -= mDTSDeltaLength;
  251. }
  252. }
  253. if (mRandomAccessIndication) {
  254. if (numBitsLeft < 1) {
  255. break;
  256. }
  257. bits.skipBits(1);
  258. --numBitsLeft;
  259. }
  260. if (mStreamStateIndication > 0) {
  261. if (numBitsLeft < mStreamStateIndication) {
  262. break;
  263. }
  264. bits.skipBits(mStreamStateIndication);
  265. }
  266. AUHeader header;
  267. header.mSize = AU_size;
  268. header.mSerial = AU_serial;
  269. headers.push_back(header);
  270. }
  271. size_t offset = 2 + (AU_headers_length + 7) / 8;
  272. if (mAuxiliaryDataSizeLength > 0) {
  273. ABitReader bits(buffer->data() + offset, buffer->size() - offset);
  274. unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
  275. offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
  276. }
  277. for (List<AUHeader>::iterator it = headers.begin();
  278. it != headers.end(); ++it) {
  279. const AUHeader &header = *it;
  280. if (buffer->size() < offset + header.mSize) {
  281. return MALFORMED_PACKET;
  282. }
  283. sp<ABuffer> accessUnit = new ABuffer(header.mSize);
  284. memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
  285. offset += header.mSize;
  286. CopyTimes(accessUnit, buffer);
  287. mPackets.push_back(accessUnit);
  288. }
  289. if (offset != buffer->size()) {
  290. ALOGW("potentially malformed packet (offset %zu, size %zu)",
  291. offset, buffer->size());
  292. }
  293. }
  294. queue->erase(queue->begin());
  295. ++mNextExpectedSeqNo;
  296. return OK;
  297. }
  298. void AMPEG4ElementaryAssembler::submitAccessUnit() {
  299. CHECK(!mPackets.empty());
  300. ALOGV("Access unit complete (%zu nal units)", mPackets.size());
  301. sp<ABuffer> accessUnit;
  302. if (mIsGeneric) {
  303. accessUnit = MakeADTSCompoundFromAACFrames(
  304. OMX_AUDIO_AACObjectLC - 1,
  305. mSampleRateIndex,
  306. mChannelConfig,
  307. mPackets);
  308. } else {
  309. accessUnit = MakeCompoundFromPackets(mPackets);
  310. }
  311. #if 0
  312. printf(mAccessUnitDamaged ? "X" : ".");
  313. fflush(stdout);
  314. #endif
  315. if (mAccessUnitDamaged) {
  316. accessUnit->meta()->setInt32("damaged", true);
  317. }
  318. mPackets.clear();
  319. mAccessUnitDamaged = false;
  320. sp<AMessage> msg = mNotifyMsg->dup();
  321. msg->setBuffer("access-unit", accessUnit);
  322. msg->post();
  323. }
  324. ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::assembleMore(
  325. const sp<ARTPSource> &source) {
  326. AssemblyStatus status = addPacket(source);
  327. if (status == MALFORMED_PACKET) {
  328. ALOGI("access unit is damaged");
  329. mAccessUnitDamaged = true;
  330. }
  331. return status;
  332. }
  333. void AMPEG4ElementaryAssembler::packetLost() {
  334. CHECK(mNextExpectedSeqNoValid);
  335. ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
  336. ++mNextExpectedSeqNo;
  337. mAccessUnitDamaged = true;
  338. }
  339. void AMPEG4ElementaryAssembler::onByeReceived() {
  340. sp<AMessage> msg = mNotifyMsg->dup();
  341. msg->setInt32("eos", true);
  342. msg->post();
  343. }
  344. } // namespace android