winlin

refine code, write audio immediatly

1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_hls.hpp>  
25 -  
26 -#include <sys/types.h>  
27 -#include <sys/stat.h>  
28 -#include <fcntl.h>  
29 -#include <stdlib.h>  
30 -#include <string.h>  
31 -  
32 -#include <srs_core_error.hpp>  
33 -#include <srs_core_codec.hpp>  
34 -#include <srs_core_amf0.hpp>  
35 -#include <srs_core_protocol.hpp>  
36 -#include <srs_core_config.hpp>  
37 -  
38 -SrsHLS::SrsHLS()  
39 -{  
40 - hls_enabled = false;  
41 - codec = new SrsCodec();  
42 - sample = new SrsCodecSample();  
43 - muxer = NULL;  
44 -}  
45 -  
46 -SrsHLS::~SrsHLS()  
47 -{  
48 - srs_freep(codec);  
49 - srs_freep(sample);  
50 - srs_freep(muxer);  
51 -}  
52 -  
53 -int SrsHLS::on_publish(std::string _vhost)  
54 -{  
55 - int ret = ERROR_SUCCESS;  
56 -  
57 - if (muxer) {  
58 - ret = ERROR_HLS_BUSY;  
59 - srs_error("hls is busy, something error, "  
60 - "vhost=%s, ret=%d", _vhost.c_str(), ret);  
61 - return ret;  
62 - }  
63 -  
64 - vhost = _vhost;  
65 - muxer = new SrsTSMuxer();  
66 -  
67 - // try to open the HLS muxer  
68 - SrsConfDirective* conf = config->get_hls(vhost);  
69 - if (!conf && conf->arg0() == "off") {  
70 - return ret;  
71 - }  
72 -  
73 - // TODO: check the audio and video, ensure both exsists.  
74 - // for use fixed mpegts header specifeid the audio and video pid.  
75 -  
76 - hls_enabled = true;  
77 -  
78 - std::string path = SRS_CONF_DEFAULT_HLS_PATH;  
79 - if ((conf = config->get_hls_path(vhost)) != NULL) {  
80 - path = conf->arg0();  
81 - }  
82 -  
83 - // TODO: generate by m3u8 muxer.  
84 - path += "/1.ts";  
85 -  
86 - if ((ret = muxer->open(path)) != ERROR_SUCCESS) {  
87 - srs_error("open hls muxer failed. ret=%d", ret);  
88 - return ret;  
89 - }  
90 -  
91 - return ret;  
92 -}  
93 -  
94 -void SrsHLS::on_unpublish()  
95 -{  
96 - hls_enabled = false;  
97 - muxer->close();  
98 - srs_freep(muxer);  
99 -}  
100 -  
101 -int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)  
102 -{  
103 - int ret = ERROR_SUCCESS;  
104 -  
105 - if (!metadata || !metadata->metadata) {  
106 - srs_trace("no metadata persent, hls ignored it.");  
107 - return ret;  
108 - }  
109 -  
110 - SrsAmf0Object* obj = metadata->metadata;  
111 - if (obj->size() <= 0) {  
112 - srs_trace("no metadata persent, hls ignored it.");  
113 - return ret;  
114 - }  
115 -  
116 - // finger out the codec info from metadata if possible.  
117 - SrsAmf0Any* prop = NULL;  
118 -  
119 - if ((prop = obj->get_property("duration")) != NULL && prop->is_number()) {  
120 - codec->duration = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
121 - }  
122 - if ((prop = obj->get_property("width")) != NULL && prop->is_number()) {  
123 - codec->width = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
124 - }  
125 - if ((prop = obj->get_property("height")) != NULL && prop->is_number()) {  
126 - codec->height = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
127 - }  
128 - if ((prop = obj->get_property("framerate")) != NULL && prop->is_number()) {  
129 - codec->frame_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
130 - }  
131 - if ((prop = obj->get_property("videocodecid")) != NULL && prop->is_number()) {  
132 - codec->video_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
133 - }  
134 - if ((prop = obj->get_property("videodatarate")) != NULL && prop->is_number()) {  
135 - codec->video_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);  
136 - }  
137 -  
138 - if ((prop = obj->get_property("audiocodecid")) != NULL && prop->is_number()) {  
139 - codec->audio_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;  
140 - }  
141 - if ((prop = obj->get_property("audiodatarate")) != NULL && prop->is_number()) {  
142 - codec->audio_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);  
143 - }  
144 -  
145 - // ignore the following, for each flv/rtmp packet contains them:  
146 - // audiosamplerate, sample->sound_rate  
147 - // audiosamplesize, sample->sound_size  
148 - // stereo, sample->sound_type  
149 -  
150 - return ret;  
151 -}  
152 -  
153 -int SrsHLS::on_audio(SrsCommonMessage* audio)  
154 -{  
155 - int ret = ERROR_SUCCESS;  
156 -  
157 - sample->clear();  
158 - if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {  
159 - return ret;  
160 - }  
161 -  
162 - if (codec->audio_codec_id != SrsCodecAudioAAC) {  
163 - return ret;  
164 - }  
165 -  
166 - // TODO: maybe donot need to demux the aac?  
167 - if (!hls_enabled) {  
168 - return ret;  
169 - }  
170 -  
171 - // ignore sequence header  
172 - if (sample->aac_packet_type == SrsCodecAudioTypeSequenceHeader) {  
173 - return ret;  
174 - }  
175 -  
176 - u_int32_t timestamp = audio->header.timestamp;  
177 - // TODO: correct the timestamp.  
178 -  
179 - if ((ret = muxer->write_audio(timestamp, codec, sample)) != ERROR_SUCCESS) {  
180 - return ret;  
181 - }  
182 -  
183 - return ret;  
184 -}  
185 -  
186 -int SrsHLS::on_video(SrsCommonMessage* video)  
187 -{  
188 - int ret = ERROR_SUCCESS;  
189 -  
190 - sample->clear();  
191 - if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) {  
192 - return ret;  
193 - }  
194 -  
195 - if (codec->video_codec_id != SrsCodecVideoAVC) {  
196 - return ret;  
197 - }  
198 -  
199 - // TODO: maybe donot need to demux the avc?  
200 - if (!hls_enabled) {  
201 - return ret;  
202 - }  
203 -  
204 - // ignore sequence header  
205 - if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && sample->avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {  
206 - return ret;  
207 - }  
208 -  
209 - u_int32_t timestamp = video->header.timestamp;  
210 - // TODO: correct the timestamp.  
211 -  
212 - if ((ret = muxer->write_video(timestamp, codec, sample)) != ERROR_SUCCESS) {  
213 - return ret;  
214 - }  
215 -  
216 - return ret;  
217 -}  
218 -  
219 -// @see: ngx_rtmp_mpegts_header  
220 -u_int8_t mpegts_header[] = {  
221 - /* TS */  
222 - 0x47, 0x40, 0x00, 0x10, 0x00,  
223 - /* PSI */  
224 - 0x00, 0xb0, 0x0d, 0x00, 0x01, 0xc1, 0x00, 0x00,  
225 - /* PAT */  
226 - 0x00, 0x01, 0xf0, 0x01,  
227 - /* CRC */  
228 - 0x2e, 0x70, 0x19, 0x05,  
229 - /* stuffing 167 bytes */  
230 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
231 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
232 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
233 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
234 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
235 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
236 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
237 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
238 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
239 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
240 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
241 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
242 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
243 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
244 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
245 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
246 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
247 -  
248 - /* TS */  
249 - 0x47, 0x50, 0x01, 0x10, 0x00,  
250 - /* PSI */  
251 - 0x02, 0xb0, 0x17, 0x00, 0x01, 0xc1, 0x00, 0x00,  
252 - /* PMT */  
253 - 0xe1, 0x00,  
254 - 0xf0, 0x00,  
255 - 0x1b, 0xe1, 0x00, 0xf0, 0x00, /* h264, pid=0x100=256 */  
256 - 0x0f, 0xe1, 0x01, 0xf0, 0x00, /* aac, pid=0x101=257 */  
257 - /*0x03, 0xe1, 0x01, 0xf0, 0x00,*/ /* mp3 */  
258 - /* CRC */  
259 - 0x2f, 0x44, 0xb9, 0x9b, /* crc for aac */  
260 - /*0x4e, 0x59, 0x3d, 0x1e,*/ /* crc for mp3 */  
261 - /* stuffing 157 bytes */  
262 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
263 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
264 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
265 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
266 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
267 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
268 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
269 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
270 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
271 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
272 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
273 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
274 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
275 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
276 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
277 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff  
278 -};  
279 -  
280 -// @see: NGX_RTMP_HLS_DELAY,  
281 -// 63000: 700ms, ts_tbn=90000  
282 -#define SRS_HLS_DELAY 63000  
283 -  
284 -// @see: ngx_rtmp_SrsMpegtsFrame_t  
285 -struct SrsMpegtsFrame  
286 -{  
287 - int64_t pts;  
288 - int64_t dts;  
289 - int pid;  
290 - int sid;  
291 - int cc;  
292 - bool key;  
293 -  
294 - SrsMpegtsFrame()  
295 - {  
296 - pts = dts = 0;  
297 - pid = sid = cc = 0;  
298 - key = false;  
299 - }  
300 -};  
301 -  
302 -// @see: ngx_rtmp_mpegts.c  
303 -// TODO: support full mpegts feature in future.  
304 -class SrsMpegtsWriter  
305 -{  
306 -public:  
307 - static int write_header(int fd)  
308 - {  
309 - int ret = ERROR_SUCCESS;  
310 -  
311 - if (::write(fd, mpegts_header, sizeof(mpegts_header)) != sizeof(mpegts_header)) {  
312 - ret = ERROR_HLS_WRITE_FAILED;  
313 - srs_error("write ts file header failed. ret=%d", ret);  
314 - return ret;  
315 - }  
316 -  
317 - return ret;  
318 - }  
319 - static int write_frame(int fd, SrsMpegtsFrame* frame, SrsCodecBuffer* buffer)  
320 - {  
321 - int ret = ERROR_SUCCESS;  
322 -  
323 - if (!buffer->bytes || buffer->size <= 0) {  
324 - return ret;  
325 - }  
326 -  
327 - char* last = buffer->bytes + buffer->size;  
328 - char* pos = buffer->bytes;  
329 -  
330 - bool first = true;  
331 - while (pos < last) {  
332 - static char packet[188];  
333 - char* p = packet;  
334 -  
335 - frame->cc++;  
336 -  
337 - // sync_byte; //8bits  
338 - *p++ = 0x47;  
339 - // pid; //13bits  
340 - *p++ = (frame->pid >> 8) & 0x1f;  
341 - // payload_unit_start_indicator; //1bit  
342 - if (first) {  
343 - p[-1] |= 0x40;  
344 - }  
345 - *p++ = frame->pid;  
346 -  
347 - // transport_scrambling_control; //2bits  
348 - // adaption_field_control; //2bits, 0x01: PayloadOnly  
349 - // continuity_counter; //4bits  
350 - *p++ = 0x10 | (frame->cc & 0x0f);  
351 -  
352 - if (first) {  
353 - first = false;  
354 - if (frame->key) {  
355 - p[-1] |= 0x20; // Both Adaption and Payload  
356 - *p++ = 7; // size  
357 - *p++ = 0x50; // random access + PCR  
358 - p = write_pcr(p, frame->dts - SRS_HLS_DELAY);  
359 - }  
360 -  
361 - // PES header  
362 - // packet_start_code_prefix; //24bits, '00 00 01'  
363 - *p++ = 0x00;  
364 - *p++ = 0x00;  
365 - *p++ = 0x01;  
366 - //8bits  
367 - *p++ = frame->sid;  
368 -  
369 - // pts(33bits) need 5bytes.  
370 - u_int8_t header_size = 5;  
371 - u_int8_t flags = 0x80; // pts  
372 -  
373 - // dts(33bits) need 5bytes also  
374 - if (frame->dts != frame->pts) {  
375 - header_size += 5;  
376 - flags |= 0x40; // dts  
377 - }  
378 -  
379 - // 3bytes: flag fields from PES_packet_length to PES_header_data_length  
380 - int pes_size = (last - pos) + header_size + 3;  
381 - if (pes_size > 0xffff) {  
382 - /**  
383 - * when actual packet length > 0xffff(65535),  
384 - * which exceed the max u_int16_t packet length,  
385 - * use 0 packet length, the next unit start indicates the end of packet.  
386 - */  
387 - pes_size = 0;  
388 - }  
389 -  
390 - // PES_packet_length; //16bits  
391 - *p++ = (pes_size >> 8);  
392 - *p++ = pes_size;  
393 -  
394 - // PES_scrambling_control; //2bits, '10'  
395 - // PES_priority; //1bit  
396 - // data_alignment_indicator; //1bit  
397 - // copyright; //1bit  
398 - // original_or_copy; //1bit  
399 - *p++ = 0x80; /* H222 */  
400 -  
401 - // PTS_DTS_flags; //2bits  
402 - // ESCR_flag; //1bit  
403 - // ES_rate_flag; //1bit  
404 - // DSM_trick_mode_flag; //1bit  
405 - // additional_copy_info_flag; //1bit  
406 - // PES_CRC_flag; //1bit  
407 - // PES_extension_flag; //1bit  
408 - *p++ = flags;  
409 -  
410 - // PES_header_data_length; //8bits  
411 - *p++ = header_size;  
412 -  
413 - // pts; // 33bits  
414 - p = write_pts(p, flags >> 6, frame->pts + SRS_HLS_DELAY);  
415 -  
416 - // dts; // 33bits  
417 - if (frame->dts != frame->pts) {  
418 - p = write_pts(p, 1, frame->dts + SRS_HLS_DELAY);  
419 - }  
420 - }  
421 -  
422 - int body_size = sizeof(packet) - (p - packet);  
423 - int in_size = last - pos;  
424 -  
425 - if (body_size <= in_size) {  
426 - memcpy(p, pos, body_size);  
427 - pos += body_size;  
428 - } else {  
429 - p = fill_stuff(p, packet, body_size, in_size);  
430 - memcpy(p, pos, in_size);  
431 - pos = last;  
432 - }  
433 -  
434 - // write ts packet  
435 - if (::write(fd, packet, sizeof(packet)) != sizeof(packet)) {  
436 - ret = ERROR_HLS_WRITE_FAILED;  
437 - srs_error("write ts file failed. ret=%d", ret);  
438 - return ret;  
439 - }  
440 - }  
441 -  
442 - // write success, clear and free the buffer  
443 - buffer->free();  
444 -  
445 - return ret;  
446 - }  
447 -private:  
448 - static char* fill_stuff(char* pes_body_end, char* packet, int body_size, int in_size)  
449 - {  
450 - char* p = pes_body_end;  
451 -  
452 - // insert the stuff bytes before PES body  
453 - int stuff_size = (body_size - in_size);  
454 -  
455 - // adaption_field_control; //2bits  
456 - if (packet[3] & 0x20) {  
457 - // has adaptation  
458 - // packet[4]: adaption_field_length  
459 - // packet[5]: adaption field data  
460 - // base: start of PES body  
461 - char* base = &packet[5] + packet[4];  
462 - int len = p - base;  
463 - p = (char*)memmove(base + stuff_size, base, len) + len;  
464 - // increase the adaption field size.  
465 - packet[4] += stuff_size;  
466 -  
467 - return p;  
468 - }  
469 -  
470 - // create adaption field.  
471 - // adaption_field_control; //2bits  
472 - packet[3] |= 0x20;  
473 - // base: start of PES body  
474 - char* base = &packet[4];  
475 - int len = p - base;  
476 - p = (char*)memmove(base + stuff_size, base, len) + len;  
477 - // adaption_field_length; //8bits  
478 - packet[4] = (stuff_size - 1);  
479 - if (stuff_size >= 2) {  
480 - // adaption field flags.  
481 - packet[5] = 0;  
482 - // adaption data.  
483 - if (stuff_size > 2) {  
484 - memset(&packet[6], 0xff, stuff_size - 2);  
485 - }  
486 - }  
487 -  
488 - return p;  
489 - }  
490 - static char* write_pcr(char* p, int64_t pcr)  
491 - {  
492 - *p++ = (char) (pcr >> 25);  
493 - *p++ = (char) (pcr >> 17);  
494 - *p++ = (char) (pcr >> 9);  
495 - *p++ = (char) (pcr >> 1);  
496 - *p++ = (char) (pcr << 7 | 0x7e);  
497 - *p++ = 0;  
498 -  
499 - return p;  
500 - }  
501 - static char* write_pts(char* p, u_int8_t fb, int64_t pts)  
502 - {  
503 - int32_t val;  
504 -  
505 - val = fb << 4 | (((pts >> 30) & 0x07) << 1) | 1;  
506 - *p++ = val;  
507 -  
508 - val = (((pts >> 15) & 0x7fff) << 1) | 1;  
509 - *p++ = (val >> 8);  
510 - *p++ = val;  
511 -  
512 - val = (((pts) & 0x7fff) << 1) | 1;  
513 - *p++ = (val >> 8);  
514 - *p++ = val;  
515 -  
516 - return p;  
517 - }  
518 -};  
519 -  
520 -// the mpegts header specifed the video/audio pid.  
521 -#define TS_VIDEO_PID 256  
522 -#define TS_AUDIO_PID 257  
523 -  
524 -// ts aac stream id.  
525 -#define TS_AUDIO_AAC 0xc0  
526 -// ts avc stream id.  
527 -#define TS_VIDEO_AVC 0xe0  
528 -  
529 -SrsTSMuxer::SrsTSMuxer()  
530 -{  
531 - fd = -1;  
532 -  
533 - audio_buffer = new SrsCodecBuffer();  
534 - video_buffer = new SrsCodecBuffer();  
535 -  
536 - audio_frame = new SrsMpegtsFrame();  
537 - video_frame = new SrsMpegtsFrame();  
538 -}  
539 -  
540 -SrsTSMuxer::~SrsTSMuxer()  
541 -{  
542 - close();  
543 -  
544 - audio_buffer->free();  
545 - video_buffer->free();  
546 -  
547 - srs_freep(audio_buffer);  
548 - srs_freep(video_buffer);  
549 -  
550 - srs_freep(audio_frame);  
551 - srs_freep(video_frame);  
552 -}  
553 -  
554 -int SrsTSMuxer::open(std::string _path)  
555 -{  
556 - int ret = ERROR_SUCCESS;  
557 -  
558 - path = _path;  
559 -  
560 - close();  
561 -  
562 - int flags = O_CREAT|O_WRONLY|O_TRUNC;  
563 - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;  
564 - if ((fd = ::open(path.c_str(), flags, mode)) < 0) {  
565 - ret = ERROR_HLS_OPEN_FAILED;  
566 - srs_error("open ts file %s failed. ret=%d", path.c_str(), ret);  
567 - return ret;  
568 - }  
569 -  
570 - // write mpegts header  
571 - if ((ret = SrsMpegtsWriter::write_header(fd)) != ERROR_SUCCESS) {  
572 - return ret;  
573 - }  
574 -  
575 - return ret;  
576 -}  
577 -  
578 -int SrsTSMuxer::write_audio(u_int32_t time, SrsCodec* codec, SrsCodecSample* sample)  
579 -{  
580 - int ret = ERROR_SUCCESS;  
581 -  
582 - if (!audio_frame) {  
583 - audio_frame = new SrsMpegtsFrame();  
584 - audio_frame->dts = audio_frame->pts = time * 90;  
585 - audio_frame->pid = TS_AUDIO_PID;  
586 - audio_frame->sid = TS_AUDIO_AAC;  
587 - }  
588 -  
589 - for (int i = 0; i < sample->nb_buffers; i++) {  
590 - SrsCodecBuffer* buf = &sample->buffers[i];  
591 - int32_t size = buf->size;  
592 -  
593 - if (!buf->bytes || size <= 0 || size > 0x1fff) {  
594 - ret = ERROR_HLS_AAC_FRAME_LENGTH;  
595 - srs_error("invalid aac frame length=%d, ret=%d", size, ret);  
596 - return ret;  
597 - }  
598 -  
599 - // the frame length is the AAC raw data plus the adts header size.  
600 - int32_t frame_length = size + 7;  
601 -  
602 - // AAC-ADTS  
603 - // 6.2 Audio Data Transport Stream, ADTS  
604 - // in aac-iso-13818-7.pdf, page 26.  
605 - // fixed 7bytes header  
606 - static u_int8_t adts_header[7] = {0xff, 0xf1, 0x00, 0x00, 0x00, 0x0f, 0xfc};  
607 - /*  
608 - // adts_fixed_header  
609 - // 2B, 16bits  
610 - int16_t syncword; //12bits, '1111 1111 1111'  
611 - int8_t ID; //1bit, '0'  
612 - int8_t layer; //2bits, '00'  
613 - int8_t protection_absent; //1bit, can be '1'  
614 - // 12bits  
615 - int8_t profile; //2bit, 7.1 Profiles, page 40  
616 - TSAacSampleFrequency sampling_frequency_index; //4bits, Table 35, page 46  
617 - int8_t private_bit; //1bit, can be '0'  
618 - int8_t channel_configuration; //3bits, Table 8  
619 - int8_t original_or_copy; //1bit, can be '0'  
620 - int8_t home; //1bit, can be '0'  
621 -  
622 - // adts_variable_header  
623 - // 28bits  
624 - int8_t copyright_identification_bit; //1bit, can be '0'  
625 - int8_t copyright_identification_start; //1bit, can be '0'  
626 - int16_t frame_length; //13bits  
627 - int16_t adts_buffer_fullness; //11bits, 7FF signals that the bitstream is a variable rate bitstream.  
628 - int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block()  
629 - */  
630 - // profile, 2bits  
631 - adts_header[2] = (codec->aac_profile << 6) & 0xc0;  
632 - // sampling_frequency_index 4bits  
633 - adts_header[2] |= (codec->aac_sample_rate << 2) & 0x3c;  
634 - // channel_configuration 3bits  
635 - adts_header[2] |= (codec->aac_channels >> 2) & 0x01;  
636 - adts_header[3] = (codec->aac_channels << 6) & 0xc0;  
637 - // frame_length 13bits  
638 - adts_header[3] |= (frame_length >> 11) & 0x03;  
639 - adts_header[4] = (frame_length >> 3) & 0xff;  
640 - adts_header[5] = ((frame_length << 5) & 0xe0);  
641 - // adts_buffer_fullness; //11bits  
642 - adts_header[5] |= 0x1f;  
643 -  
644 - // copy to audio buffer  
645 - audio_buffer->append(adts_header, sizeof(adts_header));  
646 - audio_buffer->append(buf->bytes, buf->size);  
647 - }  
648 -  
649 - if ((ret = SrsMpegtsWriter::write_frame(fd, audio_frame, audio_buffer)) != ERROR_SUCCESS) {  
650 - return ret;  
651 - }  
652 - srs_freep(audio_frame);  
653 -  
654 - return ret;  
655 -}  
656 -  
657 -int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sample)  
658 -{  
659 - int ret = ERROR_SUCCESS;  
660 -  
661 - video_frame->dts = time * 90;  
662 - video_frame->pts = video_frame->dts + sample->cts * 90;  
663 - video_frame->pid = TS_VIDEO_PID;  
664 - video_frame->sid = TS_VIDEO_AVC;  
665 - video_frame->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame;  
666 -  
667 - static u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };  
668 - video_buffer->append(aud_nal, sizeof(aud_nal));  
669 -  
670 - bool sps_pps_sent = false;  
671 - for (int i = 0; i < sample->nb_buffers; i++) {  
672 - SrsCodecBuffer* buf = &sample->buffers[i];  
673 - int32_t size = buf->size;  
674 -  
675 - if (!buf->bytes || size <= 0) {  
676 - ret = ERROR_HLS_AVC_SAMPLE_SIZE;  
677 - srs_error("invalid avc sample length=%d, ret=%d", size, ret);  
678 - return ret;  
679 - }  
680 -  
681 - // 5bits, 7.3.1 NAL unit syntax,  
682 - // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.  
683 - u_int8_t nal_unit_type;  
684 - nal_unit_type = *buf->bytes;  
685 - nal_unit_type &= 0x1f;  
686 -  
687 - // Table 7-1 – NAL unit type codes, page 61  
688 - // 1: Coded slice  
689 - if (nal_unit_type == 1) {  
690 - sps_pps_sent = false;  
691 - }  
692 - // 5: Coded slice of an IDR picture.  
693 - // insert sps/pps before IDR or key frame is ok.  
694 - if (nal_unit_type == 5 && !sps_pps_sent) {  
695 - //if (video_frame->key && !sps_pps_sent) {  
696 - sps_pps_sent = true;  
697 -  
698 - // ngx_rtmp_hls_append_sps_pps  
699 - if (codec->sequenceParameterSetLength > 0) {  
700 - // AnnexB prefix  
701 - video_buffer->append(aud_nal, 4);  
702 - // sps  
703 - video_buffer->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength);  
704 - }  
705 - if (codec->pictureParameterSetLength > 0) {  
706 - // AnnexB prefix  
707 - video_buffer->append(aud_nal, 4);  
708 - // pps  
709 - video_buffer->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength);  
710 - }  
711 - }  
712 -  
713 - // sample start prefix, '00 00 00 01' or '00 00 01'  
714 - u_int8_t* p = aud_nal + 1;  
715 - u_int8_t* end = p + 3;  
716 -  
717 - // first AnnexB prefix is long (4 bytes)  
718 - if (i == 0) {  
719 - p = aud_nal;  
720 - }  
721 - video_buffer->append(p, end - p);  
722 -  
723 - // sample data  
724 - video_buffer->append(buf->bytes, buf->size);  
725 - }  
726 -  
727 - if ((ret = SrsMpegtsWriter::write_frame(fd, video_frame, video_buffer)) != ERROR_SUCCESS) {  
728 - return ret;  
729 - }  
730 -  
731 - return ret;  
732 -}  
733 -  
734 -void SrsTSMuxer::close()  
735 -{  
736 - if (fd > 0) {  
737 - ::close(fd);  
738 - fd = -1;  
739 - }  
740 -}  
741 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_hls.hpp>
  25 +
  26 +#include <sys/types.h>
  27 +#include <sys/stat.h>
  28 +#include <fcntl.h>
  29 +#include <stdlib.h>
  30 +#include <string.h>
  31 +
  32 +#include <srs_core_error.hpp>
  33 +#include <srs_core_codec.hpp>
  34 +#include <srs_core_amf0.hpp>
  35 +#include <srs_core_protocol.hpp>
  36 +#include <srs_core_config.hpp>
  37 +
  38 +SrsHLS::SrsHLS()
  39 +{
  40 + hls_enabled = false;
  41 + codec = new SrsCodec();
  42 + sample = new SrsCodecSample();
  43 + muxer = NULL;
  44 +}
  45 +
  46 +SrsHLS::~SrsHLS()
  47 +{
  48 + srs_freep(codec);
  49 + srs_freep(sample);
  50 + srs_freep(muxer);
  51 +}
  52 +
  53 +int SrsHLS::on_publish(std::string _vhost)
  54 +{
  55 + int ret = ERROR_SUCCESS;
  56 +
  57 + if (muxer) {
  58 + ret = ERROR_HLS_BUSY;
  59 + srs_error("hls is busy, something error, "
  60 + "vhost=%s, ret=%d", _vhost.c_str(), ret);
  61 + return ret;
  62 + }
  63 +
  64 + vhost = _vhost;
  65 + muxer = new SrsTSMuxer();
  66 +
  67 + // try to open the HLS muxer
  68 + SrsConfDirective* conf = config->get_hls(vhost);
  69 + if (!conf && conf->arg0() == "off") {
  70 + return ret;
  71 + }
  72 +
  73 + // TODO: check the audio and video, ensure both exsists.
  74 + // for use fixed mpegts header specifeid the audio and video pid.
  75 +
  76 + hls_enabled = true;
  77 +
  78 + std::string path = SRS_CONF_DEFAULT_HLS_PATH;
  79 + if ((conf = config->get_hls_path(vhost)) != NULL) {
  80 + path = conf->arg0();
  81 + }
  82 +
  83 + // TODO: generate by m3u8 muxer.
  84 + path += "/1.ts";
  85 +
  86 + if ((ret = muxer->open(path)) != ERROR_SUCCESS) {
  87 + srs_error("open hls muxer failed. ret=%d", ret);
  88 + return ret;
  89 + }
  90 +
  91 + return ret;
  92 +}
  93 +
  94 +void SrsHLS::on_unpublish()
  95 +{
  96 + hls_enabled = false;
  97 + muxer->close();
  98 + srs_freep(muxer);
  99 +}
  100 +
  101 +int SrsHLS::on_meta_data(SrsOnMetaDataPacket* metadata)
  102 +{
  103 + int ret = ERROR_SUCCESS;
  104 +
  105 + if (!metadata || !metadata->metadata) {
  106 + srs_trace("no metadata persent, hls ignored it.");
  107 + return ret;
  108 + }
  109 +
  110 + SrsAmf0Object* obj = metadata->metadata;
  111 + if (obj->size() <= 0) {
  112 + srs_trace("no metadata persent, hls ignored it.");
  113 + return ret;
  114 + }
  115 +
  116 + // finger out the codec info from metadata if possible.
  117 + SrsAmf0Any* prop = NULL;
  118 +
  119 + if ((prop = obj->get_property("duration")) != NULL && prop->is_number()) {
  120 + codec->duration = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  121 + }
  122 + if ((prop = obj->get_property("width")) != NULL && prop->is_number()) {
  123 + codec->width = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  124 + }
  125 + if ((prop = obj->get_property("height")) != NULL && prop->is_number()) {
  126 + codec->height = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  127 + }
  128 + if ((prop = obj->get_property("framerate")) != NULL && prop->is_number()) {
  129 + codec->frame_rate = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  130 + }
  131 + if ((prop = obj->get_property("videocodecid")) != NULL && prop->is_number()) {
  132 + codec->video_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  133 + }
  134 + if ((prop = obj->get_property("videodatarate")) != NULL && prop->is_number()) {
  135 + codec->video_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
  136 + }
  137 +
  138 + if ((prop = obj->get_property("audiocodecid")) != NULL && prop->is_number()) {
  139 + codec->audio_codec_id = (int)srs_amf0_convert<SrsAmf0Number>(prop)->value;
  140 + }
  141 + if ((prop = obj->get_property("audiodatarate")) != NULL && prop->is_number()) {
  142 + codec->audio_data_rate = (int)(1000 * srs_amf0_convert<SrsAmf0Number>(prop)->value);
  143 + }
  144 +
  145 + // ignore the following, for each flv/rtmp packet contains them:
  146 + // audiosamplerate, sample->sound_rate
  147 + // audiosamplesize, sample->sound_size
  148 + // stereo, sample->sound_type
  149 +
  150 + return ret;
  151 +}
  152 +
  153 +int SrsHLS::on_audio(SrsCommonMessage* audio)
  154 +{
  155 + int ret = ERROR_SUCCESS;
  156 +
  157 + sample->clear();
  158 + if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
  159 + return ret;
  160 + }
  161 +
  162 + if (codec->audio_codec_id != SrsCodecAudioAAC) {
  163 + return ret;
  164 + }
  165 +
  166 + // TODO: maybe donot need to demux the aac?
  167 + if (!hls_enabled) {
  168 + return ret;
  169 + }
  170 +
  171 + // ignore sequence header
  172 + if (sample->aac_packet_type == SrsCodecAudioTypeSequenceHeader) {
  173 + return ret;
  174 + }
  175 +
  176 + u_int32_t timestamp = audio->header.timestamp;
  177 + // TODO: correct the timestamp.
  178 +
  179 + if ((ret = muxer->write_audio(timestamp, codec, sample)) != ERROR_SUCCESS) {
  180 + return ret;
  181 + }
  182 +
  183 + return ret;
  184 +}
  185 +
  186 +int SrsHLS::on_video(SrsCommonMessage* video)
  187 +{
  188 + int ret = ERROR_SUCCESS;
  189 +
  190 + sample->clear();
  191 + if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) {
  192 + return ret;
  193 + }
  194 +
  195 + if (codec->video_codec_id != SrsCodecVideoAVC) {
  196 + return ret;
  197 + }
  198 +
  199 + // TODO: maybe donot need to demux the avc?
  200 + if (!hls_enabled) {
  201 + return ret;
  202 + }
  203 +
  204 + // ignore sequence header
  205 + if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame && sample->avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {
  206 + return ret;
  207 + }
  208 +
  209 + u_int32_t timestamp = video->header.timestamp;
  210 + // TODO: correct the timestamp.
  211 +
  212 + if ((ret = muxer->write_video(timestamp, codec, sample)) != ERROR_SUCCESS) {
  213 + return ret;
  214 + }
  215 +
  216 + return ret;
  217 +}
  218 +
  219 +// @see: ngx_rtmp_mpegts_header
  220 +u_int8_t mpegts_header[] = {
  221 + /* TS */
  222 + 0x47, 0x40, 0x00, 0x10, 0x00,
  223 + /* PSI */
  224 + 0x00, 0xb0, 0x0d, 0x00, 0x01, 0xc1, 0x00, 0x00,
  225 + /* PAT */
  226 + 0x00, 0x01, 0xf0, 0x01,
  227 + /* CRC */
  228 + 0x2e, 0x70, 0x19, 0x05,
  229 + /* stuffing 167 bytes */
  230 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  231 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  232 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  233 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  234 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  235 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  236 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  237 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  238 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  239 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  240 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  241 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  242 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  243 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  244 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  245 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  246 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  247 +
  248 + /* TS */
  249 + 0x47, 0x50, 0x01, 0x10, 0x00,
  250 + /* PSI */
  251 + 0x02, 0xb0, 0x17, 0x00, 0x01, 0xc1, 0x00, 0x00,
  252 + /* PMT */
  253 + 0xe1, 0x00,
  254 + 0xf0, 0x00,
  255 + 0x1b, 0xe1, 0x00, 0xf0, 0x00, /* h264, pid=0x100=256 */
  256 + 0x0f, 0xe1, 0x01, 0xf0, 0x00, /* aac, pid=0x101=257 */
  257 + /*0x03, 0xe1, 0x01, 0xf0, 0x00,*/ /* mp3 */
  258 + /* CRC */
  259 + 0x2f, 0x44, 0xb9, 0x9b, /* crc for aac */
  260 + /*0x4e, 0x59, 0x3d, 0x1e,*/ /* crc for mp3 */
  261 + /* stuffing 157 bytes */
  262 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  263 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  264 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  265 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  266 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  267 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  268 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  269 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  270 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  271 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  272 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  273 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  274 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  275 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  276 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  277 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  278 +};
  279 +
  280 +// @see: NGX_RTMP_HLS_DELAY,
  281 +// 63000: 700ms, ts_tbn=90000
  282 +#define SRS_HLS_DELAY 63000
  283 +
  284 +// @see: ngx_rtmp_SrsMpegtsFrame_t
  285 +struct SrsMpegtsFrame
  286 +{
  287 + int64_t pts;
  288 + int64_t dts;
  289 + int pid;
  290 + int sid;
  291 + int cc;
  292 + bool key;
  293 +
  294 + SrsMpegtsFrame()
  295 + {
  296 + pts = dts = 0;
  297 + pid = sid = cc = 0;
  298 + key = false;
  299 + }
  300 +};
  301 +
  302 +// @see: ngx_rtmp_mpegts.c
  303 +// TODO: support full mpegts feature in future.
  304 +class SrsMpegtsWriter
  305 +{
  306 +public:
  307 + static int write_header(int fd)
  308 + {
  309 + int ret = ERROR_SUCCESS;
  310 +
  311 + if (::write(fd, mpegts_header, sizeof(mpegts_header)) != sizeof(mpegts_header)) {
  312 + ret = ERROR_HLS_WRITE_FAILED;
  313 + srs_error("write ts file header failed. ret=%d", ret);
  314 + return ret;
  315 + }
  316 +
  317 + return ret;
  318 + }
  319 + static int write_frame(int fd, SrsMpegtsFrame* frame, SrsCodecBuffer* buffer)
  320 + {
  321 + int ret = ERROR_SUCCESS;
  322 +
  323 + if (!buffer->bytes || buffer->size <= 0) {
  324 + return ret;
  325 + }
  326 +
  327 + char* last = buffer->bytes + buffer->size;
  328 + char* pos = buffer->bytes;
  329 +
  330 + bool first = true;
  331 + while (pos < last) {
  332 + static char packet[188];
  333 + char* p = packet;
  334 +
  335 + frame->cc++;
  336 +
  337 + // sync_byte; //8bits
  338 + *p++ = 0x47;
  339 + // pid; //13bits
  340 + *p++ = (frame->pid >> 8) & 0x1f;
  341 + // payload_unit_start_indicator; //1bit
  342 + if (first) {
  343 + p[-1] |= 0x40;
  344 + }
  345 + *p++ = frame->pid;
  346 +
  347 + // transport_scrambling_control; //2bits
  348 + // adaption_field_control; //2bits, 0x01: PayloadOnly
  349 + // continuity_counter; //4bits
  350 + *p++ = 0x10 | (frame->cc & 0x0f);
  351 +
  352 + if (first) {
  353 + first = false;
  354 + if (frame->key) {
  355 + p[-1] |= 0x20; // Both Adaption and Payload
  356 + *p++ = 7; // size
  357 + *p++ = 0x50; // random access + PCR
  358 + p = write_pcr(p, frame->dts - SRS_HLS_DELAY);
  359 + }
  360 +
  361 + // PES header
  362 + // packet_start_code_prefix; //24bits, '00 00 01'
  363 + *p++ = 0x00;
  364 + *p++ = 0x00;
  365 + *p++ = 0x01;
  366 + //8bits
  367 + *p++ = frame->sid;
  368 +
  369 + // pts(33bits) need 5bytes.
  370 + u_int8_t header_size = 5;
  371 + u_int8_t flags = 0x80; // pts
  372 +
  373 + // dts(33bits) need 5bytes also
  374 + if (frame->dts != frame->pts) {
  375 + header_size += 5;
  376 + flags |= 0x40; // dts
  377 + }
  378 +
  379 + // 3bytes: flag fields from PES_packet_length to PES_header_data_length
  380 + int pes_size = (last - pos) + header_size + 3;
  381 + if (pes_size > 0xffff) {
  382 + /**
  383 + * when actual packet length > 0xffff(65535),
  384 + * which exceed the max u_int16_t packet length,
  385 + * use 0 packet length, the next unit start indicates the end of packet.
  386 + */
  387 + pes_size = 0;
  388 + }
  389 +
  390 + // PES_packet_length; //16bits
  391 + *p++ = (pes_size >> 8);
  392 + *p++ = pes_size;
  393 +
  394 + // PES_scrambling_control; //2bits, '10'
  395 + // PES_priority; //1bit
  396 + // data_alignment_indicator; //1bit
  397 + // copyright; //1bit
  398 + // original_or_copy; //1bit
  399 + *p++ = 0x80; /* H222 */
  400 +
  401 + // PTS_DTS_flags; //2bits
  402 + // ESCR_flag; //1bit
  403 + // ES_rate_flag; //1bit
  404 + // DSM_trick_mode_flag; //1bit
  405 + // additional_copy_info_flag; //1bit
  406 + // PES_CRC_flag; //1bit
  407 + // PES_extension_flag; //1bit
  408 + *p++ = flags;
  409 +
  410 + // PES_header_data_length; //8bits
  411 + *p++ = header_size;
  412 +
  413 + // pts; // 33bits
  414 + p = write_pts(p, flags >> 6, frame->pts + SRS_HLS_DELAY);
  415 +
  416 + // dts; // 33bits
  417 + if (frame->dts != frame->pts) {
  418 + p = write_pts(p, 1, frame->dts + SRS_HLS_DELAY);
  419 + }
  420 + }
  421 +
  422 + int body_size = sizeof(packet) - (p - packet);
  423 + int in_size = last - pos;
  424 +
  425 + if (body_size <= in_size) {
  426 + memcpy(p, pos, body_size);
  427 + pos += body_size;
  428 + } else {
  429 + p = fill_stuff(p, packet, body_size, in_size);
  430 + memcpy(p, pos, in_size);
  431 + pos = last;
  432 + }
  433 +
  434 + // write ts packet
  435 + if (::write(fd, packet, sizeof(packet)) != sizeof(packet)) {
  436 + ret = ERROR_HLS_WRITE_FAILED;
  437 + srs_error("write ts file failed. ret=%d", ret);
  438 + return ret;
  439 + }
  440 + }
  441 +
  442 + // write success, clear and free the buffer
  443 + buffer->free();
  444 +
  445 + return ret;
  446 + }
  447 +private:
  448 + static char* fill_stuff(char* pes_body_end, char* packet, int body_size, int in_size)
  449 + {
  450 + char* p = pes_body_end;
  451 +
  452 + // insert the stuff bytes before PES body
  453 + int stuff_size = (body_size - in_size);
  454 +
  455 + // adaption_field_control; //2bits
  456 + if (packet[3] & 0x20) {
  457 + // has adaptation
  458 + // packet[4]: adaption_field_length
  459 + // packet[5]: adaption field data
  460 + // base: start of PES body
  461 + char* base = &packet[5] + packet[4];
  462 + int len = p - base;
  463 + p = (char*)memmove(base + stuff_size, base, len) + len;
  464 + // increase the adaption field size.
  465 + packet[4] += stuff_size;
  466 +
  467 + return p;
  468 + }
  469 +
  470 + // create adaption field.
  471 + // adaption_field_control; //2bits
  472 + packet[3] |= 0x20;
  473 + // base: start of PES body
  474 + char* base = &packet[4];
  475 + int len = p - base;
  476 + p = (char*)memmove(base + stuff_size, base, len) + len;
  477 + // adaption_field_length; //8bits
  478 + packet[4] = (stuff_size - 1);
  479 + if (stuff_size >= 2) {
  480 + // adaption field flags.
  481 + packet[5] = 0;
  482 + // adaption data.
  483 + if (stuff_size > 2) {
  484 + memset(&packet[6], 0xff, stuff_size - 2);
  485 + }
  486 + }
  487 +
  488 + return p;
  489 + }
  490 + static char* write_pcr(char* p, int64_t pcr)
  491 + {
  492 + *p++ = (char) (pcr >> 25);
  493 + *p++ = (char) (pcr >> 17);
  494 + *p++ = (char) (pcr >> 9);
  495 + *p++ = (char) (pcr >> 1);
  496 + *p++ = (char) (pcr << 7 | 0x7e);
  497 + *p++ = 0;
  498 +
  499 + return p;
  500 + }
  501 + static char* write_pts(char* p, u_int8_t fb, int64_t pts)
  502 + {
  503 + int32_t val;
  504 +
  505 + val = fb << 4 | (((pts >> 30) & 0x07) << 1) | 1;
  506 + *p++ = val;
  507 +
  508 + val = (((pts >> 15) & 0x7fff) << 1) | 1;
  509 + *p++ = (val >> 8);
  510 + *p++ = val;
  511 +
  512 + val = (((pts) & 0x7fff) << 1) | 1;
  513 + *p++ = (val >> 8);
  514 + *p++ = val;
  515 +
  516 + return p;
  517 + }
  518 +};
  519 +
  520 +// the mpegts header specifed the video/audio pid.
  521 +#define TS_VIDEO_PID 256
  522 +#define TS_AUDIO_PID 257
  523 +
  524 +// ts aac stream id.
  525 +#define TS_AUDIO_AAC 0xc0
  526 +// ts avc stream id.
  527 +#define TS_VIDEO_AVC 0xe0
  528 +
  529 +SrsTSMuxer::SrsTSMuxer()
  530 +{
  531 + fd = -1;
  532 +
  533 + audio_buffer = new SrsCodecBuffer();
  534 + video_buffer = new SrsCodecBuffer();
  535 +
  536 + audio_frame = new SrsMpegtsFrame();
  537 + video_frame = new SrsMpegtsFrame();
  538 +}
  539 +
  540 +SrsTSMuxer::~SrsTSMuxer()
  541 +{
  542 + close();
  543 +
  544 + audio_buffer->free();
  545 + video_buffer->free();
  546 +
  547 + srs_freep(audio_buffer);
  548 + srs_freep(video_buffer);
  549 +
  550 + srs_freep(audio_frame);
  551 + srs_freep(video_frame);
  552 +}
  553 +
  554 +int SrsTSMuxer::open(std::string _path)
  555 +{
  556 + int ret = ERROR_SUCCESS;
  557 +
  558 + path = _path;
  559 +
  560 + close();
  561 +
  562 + int flags = O_CREAT|O_WRONLY|O_TRUNC;
  563 + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
  564 + if ((fd = ::open(path.c_str(), flags, mode)) < 0) {
  565 + ret = ERROR_HLS_OPEN_FAILED;
  566 + srs_error("open ts file %s failed. ret=%d", path.c_str(), ret);
  567 + return ret;
  568 + }
  569 +
  570 + // write mpegts header
  571 + if ((ret = SrsMpegtsWriter::write_header(fd)) != ERROR_SUCCESS) {
  572 + return ret;
  573 + }
  574 +
  575 + return ret;
  576 +}
  577 +
  578 +int SrsTSMuxer::write_audio(u_int32_t time, SrsCodec* codec, SrsCodecSample* sample)
  579 +{
  580 + int ret = ERROR_SUCCESS;
  581 +
  582 + audio_frame->dts = audio_frame->pts = time * 90;
  583 + audio_frame->pid = TS_AUDIO_PID;
  584 + audio_frame->sid = TS_AUDIO_AAC;
  585 +
  586 + for (int i = 0; i < sample->nb_buffers; i++) {
  587 + SrsCodecBuffer* buf = &sample->buffers[i];
  588 + int32_t size = buf->size;
  589 +
  590 + if (!buf->bytes || size <= 0 || size > 0x1fff) {
  591 + ret = ERROR_HLS_AAC_FRAME_LENGTH;
  592 + srs_error("invalid aac frame length=%d, ret=%d", size, ret);
  593 + return ret;
  594 + }
  595 +
  596 + // the frame length is the AAC raw data plus the adts header size.
  597 + int32_t frame_length = size + 7;
  598 +
  599 + // AAC-ADTS
  600 + // 6.2 Audio Data Transport Stream, ADTS
  601 + // in aac-iso-13818-7.pdf, page 26.
  602 + // fixed 7bytes header
  603 + static u_int8_t adts_header[7] = {0xff, 0xf1, 0x00, 0x00, 0x00, 0x0f, 0xfc};
  604 + /*
  605 + // adts_fixed_header
  606 + // 2B, 16bits
  607 + int16_t syncword; //12bits, '1111 1111 1111'
  608 + int8_t ID; //1bit, '0'
  609 + int8_t layer; //2bits, '00'
  610 + int8_t protection_absent; //1bit, can be '1'
  611 + // 12bits
  612 + int8_t profile; //2bit, 7.1 Profiles, page 40
  613 + TSAacSampleFrequency sampling_frequency_index; //4bits, Table 35, page 46
  614 + int8_t private_bit; //1bit, can be '0'
  615 + int8_t channel_configuration; //3bits, Table 8
  616 + int8_t original_or_copy; //1bit, can be '0'
  617 + int8_t home; //1bit, can be '0'
  618 +
  619 + // adts_variable_header
  620 + // 28bits
  621 + int8_t copyright_identification_bit; //1bit, can be '0'
  622 + int8_t copyright_identification_start; //1bit, can be '0'
  623 + int16_t frame_length; //13bits
  624 + int16_t adts_buffer_fullness; //11bits, 7FF signals that the bitstream is a variable rate bitstream.
  625 + int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block()
  626 + */
  627 + // profile, 2bits
  628 + adts_header[2] = (codec->aac_profile << 6) & 0xc0;
  629 + // sampling_frequency_index 4bits
  630 + adts_header[2] |= (codec->aac_sample_rate << 2) & 0x3c;
  631 + // channel_configuration 3bits
  632 + adts_header[2] |= (codec->aac_channels >> 2) & 0x01;
  633 + adts_header[3] = (codec->aac_channels << 6) & 0xc0;
  634 + // frame_length 13bits
  635 + adts_header[3] |= (frame_length >> 11) & 0x03;
  636 + adts_header[4] = (frame_length >> 3) & 0xff;
  637 + adts_header[5] = ((frame_length << 5) & 0xe0);
  638 + // adts_buffer_fullness; //11bits
  639 + adts_header[5] |= 0x1f;
  640 +
  641 + // copy to audio buffer
  642 + audio_buffer->append(adts_header, sizeof(adts_header));
  643 + audio_buffer->append(buf->bytes, buf->size);
  644 + }
  645 +
  646 + if ((ret = SrsMpegtsWriter::write_frame(fd, audio_frame, audio_buffer)) != ERROR_SUCCESS) {
  647 + return ret;
  648 + }
  649 +
  650 + return ret;
  651 +}
  652 +
  653 +int SrsTSMuxer::write_video(u_int32_t time, SrsCodec* codec, SrsCodecSample* sample)
  654 +{
  655 + int ret = ERROR_SUCCESS;
  656 +
  657 + video_frame->dts = time * 90;
  658 + video_frame->pts = video_frame->dts + sample->cts * 90;
  659 + video_frame->pid = TS_VIDEO_PID;
  660 + video_frame->sid = TS_VIDEO_AVC;
  661 + video_frame->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame;
  662 +
  663 + static u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };
  664 + video_buffer->append(aud_nal, sizeof(aud_nal));
  665 +
  666 + bool sps_pps_sent = false;
  667 + for (int i = 0; i < sample->nb_buffers; i++) {
  668 + SrsCodecBuffer* buf = &sample->buffers[i];
  669 + int32_t size = buf->size;
  670 +
  671 + if (!buf->bytes || size <= 0) {
  672 + ret = ERROR_HLS_AVC_SAMPLE_SIZE;
  673 + srs_error("invalid avc sample length=%d, ret=%d", size, ret);
  674 + return ret;
  675 + }
  676 +
  677 + // 5bits, 7.3.1 NAL unit syntax,
  678 + // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
  679 + u_int8_t nal_unit_type;
  680 + nal_unit_type = *buf->bytes;
  681 + nal_unit_type &= 0x1f;
  682 +
  683 + // Table 7-1 – NAL unit type codes, page 61
  684 + // 1: Coded slice
  685 + if (nal_unit_type == 1) {
  686 + sps_pps_sent = false;
  687 + }
  688 + // 5: Coded slice of an IDR picture.
  689 + // insert sps/pps before IDR or key frame is ok.
  690 + if (nal_unit_type == 5 && !sps_pps_sent) {
  691 + //if (video_frame->key && !sps_pps_sent) {
  692 + sps_pps_sent = true;
  693 +
  694 + // ngx_rtmp_hls_append_sps_pps
  695 + if (codec->sequenceParameterSetLength > 0) {
  696 + // AnnexB prefix
  697 + video_buffer->append(aud_nal, 4);
  698 + // sps
  699 + video_buffer->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength);
  700 + }
  701 + if (codec->pictureParameterSetLength > 0) {
  702 + // AnnexB prefix
  703 + video_buffer->append(aud_nal, 4);
  704 + // pps
  705 + video_buffer->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength);
  706 + }
  707 + }
  708 +
  709 + // sample start prefix, '00 00 00 01' or '00 00 01'
  710 + u_int8_t* p = aud_nal + 1;
  711 + u_int8_t* end = p + 3;
  712 +
  713 + // first AnnexB prefix is long (4 bytes)
  714 + if (i == 0) {
  715 + p = aud_nal;
  716 + }
  717 + video_buffer->append(p, end - p);
  718 +
  719 + // sample data
  720 + video_buffer->append(buf->bytes, buf->size);
  721 + }
  722 +
  723 + if ((ret = SrsMpegtsWriter::write_frame(fd, video_frame, video_buffer)) != ERROR_SUCCESS) {
  724 + return ret;
  725 + }
  726 +
  727 + return ret;
  728 +}
  729 +
  730 +void SrsTSMuxer::close()
  731 +{
  732 + if (fd > 0) {
  733 + ::close(fd);
  734 + fd = -1;
  735 + }
  736 +}
  737 +