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
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "MPEG2TSWriter"
19
20 #include <media/MediaSource.h>
21 #include <media/stagefright/foundation/ADebug.h>
22 #include <media/stagefright/foundation/hexdump.h>
23 #include <media/stagefright/foundation/ABuffer.h>
24 #include <media/stagefright/foundation/AMessage.h>
25 #include <media/stagefright/foundation/ByteUtils.h>
26 #include <media/stagefright/MPEG2TSWriter.h>
27 #include <media/stagefright/MediaBuffer.h>
28 #include <media/stagefright/MediaDefs.h>
29 #include <media/stagefright/MediaErrors.h>
30 #include <media/stagefright/MetaData.h>
31 #include <arpa/inet.h>
32
33 #include "include/ESDS.h"
34
35 namespace android {
36
37 struct MPEG2TSWriter::SourceInfo : public AHandler {
38 explicit SourceInfo(const sp<MediaSource> &source);
39
40 void start(const sp<AMessage> ¬ify, const sp<MetaData> ¶ms);
41 void stop();
42
43 unsigned streamType() const;
44 unsigned incrementContinuityCounter();
45
46 void readMore();
47
48 enum {
49 kNotifyStartFailed,
50 kNotifyBuffer,
51 kNotifyReachedEOS,
52 };
53
54 sp<ABuffer> lastAccessUnit();
55 int64_t lastAccessUnitTimeUs();
56 void setLastAccessUnit(const sp<ABuffer> &accessUnit);
57
58 void setEOSReceived();
59 bool eosReceived() const;
60
61 protected:
62 virtual void onMessageReceived(const sp<AMessage> &msg);
63
64 virtual ~SourceInfo();
65
66 private:
67 enum {
68 kWhatStart = 'strt',
69 kWhatRead = 'read',
70 };
71
72 sp<MediaSource> mSource;
73 sp<ALooper> mLooper;
74 sp<AMessage> mNotify;
75
76 sp<ABuffer> mAACCodecSpecificData;
77
78 sp<ABuffer> mBuffer;
79
80 sp<ABuffer> mLastAccessUnit;
81 bool mEOSReceived;
82
83 unsigned mStreamType;
84 unsigned mContinuityCounter;
85
86 void extractCodecSpecificData();
87
88 void appendAACFrames(MediaBufferBase *buffer);
89 void appendAVCFrame(MediaBufferBase *buffer);
90
91 DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
92 };
93
SourceInfo(const sp<MediaSource> & source)94 MPEG2TSWriter::SourceInfo::SourceInfo(const sp<MediaSource> &source)
95 : mSource(source),
96 mLooper(new ALooper),
97 mEOSReceived(false),
98 mStreamType(0),
99 mContinuityCounter(0) {
100 mLooper->setName("MPEG2TSWriter source");
101
102 sp<MetaData> meta = mSource->getFormat();
103 const char *mime;
104 CHECK(meta->findCString(kKeyMIMEType, &mime));
105
106 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
107 mStreamType = 0x0f;
108 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
109 mStreamType = 0x1b;
110 } else {
111 TRESPASS();
112 }
113 }
114
~SourceInfo()115 MPEG2TSWriter::SourceInfo::~SourceInfo() {
116 }
117
streamType() const118 unsigned MPEG2TSWriter::SourceInfo::streamType() const {
119 return mStreamType;
120 }
121
incrementContinuityCounter()122 unsigned MPEG2TSWriter::SourceInfo::incrementContinuityCounter() {
123 if (++mContinuityCounter == 16) {
124 mContinuityCounter = 0;
125 }
126
127 return mContinuityCounter;
128 }
129
start(const sp<AMessage> & notify,const sp<MetaData> & params)130 void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> ¬ify, const sp<MetaData> ¶ms) {
131 mLooper->registerHandler(this);
132 mLooper->start();
133 mNotify = notify;
134
135 sp<AMessage> msg = new AMessage(kWhatStart, this);
136 msg->setObject("meta", params);
137 msg->post();
138 }
139
stop()140 void MPEG2TSWriter::SourceInfo::stop() {
141 mLooper->unregisterHandler(id());
142 mLooper->stop();
143
144 mSource->stop();
145 }
146
extractCodecSpecificData()147 void MPEG2TSWriter::SourceInfo::extractCodecSpecificData() {
148 sp<MetaData> meta = mSource->getFormat();
149
150 const char *mime;
151 CHECK(meta->findCString(kKeyMIMEType, &mime));
152
153 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
154 uint32_t type;
155 const void *data;
156 size_t size;
157 if (!meta->findData(kKeyESDS, &type, &data, &size)) {
158 // Codec specific data better be in the first data buffer.
159 return;
160 }
161
162 ESDS esds((const char *)data, size);
163 CHECK_EQ(esds.InitCheck(), (status_t)OK);
164
165 const uint8_t *codec_specific_data;
166 size_t codec_specific_data_size;
167 esds.getCodecSpecificInfo(
168 (const void **)&codec_specific_data, &codec_specific_data_size);
169
170 CHECK_GE(codec_specific_data_size, 2u);
171
172 mAACCodecSpecificData = new ABuffer(codec_specific_data_size);
173
174 memcpy(mAACCodecSpecificData->data(), codec_specific_data,
175 codec_specific_data_size);
176
177 return;
178 }
179
180 if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
181 return;
182 }
183
184 uint32_t type;
185 const void *data;
186 size_t size;
187 if (!meta->findData(kKeyAVCC, &type, &data, &size)) {
188 // Codec specific data better be part of the data stream then.
189 return;
190 }
191
192 sp<ABuffer> out = new ABuffer(1024);
193 out->setRange(0, 0);
194
195 const uint8_t *ptr = (const uint8_t *)data;
196
197 size_t numSeqParameterSets = ptr[5] & 31;
198
199 ptr += 6;
200 size -= 6;
201
202 for (size_t i = 0; i < numSeqParameterSets; ++i) {
203 CHECK(size >= 2);
204 size_t length = U16_AT(ptr);
205
206 ptr += 2;
207 size -= 2;
208
209 CHECK(size >= length);
210
211 CHECK_LE(out->size() + 4 + length, out->capacity());
212 memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
213 memcpy(out->data() + out->size() + 4, ptr, length);
214 out->setRange(0, out->size() + length + 4);
215
216 ptr += length;
217 size -= length;
218 }
219
220 CHECK(size >= 1);
221 size_t numPictureParameterSets = *ptr;
222 ++ptr;
223 --size;
224
225 for (size_t i = 0; i < numPictureParameterSets; ++i) {
226 CHECK(size >= 2);
227 size_t length = U16_AT(ptr);
228
229 ptr += 2;
230 size -= 2;
231
232 CHECK(size >= length);
233
234 CHECK_LE(out->size() + 4 + length, out->capacity());
235 memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
236 memcpy(out->data() + out->size() + 4, ptr, length);
237 out->setRange(0, out->size() + length + 4);
238
239 ptr += length;
240 size -= length;
241 }
242
243 out->meta()->setInt64("timeUs", 0LL);
244
245 sp<AMessage> notify = mNotify->dup();
246 notify->setInt32("what", kNotifyBuffer);
247 notify->setBuffer("buffer", out);
248 notify->setInt32("oob", true);
249 notify->post();
250 }
251
appendAVCFrame(MediaBufferBase * buffer)252 void MPEG2TSWriter::SourceInfo::appendAVCFrame(MediaBufferBase *buffer) {
253 sp<AMessage> notify = mNotify->dup();
254 notify->setInt32("what", kNotifyBuffer);
255
256 if (mBuffer == NULL || buffer->range_length() > mBuffer->capacity()) {
257 mBuffer = new ABuffer(buffer->range_length());
258 }
259 mBuffer->setRange(0, 0);
260
261 memcpy(mBuffer->data(),
262 (const uint8_t *)buffer->data()
263 + buffer->range_offset(),
264 buffer->range_length());
265
266 int64_t timeUs;
267 CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs));
268 mBuffer->meta()->setInt64("timeUs", timeUs);
269
270 int32_t isSync;
271 if (buffer->meta_data().findInt32(kKeyIsSyncFrame, &isSync)
272 && isSync != 0) {
273 mBuffer->meta()->setInt32("isSync", true);
274 }
275
276 mBuffer->setRange(0, buffer->range_length());
277
278 notify->setBuffer("buffer", mBuffer);
279 notify->post();
280 }
281
appendAACFrames(MediaBufferBase * buffer)282 void MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBufferBase *buffer) {
283 sp<AMessage> notify = mNotify->dup();
284 notify->setInt32("what", kNotifyBuffer);
285
286 if (mBuffer == NULL || 7 + buffer->range_length() > mBuffer->capacity()) {
287 mBuffer = new ABuffer(7 + buffer->range_length());
288 }
289
290 int64_t timeUs;
291 CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs));
292
293 mBuffer->meta()->setInt64("timeUs", timeUs);
294 mBuffer->meta()->setInt32("isSync", true);
295
296 mBuffer->setRange(0, 0);
297
298 const uint8_t *codec_specific_data = mAACCodecSpecificData->data();
299
300 unsigned profile = (codec_specific_data[0] >> 3) - 1;
301
302 unsigned sampling_freq_index =
303 ((codec_specific_data[0] & 7) << 1)
304 | (codec_specific_data[1] >> 7);
305
306 unsigned channel_configuration =
307 (codec_specific_data[1] >> 3) & 0x0f;
308
309 uint8_t *ptr = mBuffer->data() + mBuffer->size();
310
311 const uint32_t aac_frame_length = buffer->range_length() + 7;
312
313 *ptr++ = 0xff;
314 *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1
315
316 *ptr++ =
317 profile << 6
318 | sampling_freq_index << 2
319 | ((channel_configuration >> 2) & 1); // private_bit=0
320
321 // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0
322 *ptr++ =
323 (channel_configuration & 3) << 6
324 | aac_frame_length >> 11;
325 *ptr++ = (aac_frame_length >> 3) & 0xff;
326 *ptr++ = (aac_frame_length & 7) << 5;
327
328 // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0
329 *ptr++ = 0;
330
331 memcpy(ptr,
332 (const uint8_t *)buffer->data() + buffer->range_offset(),
333 buffer->range_length());
334
335 ptr += buffer->range_length();
336
337 mBuffer->setRange(0, ptr - mBuffer->data());
338
339 notify->setBuffer("buffer", mBuffer);
340 notify->post();
341 }
342
readMore()343 void MPEG2TSWriter::SourceInfo::readMore() {
344 (new AMessage(kWhatRead, this))->post();
345 }
346
onMessageReceived(const sp<AMessage> & msg)347 void MPEG2TSWriter::SourceInfo::onMessageReceived(const sp<AMessage> &msg) {
348 switch (msg->what()) {
349 case kWhatStart:
350 {
351 sp<RefBase> obj;
352 CHECK(msg->findObject("meta", &obj));
353 MetaData *params = static_cast<MetaData *>(obj.get());
354 status_t err = mSource->start(params);
355 if (err != OK) {
356 sp<AMessage> notify = mNotify->dup();
357 notify->setInt32("what", kNotifyStartFailed);
358 notify->post();
359 break;
360 }
361
362 // Extract CSD from config format.
363 extractCodecSpecificData();
364
365 readMore();
366 break;
367 }
368
369 case kWhatRead:
370 {
371 MediaBufferBase *buffer;
372 status_t err = mSource->read(&buffer);
373
374 if (err != OK && err != INFO_FORMAT_CHANGED) {
375 sp<AMessage> notify = mNotify->dup();
376 notify->setInt32("what", kNotifyReachedEOS);
377 notify->setInt32("status", err);
378 notify->post();
379 break;
380 }
381
382 if (err == OK) {
383 if (mStreamType == 0x0f && mAACCodecSpecificData == NULL) {
384 // The first audio buffer must contain CSD if not received yet.
385 CHECK_GE(buffer->range_length(), 2u);
386 mAACCodecSpecificData = new ABuffer(buffer->range_length());
387
388 memcpy(mAACCodecSpecificData->data(),
389 (const uint8_t *)buffer->data()
390 + buffer->range_offset(),
391 buffer->range_length());
392 readMore();
393 } else if (buffer->range_length() > 0) {
394 if (mStreamType == 0x0f) {
395 appendAACFrames(buffer);
396 } else {
397 appendAVCFrame(buffer);
398 }
399 } else {
400 readMore();
401 }
402
403 buffer->release();
404 buffer = NULL;
405 }
406
407 // Do not read more data until told to.
408 break;
409 }
410
411 default:
412 TRESPASS();
413 }
414 }
415
lastAccessUnit()416 sp<ABuffer> MPEG2TSWriter::SourceInfo::lastAccessUnit() {
417 return mLastAccessUnit;
418 }
419
setLastAccessUnit(const sp<ABuffer> & accessUnit)420 void MPEG2TSWriter::SourceInfo::setLastAccessUnit(
421 const sp<ABuffer> &accessUnit) {
422 mLastAccessUnit = accessUnit;
423 }
424
lastAccessUnitTimeUs()425 int64_t MPEG2TSWriter::SourceInfo::lastAccessUnitTimeUs() {
426 if (mLastAccessUnit == NULL) {
427 return -1;
428 }
429
430 int64_t timeUs;
431 CHECK(mLastAccessUnit->meta()->findInt64("timeUs", &timeUs));
432 return timeUs;
433 }
434
setEOSReceived()435 void MPEG2TSWriter::SourceInfo::setEOSReceived() {
436 CHECK(!mEOSReceived);
437 mEOSReceived = true;
438 }
439
eosReceived() const440 bool MPEG2TSWriter::SourceInfo::eosReceived() const {
441 return mEOSReceived;
442 }
443
444 ////////////////////////////////////////////////////////////////////////////////
445
MPEG2TSWriter(int fd)446 MPEG2TSWriter::MPEG2TSWriter(int fd)
447 : mFile(fdopen(dup(fd), "wb")),
448 mWriteCookie(NULL),
449 mWriteFunc(NULL),
450 mStarted(false),
451 mNumSourcesDone(0),
452 mNumTSPacketsWritten(0),
453 mNumTSPacketsBeforeMeta(0),
454 mPATContinuityCounter(0),
455 mPMTContinuityCounter(0) {
456 init();
457 }
458
MPEG2TSWriter(void * cookie,ssize_t (* write)(void * cookie,const void * data,size_t size))459 MPEG2TSWriter::MPEG2TSWriter(
460 void *cookie,
461 ssize_t (*write)(void *cookie, const void *data, size_t size))
462 : mFile(NULL),
463 mWriteCookie(cookie),
464 mWriteFunc(write),
465 mStarted(false),
466 mNumSourcesDone(0),
467 mNumTSPacketsWritten(0),
468 mNumTSPacketsBeforeMeta(0),
469 mPATContinuityCounter(0),
470 mPMTContinuityCounter(0) {
471 init();
472 }
473
init()474 void MPEG2TSWriter::init() {
475 CHECK(mFile != NULL || mWriteFunc != NULL);
476
477 initCrcTable();
478
479 mLooper = new ALooper;
480 mLooper->setName("MPEG2TSWriter");
481
482 mReflector = new AHandlerReflector<MPEG2TSWriter>(this);
483
484 mLooper->registerHandler(mReflector);
485 mLooper->start();
486 }
487
~MPEG2TSWriter()488 MPEG2TSWriter::~MPEG2TSWriter() {
489 if (mStarted) {
490 reset();
491 }
492
493 mLooper->unregisterHandler(mReflector->id());
494 mLooper->stop();
495
496 if (mFile != NULL) {
497 fclose(mFile);
498 mFile = NULL;
499 }
500 }
501
addSource(const sp<MediaSource> & source)502 status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
503 CHECK(!mStarted);
504
505 sp<MetaData> meta = source->getFormat();
506 const char *mime;
507 CHECK(meta->findCString(kKeyMIMEType, &mime));
508
509 if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
510 && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
511 return ERROR_UNSUPPORTED;
512 }
513
514 sp<SourceInfo> info = new SourceInfo(source);
515
516 mSources.push(info);
517
518 return OK;
519 }
520
start(MetaData * param)521 status_t MPEG2TSWriter::start(MetaData *param ) {
522 CHECK(!mStarted);
523
524 mStarted = true;
525 mNumSourcesDone = 0;
526 mNumTSPacketsWritten = 0;
527 mNumTSPacketsBeforeMeta = 0;
528
529 for (size_t i = 0; i < mSources.size(); ++i) {
530 sp<AMessage> notify =
531 new AMessage(kWhatSourceNotify, mReflector);
532
533 notify->setInt32("source-index", i);
534
535 mSources.editItemAt(i)->start(notify, param);
536 }
537
538 return OK;
539 }
540
reset()541 status_t MPEG2TSWriter::reset() {
542 CHECK(mStarted);
543
544 for (size_t i = 0; i < mSources.size(); ++i) {
545 mSources.editItemAt(i)->stop();
546 }
547 mStarted = false;
548
549 return OK;
550 }
551
pause()552 status_t MPEG2TSWriter::pause() {
553 CHECK(mStarted);
554
555 return OK;
556 }
557
reachedEOS()558 bool MPEG2TSWriter::reachedEOS() {
559 return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
560 }
561
dump(int,const Vector<String16> &)562 status_t MPEG2TSWriter::dump(
563 int /* fd */, const Vector<String16> & /* args */) {
564 return OK;
565 }
566
onMessageReceived(const sp<AMessage> & msg)567 void MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
568 switch (msg->what()) {
569 case kWhatSourceNotify:
570 {
571 int32_t sourceIndex;
572 CHECK(msg->findInt32("source-index", &sourceIndex));
573 sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
574
575 int32_t what;
576 CHECK(msg->findInt32("what", &what));
577
578 if (what == SourceInfo::kNotifyReachedEOS
579 || what == SourceInfo::kNotifyStartFailed) {
580 source->setEOSReceived();
581
582 sp<ABuffer> buffer = source->lastAccessUnit();
583 source->setLastAccessUnit(NULL);
584
585 if (buffer != NULL) {
586 writeTS();
587 writeAccessUnit(sourceIndex, buffer);
588 }
589
590 ++mNumSourcesDone;
591 } else if (what == SourceInfo::kNotifyBuffer) {
592 sp<ABuffer> buffer;
593 CHECK(msg->findBuffer("buffer", &buffer));
594 CHECK(source->lastAccessUnit() == NULL);
595
596 int32_t oob;
597 if (msg->findInt32("oob", &oob) && oob) {
598 // This is codec specific data delivered out of band.
599 // It can be written out immediately.
600 writeTS();
601 writeAccessUnit(sourceIndex, buffer);
602 break;
603 }
604
605 // We don't just write out data as we receive it from
606 // the various sources. That would essentially write them
607 // out in random order (as the thread scheduler determines
608 // how the messages are dispatched).
609 // Instead we gather an access unit for all tracks and
610 // write out the one with the smallest timestamp, then
611 // request more data for the written out track.
612 // Rinse, repeat.
613 // If we don't have data on any track we don't write
614 // anything just yet.
615 source->setLastAccessUnit(buffer);
616
617 ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
618 sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
619 int64_t minTimeUs = -1;
620 size_t minIndex = 0;
621
622 for (size_t i = 0; i < mSources.size(); ++i) {
623 const sp<SourceInfo> &source = mSources.editItemAt(i);
624
625 if (source->eosReceived()) {
626 continue;
627 }
628
629 int64_t timeUs = source->lastAccessUnitTimeUs();
630 if (timeUs < 0) {
631 minTimeUs = -1;
632 break;
633 } else if (minTimeUs < 0 || timeUs < minTimeUs) {
634 minTimeUs = timeUs;
635 minIndex = i;
636 }
637 }
638
639 if (minTimeUs < 0) {
640 ALOGV("not all tracks have valid data.");
641 break;
642 }
643
644 ALOGV("writing access unit at time %.2f secs (index %zu)",
645 minTimeUs / 1E6, minIndex);
646
647 source = mSources.editItemAt(minIndex);
648 buffer = source->lastAccessUnit();
649 source->setLastAccessUnit(NULL);
650
651 writeTS();
652 writeAccessUnit(minIndex, buffer);
653
654 source->readMore();
655 }
656 break;
657 }
658
659 default:
660 TRESPASS();
661 }
662 }
663
writeProgramAssociationTable()664 void MPEG2TSWriter::writeProgramAssociationTable() {
665 // 0x47
666 // transport_error_indicator = b0
667 // payload_unit_start_indicator = b1
668 // transport_priority = b0
669 // PID = b0000000000000 (13 bits)
670 // transport_scrambling_control = b00
671 // adaptation_field_control = b01 (no adaptation field, payload only)
672 // continuity_counter = b????
673 // skip = 0x00
674 // --- payload follows
675 // table_id = 0x00
676 // section_syntax_indicator = b1
677 // must_be_zero = b0
678 // reserved = b11
679 // section_length = 0x00d
680 // transport_stream_id = 0x0000
681 // reserved = b11
682 // version_number = b00001
683 // current_next_indicator = b1
684 // section_number = 0x00
685 // last_section_number = 0x00
686 // one program follows:
687 // program_number = 0x0001
688 // reserved = b111
689 // program_map_PID = 0x01e0 (13 bits!)
690 // CRC = 0x????????
691
692 static const uint8_t kData[] = {
693 0x47,
694 0x40, 0x00, 0x10, 0x00, // b0100 0000 0000 0000 0001 ???? 0000 0000
695 0x00, 0xb0, 0x0d, 0x00, // b0000 0000 1011 0000 0000 1101 0000 0000
696 0x00, 0xc3, 0x00, 0x00, // b0000 0000 1100 0011 0000 0000 0000 0000
697 0x00, 0x01, 0xe1, 0xe0, // b0000 0000 0000 0001 1110 0001 1110 0000
698 0x00, 0x00, 0x00, 0x00 // b???? ???? ???? ???? ???? ???? ???? ????
699 };
700
701 sp<ABuffer> buffer = new ABuffer(188);
702 memset(buffer->data(), 0xff, buffer->size());
703 memcpy(buffer->data(), kData, sizeof(kData));
704
705 if (++mPATContinuityCounter == 16) {
706 mPATContinuityCounter = 0;
707 }
708 buffer->data()[3] |= mPATContinuityCounter;
709
710 uint32_t crc = htonl(crc32(&buffer->data()[5], 12));
711 memcpy(&buffer->data()[17], &crc, sizeof(crc));
712
713 CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
714 }
715
writeProgramMap()716 void MPEG2TSWriter::writeProgramMap() {
717 // 0x47
718 // transport_error_indicator = b0
719 // payload_unit_start_indicator = b1
720 // transport_priority = b0
721 // PID = b0 0001 1110 0000 (13 bits) [0x1e0]
722 // transport_scrambling_control = b00
723 // adaptation_field_control = b01 (no adaptation field, payload only)
724 // continuity_counter = b????
725 // skip = 0x00
726 // -- payload follows
727 // table_id = 0x02
728 // section_syntax_indicator = b1
729 // must_be_zero = b0
730 // reserved = b11
731 // section_length = 0x???
732 // program_number = 0x0001
733 // reserved = b11
734 // version_number = b00001
735 // current_next_indicator = b1
736 // section_number = 0x00
737 // last_section_number = 0x00
738 // reserved = b111
739 // PCR_PID = b? ???? ???? ???? (13 bits)
740 // reserved = b1111
741 // program_info_length = 0x000
742 // one or more elementary stream descriptions follow:
743 // stream_type = 0x??
744 // reserved = b111
745 // elementary_PID = b? ???? ???? ???? (13 bits)
746 // reserved = b1111
747 // ES_info_length = 0x000
748 // CRC = 0x????????
749
750 static const uint8_t kData[] = {
751 0x47,
752 0x41, 0xe0, 0x10, 0x00, // b0100 0001 1110 0000 0001 ???? 0000 0000
753 0x02, 0xb0, 0x00, 0x00, // b0000 0010 1011 ???? ???? ???? 0000 0000
754 0x01, 0xc3, 0x00, 0x00, // b0000 0001 1100 0011 0000 0000 0000 0000
755 0xe0, 0x00, 0xf0, 0x00 // b111? ???? ???? ???? 1111 0000 0000 0000
756 };
757
758 sp<ABuffer> buffer = new ABuffer(188);
759 memset(buffer->data(), 0xff, buffer->size());
760 memcpy(buffer->data(), kData, sizeof(kData));
761
762 if (++mPMTContinuityCounter == 16) {
763 mPMTContinuityCounter = 0;
764 }
765 buffer->data()[3] |= mPMTContinuityCounter;
766
767 size_t section_length = 5 * mSources.size() + 4 + 9;
768 buffer->data()[6] |= section_length >> 8;
769 buffer->data()[7] = section_length & 0xff;
770
771 static const unsigned kPCR_PID = 0x1e1;
772 buffer->data()[13] |= (kPCR_PID >> 8) & 0x1f;
773 buffer->data()[14] = kPCR_PID & 0xff;
774
775 uint8_t *ptr = &buffer->data()[sizeof(kData)];
776 for (size_t i = 0; i < mSources.size(); ++i) {
777 *ptr++ = mSources.editItemAt(i)->streamType();
778
779 const unsigned ES_PID = 0x1e0 + i + 1;
780 *ptr++ = 0xe0 | (ES_PID >> 8);
781 *ptr++ = ES_PID & 0xff;
782 *ptr++ = 0xf0;
783 *ptr++ = 0x00;
784 }
785
786 uint32_t crc = htonl(crc32(&buffer->data()[5], 12+mSources.size()*5));
787 memcpy(&buffer->data()[17+mSources.size()*5], &crc, sizeof(crc));
788
789 CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
790 }
791
writeAccessUnit(int32_t sourceIndex,const sp<ABuffer> & accessUnit)792 void MPEG2TSWriter::writeAccessUnit(
793 int32_t sourceIndex, const sp<ABuffer> &accessUnit) {
794 // 0x47
795 // transport_error_indicator = b0
796 // payload_unit_start_indicator = b1
797 // transport_priority = b0
798 // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
799 // transport_scrambling_control = b00
800 // adaptation_field_control = b??
801 // continuity_counter = b????
802 // -- payload follows
803 // packet_startcode_prefix = 0x000001
804 // stream_id = 0x?? (0xe0 for avc video, 0xc0 for aac audio)
805 // PES_packet_length = 0x????
806 // reserved = b10
807 // PES_scrambling_control = b00
808 // PES_priority = b0
809 // data_alignment_indicator = b1
810 // copyright = b0
811 // original_or_copy = b0
812 // PTS_DTS_flags = b10 (PTS only)
813 // ESCR_flag = b0
814 // ES_rate_flag = b0
815 // DSM_trick_mode_flag = b0
816 // additional_copy_info_flag = b0
817 // PES_CRC_flag = b0
818 // PES_extension_flag = b0
819 // PES_header_data_length = 0x05
820 // reserved = b0010 (PTS)
821 // PTS[32..30] = b???
822 // reserved = b1
823 // PTS[29..15] = b??? ???? ???? ???? (15 bits)
824 // reserved = b1
825 // PTS[14..0] = b??? ???? ???? ???? (15 bits)
826 // reserved = b1
827 // the first fragment of "buffer" follows
828
829 sp<ABuffer> buffer = new ABuffer(188);
830 memset(buffer->data(), 0xff, buffer->size());
831
832 const unsigned PID = 0x1e0 + sourceIndex + 1;
833
834 const unsigned continuity_counter =
835 mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
836
837 // XXX if there are multiple streams of a kind (more than 1 audio or
838 // more than 1 video) they need distinct stream_ids.
839 const unsigned stream_id =
840 mSources.editItemAt(sourceIndex)->streamType() == 0x0f ? 0xc0 : 0xe0;
841
842 int64_t timeUs;
843 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
844
845 uint32_t PTS = (timeUs * 9LL) / 100LL;
846
847 size_t PES_packet_length = accessUnit->size() + 8;
848 bool padding = (accessUnit->size() < (188 - 18));
849
850 if (PES_packet_length >= 65536) {
851 // This really should only happen for video.
852 CHECK_EQ(stream_id, 0xe0u);
853
854 // It's valid to set this to 0 for video according to the specs.
855 PES_packet_length = 0;
856 }
857
858 uint8_t *ptr = buffer->data();
859 *ptr++ = 0x47;
860 *ptr++ = 0x40 | (PID >> 8);
861 *ptr++ = PID & 0xff;
862 *ptr++ = (padding ? 0x30 : 0x10) | continuity_counter;
863 if (padding) {
864 int paddingSize = 188 - accessUnit->size() - 18;
865 *ptr++ = paddingSize - 1;
866 if (paddingSize >= 2) {
867 *ptr++ = 0x00;
868 ptr += paddingSize - 2;
869 }
870 }
871 *ptr++ = 0x00;
872 *ptr++ = 0x00;
873 *ptr++ = 0x01;
874 *ptr++ = stream_id;
875 *ptr++ = PES_packet_length >> 8;
876 *ptr++ = PES_packet_length & 0xff;
877 *ptr++ = 0x84;
878 *ptr++ = 0x80;
879 *ptr++ = 0x05;
880 *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
881 *ptr++ = (PTS >> 22) & 0xff;
882 *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
883 *ptr++ = (PTS >> 7) & 0xff;
884 *ptr++ = ((PTS & 0x7f) << 1) | 1;
885
886 size_t sizeLeft = buffer->data() + buffer->size() - ptr;
887 size_t copy = accessUnit->size();
888 if (copy > sizeLeft) {
889 copy = sizeLeft;
890 }
891
892 memcpy(ptr, accessUnit->data(), copy);
893
894 CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
895
896 size_t offset = copy;
897 while (offset < accessUnit->size()) {
898 bool lastAccessUnit = ((accessUnit->size() - offset) < 184);
899 // for subsequent fragments of "buffer":
900 // 0x47
901 // transport_error_indicator = b0
902 // payload_unit_start_indicator = b0
903 // transport_priority = b0
904 // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
905 // transport_scrambling_control = b00
906 // adaptation_field_control = b??
907 // continuity_counter = b????
908 // the fragment of "buffer" follows.
909
910 memset(buffer->data(), 0xff, buffer->size());
911
912 const unsigned continuity_counter =
913 mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
914
915 ptr = buffer->data();
916 *ptr++ = 0x47;
917 *ptr++ = 0x00 | (PID >> 8);
918 *ptr++ = PID & 0xff;
919 *ptr++ = (lastAccessUnit ? 0x30 : 0x10) | continuity_counter;
920
921 if (lastAccessUnit) {
922 // Pad packet using an adaptation field
923 // Adaptation header all to 0 execpt size
924 uint8_t paddingSize = (uint8_t)184 - (accessUnit->size() - offset);
925 *ptr++ = paddingSize - 1;
926 if (paddingSize >= 2) {
927 *ptr++ = 0x00;
928 ptr += paddingSize - 2;
929 }
930 }
931
932 size_t sizeLeft = buffer->data() + buffer->size() - ptr;
933 size_t copy = accessUnit->size() - offset;
934 if (copy > sizeLeft) {
935 copy = sizeLeft;
936 }
937
938 memcpy(ptr, accessUnit->data() + offset, copy);
939 CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
940 (ssize_t)buffer->size());
941
942 offset += copy;
943 }
944 }
945
writeTS()946 void MPEG2TSWriter::writeTS() {
947 if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
948 writeProgramAssociationTable();
949 writeProgramMap();
950
951 mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
952 }
953 }
954
initCrcTable()955 void MPEG2TSWriter::initCrcTable() {
956 uint32_t poly = 0x04C11DB7;
957
958 for (int i = 0; i < 256; i++) {
959 uint32_t crc = i << 24;
960 for (int j = 0; j < 8; j++) {
961 crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
962 }
963 mCrcTable[i] = crc;
964 }
965 }
966
967 /**
968 * Compute CRC32 checksum for buffer starting at offset start and for length
969 * bytes.
970 */
crc32(const uint8_t * p_start,size_t length)971 uint32_t MPEG2TSWriter::crc32(const uint8_t *p_start, size_t length) {
972 uint32_t crc = 0xFFFFFFFF;
973 const uint8_t *p;
974
975 for (p = p_start; p < p_start + length; p++) {
976 crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
977 }
978
979 return crc;
980 }
981
internalWrite(const void * data,size_t size)982 ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
983 if (mFile != NULL) {
984 return fwrite(data, 1, size, mFile);
985 }
986
987 return (*mWriteFunc)(mWriteCookie, data, size);
988 }
989
990 } // namespace android
991
992