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> &notify, const sp<MetaData> &params);
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> &notify, const sp<MetaData> &params) {
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