blob: 53b7187b8067cb98420ab2c1cbe131d436cfef52 [file] [log] [blame]
Andreas Huberd7bee3a2012-08-29 11:41:50 -07001/*
2 * Copyright 2012, 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 "TSPacketizer"
19#include <utils/Log.h>
20
21#include "TSPacketizer.h"
22#include "include/avc_utils.h"
23
24#include <media/stagefright/foundation/ABuffer.h>
25#include <media/stagefright/foundation/ADebug.h>
26#include <media/stagefright/foundation/AMessage.h>
27#include <media/stagefright/foundation/hexdump.h>
28#include <media/stagefright/MediaDefs.h>
29#include <media/stagefright/MediaErrors.h>
30
31#include <arpa/inet.h>
32
33namespace android {
34
35struct TSPacketizer::Track : public RefBase {
36 Track(const sp<AMessage> &format,
37 unsigned PID, unsigned streamType, unsigned streamID);
38
39 unsigned PID() const;
40 unsigned streamType() const;
41 unsigned streamID() const;
42
43 // Returns the previous value.
44 unsigned incrementContinuityCounter();
45
46 bool isAudio() const;
47 bool isVideo() const;
48
49 bool isH264() const;
Andreas Hubere7bd24a2012-10-04 11:46:29 -070050 bool isAAC() const;
Andreas Huberd7bee3a2012-08-29 11:41:50 -070051 bool lacksADTSHeader() const;
Andreas Huber90a92052012-10-30 15:53:03 -070052 bool isPCMAudio() const;
Andreas Huberd7bee3a2012-08-29 11:41:50 -070053
54 sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const;
55 sp<ABuffer> prependADTSHeader(const sp<ABuffer> &accessUnit) const;
56
Andreas Huber90a92052012-10-30 15:53:03 -070057 size_t countDescriptors() const;
58 sp<ABuffer> descriptorAt(size_t index) const;
59
60 void finalize();
Andreas Hubera556c482013-03-05 10:56:27 -080061 void extractCSDIfNecessary();
Andreas Huber90a92052012-10-30 15:53:03 -070062
Andreas Huberd7bee3a2012-08-29 11:41:50 -070063protected:
64 virtual ~Track();
65
66private:
67 sp<AMessage> mFormat;
68
69 unsigned mPID;
70 unsigned mStreamType;
71 unsigned mStreamID;
72 unsigned mContinuityCounter;
73
74 AString mMIME;
75 Vector<sp<ABuffer> > mCSD;
76
Andreas Huber90a92052012-10-30 15:53:03 -070077 Vector<sp<ABuffer> > mDescriptors;
78
Andreas Huberb8c7bd42012-09-18 14:47:48 -070079 bool mAudioLacksATDSHeaders;
Andreas Huber90a92052012-10-30 15:53:03 -070080 bool mFinalized;
Andreas Hubera556c482013-03-05 10:56:27 -080081 bool mExtractedCSD;
Andreas Huberb8c7bd42012-09-18 14:47:48 -070082
Andreas Huberd7bee3a2012-08-29 11:41:50 -070083 DISALLOW_EVIL_CONSTRUCTORS(Track);
84};
85
86TSPacketizer::Track::Track(
87 const sp<AMessage> &format,
88 unsigned PID, unsigned streamType, unsigned streamID)
89 : mFormat(format),
90 mPID(PID),
91 mStreamType(streamType),
92 mStreamID(streamID),
Andreas Huberb8c7bd42012-09-18 14:47:48 -070093 mContinuityCounter(0),
Andreas Huber90a92052012-10-30 15:53:03 -070094 mAudioLacksATDSHeaders(false),
Andreas Hubera556c482013-03-05 10:56:27 -080095 mFinalized(false),
96 mExtractedCSD(false) {
Andreas Huberd7bee3a2012-08-29 11:41:50 -070097 CHECK(format->findString("mime", &mMIME));
Andreas Hubera556c482013-03-05 10:56:27 -080098}
99
100void TSPacketizer::Track::extractCSDIfNecessary() {
101 if (mExtractedCSD) {
102 return;
103 }
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700104
105 if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)
106 || !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
107 for (size_t i = 0;; ++i) {
108 sp<ABuffer> csd;
Andreas Hubera556c482013-03-05 10:56:27 -0800109 if (!mFormat->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700110 break;
111 }
112
113 mCSD.push(csd);
114 }
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700115
116 if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
117 int32_t isADTS;
118 if (!mFormat->findInt32("is-adts", &isADTS) || isADTS == 0) {
119 mAudioLacksATDSHeaders = true;
120 }
121 }
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700122 }
Andreas Hubera556c482013-03-05 10:56:27 -0800123
124 mExtractedCSD = true;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700125}
126
127TSPacketizer::Track::~Track() {
128}
129
130unsigned TSPacketizer::Track::PID() const {
131 return mPID;
132}
133
134unsigned TSPacketizer::Track::streamType() const {
135 return mStreamType;
136}
137
138unsigned TSPacketizer::Track::streamID() const {
139 return mStreamID;
140}
141
142unsigned TSPacketizer::Track::incrementContinuityCounter() {
143 unsigned prevCounter = mContinuityCounter;
144
145 if (++mContinuityCounter == 16) {
146 mContinuityCounter = 0;
147 }
148
149 return prevCounter;
150}
151
152bool TSPacketizer::Track::isAudio() const {
153 return !strncasecmp("audio/", mMIME.c_str(), 6);
154}
155
156bool TSPacketizer::Track::isVideo() const {
157 return !strncasecmp("video/", mMIME.c_str(), 6);
158}
159
160bool TSPacketizer::Track::isH264() const {
161 return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC);
162}
163
Andreas Hubere7bd24a2012-10-04 11:46:29 -0700164bool TSPacketizer::Track::isAAC() const {
165 return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC);
166}
167
Andreas Huber90a92052012-10-30 15:53:03 -0700168bool TSPacketizer::Track::isPCMAudio() const {
169 return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW);
170}
171
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700172bool TSPacketizer::Track::lacksADTSHeader() const {
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700173 return mAudioLacksATDSHeaders;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700174}
175
176sp<ABuffer> TSPacketizer::Track::prependCSD(
177 const sp<ABuffer> &accessUnit) const {
178 size_t size = 0;
179 for (size_t i = 0; i < mCSD.size(); ++i) {
180 size += mCSD.itemAt(i)->size();
181 }
182
183 sp<ABuffer> dup = new ABuffer(accessUnit->size() + size);
184 size_t offset = 0;
185 for (size_t i = 0; i < mCSD.size(); ++i) {
186 const sp<ABuffer> &csd = mCSD.itemAt(i);
187
188 memcpy(dup->data() + offset, csd->data(), csd->size());
189 offset += csd->size();
190 }
191
192 memcpy(dup->data() + offset, accessUnit->data(), accessUnit->size());
193
194 return dup;
195}
196
197sp<ABuffer> TSPacketizer::Track::prependADTSHeader(
198 const sp<ABuffer> &accessUnit) const {
199 CHECK_EQ(mCSD.size(), 1u);
200
201 const uint8_t *codec_specific_data = mCSD.itemAt(0)->data();
202
203 const uint32_t aac_frame_length = accessUnit->size() + 7;
204
205 sp<ABuffer> dup = new ABuffer(aac_frame_length);
206
207 unsigned profile = (codec_specific_data[0] >> 3) - 1;
208
209 unsigned sampling_freq_index =
210 ((codec_specific_data[0] & 7) << 1)
211 | (codec_specific_data[1] >> 7);
212
213 unsigned channel_configuration =
214 (codec_specific_data[1] >> 3) & 0x0f;
215
216 uint8_t *ptr = dup->data();
217
218 *ptr++ = 0xff;
219 *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1
220
221 *ptr++ =
222 profile << 6
223 | sampling_freq_index << 2
224 | ((channel_configuration >> 2) & 1); // private_bit=0
225
226 // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0
227 *ptr++ =
228 (channel_configuration & 3) << 6
229 | aac_frame_length >> 11;
230 *ptr++ = (aac_frame_length >> 3) & 0xff;
231 *ptr++ = (aac_frame_length & 7) << 5;
232
233 // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0
234 *ptr++ = 0;
235
236 memcpy(ptr, accessUnit->data(), accessUnit->size());
237
238 return dup;
239}
240
Andreas Huber90a92052012-10-30 15:53:03 -0700241size_t TSPacketizer::Track::countDescriptors() const {
242 return mDescriptors.size();
243}
244
245sp<ABuffer> TSPacketizer::Track::descriptorAt(size_t index) const {
246 CHECK_LT(index, mDescriptors.size());
247 return mDescriptors.itemAt(index);
248}
249
250void TSPacketizer::Track::finalize() {
251 if (mFinalized) {
252 return;
253 }
254
255 if (isH264()) {
256 {
257 // AVC video descriptor (40)
258
259 sp<ABuffer> descriptor = new ABuffer(6);
260 uint8_t *data = descriptor->data();
261 data[0] = 40; // descriptor_tag
262 data[1] = 4; // descriptor_length
263
264 CHECK_EQ(mCSD.size(), 1u);
265 const sp<ABuffer> &sps = mCSD.itemAt(0);
266 CHECK(!memcmp("\x00\x00\x00\x01", sps->data(), 4));
267 CHECK_GE(sps->size(), 7u);
268 // profile_idc, constraint_set*, level_idc
269 memcpy(&data[2], sps->data() + 4, 3);
270
271 // AVC_still_present=0, AVC_24_hour_picture_flag=0, reserved
272 data[5] = 0x3f;
273
274 mDescriptors.push_back(descriptor);
275 }
276
277 {
278 // AVC timing and HRD descriptor (42)
279
280 sp<ABuffer> descriptor = new ABuffer(4);
281 uint8_t *data = descriptor->data();
282 data[0] = 42; // descriptor_tag
283 data[1] = 2; // descriptor_length
284
285 // hrd_management_valid_flag = 0
286 // reserved = 111111b
287 // picture_and_timing_info_present = 0
288
289 data[2] = 0x7e;
290
291 // fixed_frame_rate_flag = 0
292 // temporal_poc_flag = 0
293 // picture_to_display_conversion_flag = 0
294 // reserved = 11111b
295 data[3] = 0x1f;
296
297 mDescriptors.push_back(descriptor);
298 }
299 } else if (isPCMAudio()) {
300 // LPCM audio stream descriptor (0x83)
301
302 int32_t channelCount;
303 CHECK(mFormat->findInt32("channel-count", &channelCount));
304 CHECK_EQ(channelCount, 2);
305
306 int32_t sampleRate;
307 CHECK(mFormat->findInt32("sample-rate", &sampleRate));
308 CHECK(sampleRate == 44100 || sampleRate == 48000);
309
310 sp<ABuffer> descriptor = new ABuffer(4);
311 uint8_t *data = descriptor->data();
312 data[0] = 0x83; // descriptor_tag
313 data[1] = 2; // descriptor_length
314
315 unsigned sampling_frequency = (sampleRate == 44100) ? 1 : 2;
316
317 data[2] = (sampling_frequency << 5)
318 | (3 /* reserved */ << 1)
319 | 0 /* emphasis_flag */;
320
321 data[3] =
322 (1 /* number_of_channels = stereo */ << 5)
323 | 0xf /* reserved */;
324
325 mDescriptors.push_back(descriptor);
326 }
327
Andreas Huberbfd79f22013-03-07 10:33:20 -0800328 mFinalized = true;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332
333TSPacketizer::TSPacketizer(uint32_t flags)
334 : mFlags(flags),
335 mPATContinuityCounter(0),
336 mPMTContinuityCounter(0) {
337 initCrcTable();
338
339 if (flags & (EMIT_HDCP20_DESCRIPTOR | EMIT_HDCP21_DESCRIPTOR)) {
340 int32_t hdcpVersion;
341 if (flags & EMIT_HDCP20_DESCRIPTOR) {
342 CHECK(!(flags & EMIT_HDCP21_DESCRIPTOR));
343 hdcpVersion = 0x20;
344 } else {
345 CHECK(!(flags & EMIT_HDCP20_DESCRIPTOR));
346
347 // HDCP2.0 _and_ HDCP 2.1 specs say to set the version
348 // inside the HDCP descriptor to 0x20!!!
349 hdcpVersion = 0x20;
350 }
351
Andreas Huber0224bf12012-11-12 13:08:44 -0800352 // HDCP descriptor
Andreas Huber0224bf12012-11-12 13:08:44 -0800353 sp<ABuffer> descriptor = new ABuffer(7);
354 uint8_t *data = descriptor->data();
355 data[0] = 0x05; // descriptor_tag
356 data[1] = 5; // descriptor_length
357 data[2] = 'H';
358 data[3] = 'D';
359 data[4] = 'C';
360 data[5] = 'P';
361 data[6] = hdcpVersion;
362
Andreas Huberbfd79f22013-03-07 10:33:20 -0800363 mProgramInfoDescriptors.push_back(descriptor);
Andreas Huber0224bf12012-11-12 13:08:44 -0800364 }
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700365}
366
367TSPacketizer::~TSPacketizer() {
368}
369
370ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) {
371 AString mime;
372 CHECK(format->findString("mime", &mime));
373
374 unsigned PIDStart;
375 bool isVideo = !strncasecmp("video/", mime.c_str(), 6);
376 bool isAudio = !strncasecmp("audio/", mime.c_str(), 6);
377
378 if (isVideo) {
379 PIDStart = 0x1011;
380 } else if (isAudio) {
381 PIDStart = 0x1100;
382 } else {
383 return ERROR_UNSUPPORTED;
384 }
385
386 unsigned streamType;
387 unsigned streamIDStart;
388 unsigned streamIDStop;
389
390 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
391 streamType = 0x1b;
392 streamIDStart = 0xe0;
393 streamIDStop = 0xef;
394 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
395 streamType = 0x0f;
396 streamIDStart = 0xc0;
397 streamIDStop = 0xdf;
Andreas Hubere7bd24a2012-10-04 11:46:29 -0700398 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
399 streamType = 0x83;
400 streamIDStart = 0xbd;
401 streamIDStop = 0xbd;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700402 } else {
403 return ERROR_UNSUPPORTED;
404 }
405
406 size_t numTracksOfThisType = 0;
407 unsigned PID = PIDStart;
408
409 for (size_t i = 0; i < mTracks.size(); ++i) {
410 const sp<Track> &track = mTracks.itemAt(i);
411
412 if (track->streamType() == streamType) {
413 ++numTracksOfThisType;
414 }
415
416 if ((isAudio && track->isAudio()) || (isVideo && track->isVideo())) {
417 ++PID;
418 }
419 }
420
421 unsigned streamID = streamIDStart + numTracksOfThisType;
422 if (streamID > streamIDStop) {
423 return -ERANGE;
424 }
425
426 sp<Track> track = new Track(format, PID, streamType, streamID);
427 return mTracks.add(track);
428}
429
Andreas Hubera556c482013-03-05 10:56:27 -0800430status_t TSPacketizer::extractCSDIfNecessary(size_t trackIndex) {
431 if (trackIndex >= mTracks.size()) {
432 return -ERANGE;
433 }
434
435 const sp<Track> &track = mTracks.itemAt(trackIndex);
436 track->extractCSDIfNecessary();
437
438 return OK;
439}
440
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700441status_t TSPacketizer::packetize(
442 size_t trackIndex,
443 const sp<ABuffer> &_accessUnit,
444 sp<ABuffer> *packets,
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700445 uint32_t flags,
Andreas Huber90a92052012-10-30 15:53:03 -0700446 const uint8_t *PES_private_data, size_t PES_private_data_len,
447 size_t numStuffingBytes) {
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700448 sp<ABuffer> accessUnit = _accessUnit;
449
Andreas Huber28e17ed2012-09-25 14:20:08 -0700450 int64_t timeUs;
451 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
452
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700453 packets->clear();
454
455 if (trackIndex >= mTracks.size()) {
456 return -ERANGE;
457 }
458
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700459 const sp<Track> &track = mTracks.itemAt(trackIndex);
460
Andreas Huberc6920df2012-10-02 10:16:47 -0700461 if (track->isH264() && (flags & PREPEND_SPS_PPS_TO_IDR_FRAMES)
462 && IsIDR(accessUnit)) {
463 // prepend codec specific data, i.e. SPS and PPS.
464 accessUnit = track->prependCSD(accessUnit);
Andreas Hubere7bd24a2012-10-04 11:46:29 -0700465 } else if (track->isAAC() && track->lacksADTSHeader()) {
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700466 CHECK(!(flags & IS_ENCRYPTED));
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700467 accessUnit = track->prependADTSHeader(accessUnit);
468 }
469
470 // 0x47
471 // transport_error_indicator = b0
472 // payload_unit_start_indicator = b1
473 // transport_priority = b0
474 // PID
475 // transport_scrambling_control = b00
476 // adaptation_field_control = b??
477 // continuity_counter = b????
478 // -- payload follows
479 // packet_startcode_prefix = 0x000001
480 // stream_id
481 // PES_packet_length = 0x????
482 // reserved = b10
483 // PES_scrambling_control = b00
484 // PES_priority = b0
485 // data_alignment_indicator = b1
486 // copyright = b0
487 // original_or_copy = b0
488 // PTS_DTS_flags = b10 (PTS only)
489 // ESCR_flag = b0
490 // ES_rate_flag = b0
491 // DSM_trick_mode_flag = b0
492 // additional_copy_info_flag = b0
493 // PES_CRC_flag = b0
494 // PES_extension_flag = b0
495 // PES_header_data_length = 0x05
496 // reserved = b0010 (PTS)
497 // PTS[32..30] = b???
498 // reserved = b1
499 // PTS[29..15] = b??? ???? ???? ???? (15 bits)
500 // reserved = b1
501 // PTS[14..0] = b??? ???? ???? ???? (15 bits)
502 // reserved = b1
503 // the first fragment of "buffer" follows
504
Andreas Huber90a92052012-10-30 15:53:03 -0700505 size_t PES_packet_length = accessUnit->size() + 8 + numStuffingBytes;
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700506 if (PES_private_data_len > 0) {
507 PES_packet_length += PES_private_data_len + 1;
508 }
509
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700510 size_t numTSPackets;
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700511 if (PES_packet_length <= 178) {
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700512 numTSPackets = 1;
513 } else {
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700514 numTSPackets = 1 + ((PES_packet_length - 178) + 183) / 184;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700515 }
516
517 if (flags & EMIT_PAT_AND_PMT) {
518 numTSPackets += 2;
519 }
520
521 if (flags & EMIT_PCR) {
522 ++numTSPackets;
523 }
524
525 sp<ABuffer> buffer = new ABuffer(numTSPackets * 188);
526 uint8_t *packetDataStart = buffer->data();
527
528 if (flags & EMIT_PAT_AND_PMT) {
529 // Program Association Table (PAT):
530 // 0x47
531 // transport_error_indicator = b0
532 // payload_unit_start_indicator = b1
533 // transport_priority = b0
534 // PID = b0000000000000 (13 bits)
535 // transport_scrambling_control = b00
536 // adaptation_field_control = b01 (no adaptation field, payload only)
537 // continuity_counter = b????
538 // skip = 0x00
539 // --- payload follows
540 // table_id = 0x00
541 // section_syntax_indicator = b1
542 // must_be_zero = b0
543 // reserved = b11
544 // section_length = 0x00d
545 // transport_stream_id = 0x0000
546 // reserved = b11
547 // version_number = b00001
548 // current_next_indicator = b1
549 // section_number = 0x00
550 // last_section_number = 0x00
551 // one program follows:
552 // program_number = 0x0001
553 // reserved = b111
554 // program_map_PID = kPID_PMT (13 bits!)
555 // CRC = 0x????????
556
557 if (++mPATContinuityCounter == 16) {
558 mPATContinuityCounter = 0;
559 }
560
561 uint8_t *ptr = packetDataStart;
562 *ptr++ = 0x47;
563 *ptr++ = 0x40;
564 *ptr++ = 0x00;
565 *ptr++ = 0x10 | mPATContinuityCounter;
566 *ptr++ = 0x00;
567
Andreas Huber90a92052012-10-30 15:53:03 -0700568 uint8_t *crcDataStart = ptr;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700569 *ptr++ = 0x00;
570 *ptr++ = 0xb0;
571 *ptr++ = 0x0d;
572 *ptr++ = 0x00;
573 *ptr++ = 0x00;
574 *ptr++ = 0xc3;
575 *ptr++ = 0x00;
576 *ptr++ = 0x00;
577 *ptr++ = 0x00;
578 *ptr++ = 0x01;
579 *ptr++ = 0xe0 | (kPID_PMT >> 8);
580 *ptr++ = kPID_PMT & 0xff;
581
582 CHECK_EQ(ptr - crcDataStart, 12);
583 uint32_t crc = htonl(crc32(crcDataStart, ptr - crcDataStart));
584 memcpy(ptr, &crc, 4);
585 ptr += 4;
586
587 size_t sizeLeft = packetDataStart + 188 - ptr;
588 memset(ptr, 0xff, sizeLeft);
589
590 packetDataStart += 188;
591
592 // Program Map (PMT):
593 // 0x47
594 // transport_error_indicator = b0
595 // payload_unit_start_indicator = b1
596 // transport_priority = b0
597 // PID = kPID_PMT (13 bits)
598 // transport_scrambling_control = b00
599 // adaptation_field_control = b01 (no adaptation field, payload only)
600 // continuity_counter = b????
601 // skip = 0x00
602 // -- payload follows
603 // table_id = 0x02
604 // section_syntax_indicator = b1
605 // must_be_zero = b0
606 // reserved = b11
607 // section_length = 0x???
608 // program_number = 0x0001
609 // reserved = b11
610 // version_number = b00001
611 // current_next_indicator = b1
612 // section_number = 0x00
613 // last_section_number = 0x00
614 // reserved = b111
615 // PCR_PID = kPCR_PID (13 bits)
616 // reserved = b1111
Andreas Huberbfd79f22013-03-07 10:33:20 -0800617 // program_info_length = 0x???
618 // program_info_descriptors follow
619 // one or more elementary stream descriptions follow:
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700620 // stream_type = 0x??
621 // reserved = b111
622 // elementary_PID = b? ???? ???? ???? (13 bits)
623 // reserved = b1111
624 // ES_info_length = 0x000
625 // CRC = 0x????????
626
627 if (++mPMTContinuityCounter == 16) {
628 mPMTContinuityCounter = 0;
629 }
630
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700631 ptr = packetDataStart;
632 *ptr++ = 0x47;
633 *ptr++ = 0x40 | (kPID_PMT >> 8);
634 *ptr++ = kPID_PMT & 0xff;
635 *ptr++ = 0x10 | mPMTContinuityCounter;
636 *ptr++ = 0x00;
637
638 crcDataStart = ptr;
639 *ptr++ = 0x02;
Andreas Huber90a92052012-10-30 15:53:03 -0700640
641 *ptr++ = 0x00; // section_length to be filled in below.
642 *ptr++ = 0x00;
643
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700644 *ptr++ = 0x00;
645 *ptr++ = 0x01;
646 *ptr++ = 0xc3;
647 *ptr++ = 0x00;
648 *ptr++ = 0x00;
649 *ptr++ = 0xe0 | (kPID_PCR >> 8);
650 *ptr++ = kPID_PCR & 0xff;
Andreas Huberbfd79f22013-03-07 10:33:20 -0800651
652 size_t program_info_length = 0;
653 for (size_t i = 0; i < mProgramInfoDescriptors.size(); ++i) {
654 program_info_length += mProgramInfoDescriptors.itemAt(i)->size();
655 }
656
657 CHECK_LT(program_info_length, 0x400);
658 *ptr++ = 0xf0 | (program_info_length >> 8);
659 *ptr++ = (program_info_length & 0xff);
660
661 for (size_t i = 0; i < mProgramInfoDescriptors.size(); ++i) {
662 const sp<ABuffer> &desc = mProgramInfoDescriptors.itemAt(i);
663 memcpy(ptr, desc->data(), desc->size());
664 ptr += desc->size();
665 }
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700666
667 for (size_t i = 0; i < mTracks.size(); ++i) {
668 const sp<Track> &track = mTracks.itemAt(i);
669
Andreas Huber90a92052012-10-30 15:53:03 -0700670 // Make sure all the decriptors have been added.
671 track->finalize();
672
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700673 *ptr++ = track->streamType();
674 *ptr++ = 0xe0 | (track->PID() >> 8);
675 *ptr++ = track->PID() & 0xff;
Andreas Huber90a92052012-10-30 15:53:03 -0700676
677 size_t ES_info_length = 0;
678 for (size_t i = 0; i < track->countDescriptors(); ++i) {
679 ES_info_length += track->descriptorAt(i)->size();
680 }
681 CHECK_LE(ES_info_length, 0xfff);
682
683 *ptr++ = 0xf0 | (ES_info_length >> 8);
684 *ptr++ = (ES_info_length & 0xff);
685
686 for (size_t i = 0; i < track->countDescriptors(); ++i) {
687 const sp<ABuffer> &descriptor = track->descriptorAt(i);
688 memcpy(ptr, descriptor->data(), descriptor->size());
689 ptr += descriptor->size();
690 }
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700691 }
692
Andreas Huber90a92052012-10-30 15:53:03 -0700693 size_t section_length = ptr - (crcDataStart + 3) + 4 /* CRC */;
694
695 crcDataStart[1] = 0xb0 | (section_length >> 8);
696 crcDataStart[2] = section_length & 0xff;
697
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700698 crc = htonl(crc32(crcDataStart, ptr - crcDataStart));
699 memcpy(ptr, &crc, 4);
700 ptr += 4;
701
702 sizeLeft = packetDataStart + 188 - ptr;
703 memset(ptr, 0xff, sizeLeft);
704
705 packetDataStart += 188;
706 }
707
708 if (flags & EMIT_PCR) {
709 // PCR stream
710 // 0x47
711 // transport_error_indicator = b0
712 // payload_unit_start_indicator = b1
713 // transport_priority = b0
714 // PID = kPCR_PID (13 bits)
715 // transport_scrambling_control = b00
716 // adaptation_field_control = b10 (adaptation field only, no payload)
717 // continuity_counter = b0000 (does not increment)
718 // adaptation_field_length = 183
719 // discontinuity_indicator = b0
720 // random_access_indicator = b0
721 // elementary_stream_priority_indicator = b0
722 // PCR_flag = b1
723 // OPCR_flag = b0
724 // splicing_point_flag = b0
725 // transport_private_data_flag = b0
726 // adaptation_field_extension_flag = b0
727 // program_clock_reference_base = b?????????????????????????????????
728 // reserved = b111111
729 // program_clock_reference_extension = b?????????
730
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700731 int64_t nowUs = ALooper::GetNowUs();
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700732
733 uint64_t PCR = nowUs * 27; // PCR based on a 27MHz clock
734 uint64_t PCR_base = PCR / 300;
735 uint32_t PCR_ext = PCR % 300;
736
737 uint8_t *ptr = packetDataStart;
738 *ptr++ = 0x47;
739 *ptr++ = 0x40 | (kPID_PCR >> 8);
740 *ptr++ = kPID_PCR & 0xff;
741 *ptr++ = 0x20;
742 *ptr++ = 0xb7; // adaptation_field_length
743 *ptr++ = 0x10;
744 *ptr++ = (PCR_base >> 25) & 0xff;
745 *ptr++ = (PCR_base >> 17) & 0xff;
746 *ptr++ = (PCR_base >> 9) & 0xff;
747 *ptr++ = ((PCR_base & 1) << 7) | 0x7e | ((PCR_ext >> 8) & 1);
748 *ptr++ = (PCR_ext & 0xff);
749
750 size_t sizeLeft = packetDataStart + 188 - ptr;
751 memset(ptr, 0xff, sizeLeft);
752
753 packetDataStart += 188;
754 }
755
Andreas Huber28e17ed2012-09-25 14:20:08 -0700756 uint64_t PTS = (timeUs * 9ll) / 100ll;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700757
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700758 bool padding = (PES_packet_length < (188 - 10));
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700759
760 if (PES_packet_length >= 65536) {
761 // This really should only happen for video.
762 CHECK(track->isVideo());
763
764 // It's valid to set this to 0 for video according to the specs.
765 PES_packet_length = 0;
766 }
767
768 uint8_t *ptr = packetDataStart;
769 *ptr++ = 0x47;
770 *ptr++ = 0x40 | (track->PID() >> 8);
771 *ptr++ = track->PID() & 0xff;
772 *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter();
773
774 if (padding) {
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700775 size_t paddingSize = 188 - 10 - PES_packet_length;
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700776 *ptr++ = paddingSize - 1;
777 if (paddingSize >= 2) {
778 *ptr++ = 0x00;
779 memset(ptr, 0xff, paddingSize - 2);
780 ptr += paddingSize - 2;
781 }
782 }
783
784 *ptr++ = 0x00;
785 *ptr++ = 0x00;
786 *ptr++ = 0x01;
787 *ptr++ = track->streamID();
788 *ptr++ = PES_packet_length >> 8;
789 *ptr++ = PES_packet_length & 0xff;
790 *ptr++ = 0x84;
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700791 *ptr++ = (PES_private_data_len > 0) ? 0x81 : 0x80;
792
Andreas Huber90a92052012-10-30 15:53:03 -0700793 size_t headerLength = 0x05 + numStuffingBytes;
794 if (PES_private_data_len > 0) {
795 headerLength += 1 + PES_private_data_len;
796 }
797
798 *ptr++ = headerLength;
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700799
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700800 *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
801 *ptr++ = (PTS >> 22) & 0xff;
802 *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
803 *ptr++ = (PTS >> 7) & 0xff;
804 *ptr++ = ((PTS & 0x7f) << 1) | 1;
805
Andreas Huberb8c7bd42012-09-18 14:47:48 -0700806 if (PES_private_data_len > 0) {
807 *ptr++ = 0x8e; // PES_private_data_flag, reserved.
808 memcpy(ptr, PES_private_data, PES_private_data_len);
809 ptr += PES_private_data_len;
810 }
811
Andreas Huber90a92052012-10-30 15:53:03 -0700812 for (size_t i = 0; i < numStuffingBytes; ++i) {
813 *ptr++ = 0xff;
814 }
815
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700816 // 18 bytes of TS/PES header leave 188 - 18 = 170 bytes for the payload
817
818 size_t sizeLeft = packetDataStart + 188 - ptr;
819 size_t copy = accessUnit->size();
820 if (copy > sizeLeft) {
821 copy = sizeLeft;
822 }
823
824 memcpy(ptr, accessUnit->data(), copy);
825 ptr += copy;
826 CHECK_EQ(sizeLeft, copy);
827 memset(ptr, 0xff, sizeLeft - copy);
828
829 packetDataStart += 188;
830
831 size_t offset = copy;
832 while (offset < accessUnit->size()) {
833 bool padding = (accessUnit->size() - offset) < (188 - 4);
834
835 // for subsequent fragments of "buffer":
836 // 0x47
837 // transport_error_indicator = b0
838 // payload_unit_start_indicator = b0
839 // transport_priority = b0
840 // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
841 // transport_scrambling_control = b00
842 // adaptation_field_control = b??
843 // continuity_counter = b????
844 // the fragment of "buffer" follows.
845
846 uint8_t *ptr = packetDataStart;
847 *ptr++ = 0x47;
848 *ptr++ = 0x00 | (track->PID() >> 8);
849 *ptr++ = track->PID() & 0xff;
850
851 *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter();
852
853 if (padding) {
854 size_t paddingSize = 188 - 4 - (accessUnit->size() - offset);
855 *ptr++ = paddingSize - 1;
856 if (paddingSize >= 2) {
857 *ptr++ = 0x00;
858 memset(ptr, 0xff, paddingSize - 2);
859 ptr += paddingSize - 2;
860 }
861 }
862
863 // 4 bytes of TS header leave 188 - 4 = 184 bytes for the payload
864
865 size_t sizeLeft = packetDataStart + 188 - ptr;
866 size_t copy = accessUnit->size() - offset;
867 if (copy > sizeLeft) {
868 copy = sizeLeft;
869 }
870
871 memcpy(ptr, accessUnit->data() + offset, copy);
872 ptr += copy;
873 CHECK_EQ(sizeLeft, copy);
874 memset(ptr, 0xff, sizeLeft - copy);
875
876 offset += copy;
877 packetDataStart += 188;
878 }
879
880 CHECK(packetDataStart == buffer->data() + buffer->capacity());
881
882 *packets = buffer;
883
884 return OK;
885}
886
887void TSPacketizer::initCrcTable() {
888 uint32_t poly = 0x04C11DB7;
889
890 for (int i = 0; i < 256; i++) {
891 uint32_t crc = i << 24;
892 for (int j = 0; j < 8; j++) {
893 crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
894 }
895 mCrcTable[i] = crc;
896 }
897}
898
899uint32_t TSPacketizer::crc32(const uint8_t *start, size_t size) const {
900 uint32_t crc = 0xFFFFFFFF;
901 const uint8_t *p;
902
903 for (p = start; p < start + size; ++p) {
904 crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
905 }
906
907 return crc;
908}
909
Andreas Hubere399acc2012-09-27 08:53:23 -0700910sp<ABuffer> TSPacketizer::prependCSD(
911 size_t trackIndex, const sp<ABuffer> &accessUnit) const {
912 CHECK_LT(trackIndex, mTracks.size());
913
914 const sp<Track> &track = mTracks.itemAt(trackIndex);
915 CHECK(track->isH264() && IsIDR(accessUnit));
916
917 int64_t timeUs;
918 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
919
920 sp<ABuffer> accessUnit2 = track->prependCSD(accessUnit);
921
922 accessUnit2->meta()->setInt64("timeUs", timeUs);
923
924 return accessUnit2;
925}
926
Andreas Huberd7bee3a2012-08-29 11:41:50 -0700927} // namespace android
928