Blame view

trunk/src/app/srs_app_hls.cpp 45.1 KB
1 2 3
/*
The MIT License (MIT)
4
Copyright (c) 2013-2014 winlin
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
24
#include <srs_app_hls.hpp>
25
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/**
* the public data, event HLS disable, others can use it.
*/
// 0 = 5.5 kHz = 5512 Hz
// 1 = 11 kHz = 11025 Hz
// 2 = 22 kHz = 22050 Hz
// 3 = 44 kHz = 44100 Hz
int flv_sample_rates[] = {5512, 11025, 22050, 44100};

// the sample rates in the codec,
// in the sequence header.
int aac_sample_rates[] = 
{
    96000, 88200, 64000, 48000,
    44100, 32000, 24000, 22050,
    16000, 12000, 11025,  8000,
    7350,     0,     0,    0
};

/**
* the HLS section, only available when HLS enabled.
*/
48
#ifdef SRS_AUTO_HLS
49
50 51 52 53 54 55
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
56
#include <algorithm>
57
using namespace std;
58
59
#include <srs_kernel_error.hpp>
winlin authored
60
#include <srs_kernel_codec.hpp>
61
#include <srs_protocol_amf0.hpp>
62
#include <srs_protocol_stack.hpp>
63 64
#include <srs_app_config.hpp>
#include <srs_app_source.hpp>
65
#include <srs_core_autofree.hpp>
66
#include <srs_protocol_rtmp.hpp>
67
#include <srs_app_pithy_print.hpp>
68
#include <srs_kernel_utility.hpp>
69
#include <srs_app_avc_aac.hpp>
70
#include <srs_kernel_file.hpp>
71
#include <srs_protocol_buffer.hpp>
72
winlin authored
73
// max PES packets size to flush the video.
74
#define SRS_AUTO_HLS_AUDIO_CACHE_SIZE 1024 * 1024
winlin authored
75
76
// drop the segment when duration of ts too small.
77
#define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100
78
winlin authored
79 80
// @see: NGX_RTMP_HLS_DELAY, 
// 63000: 700ms, ts_tbn=90000
81
#define SRS_AUTO_HLS_DELAY 63000
82
winlin authored
83 84 85
// the mpegts header specifed the video/audio pid.
#define TS_VIDEO_PID 256
#define TS_AUDIO_PID 257
86
winlin authored
87 88 89 90
// ts aac stream id.
#define TS_AUDIO_AAC 0xc0
// ts avc stream id.
#define TS_VIDEO_AVC 0xe0
91
92 93 94 95 96 97 98 99
// @see: ngx_rtmp_hls_audio
/* We assume here AAC frame size is 1024
 * Need to handle AAC frames with frame size of 960 */
#define _SRS_AAC_SAMPLE_SIZE 1024

// in ms, for HLS aac sync time.
#define SRS_CONF_DEFAULT_AAC_SYNC 100
// in ms, for HLS aac flush the audio
100
#define SRS_CONF_DEFAULT_AAC_DELAY 100
101
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
// @see: ngx_rtmp_mpegts_header
u_int8_t mpegts_header[] = {
    /* TS */
    0x47, 0x40, 0x00, 0x10, 0x00,
    /* PSI */
    0x00, 0xb0, 0x0d, 0x00, 0x01, 0xc1, 0x00, 0x00,
    /* PAT */
    0x00, 0x01, 0xf0, 0x01,
    /* CRC */
    0x2e, 0x70, 0x19, 0x05,
    /* stuffing 167 bytes */
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    
    /* TS */
    0x47, 0x50, 0x01, 0x10, 0x00,
    /* PSI */
    0x02, 0xb0, 0x17, 0x00, 0x01, 0xc1, 0x00, 0x00,
    /* PMT */
    0xe1, 0x00,
    0xf0, 0x00,
138 139
    // must generate header with/without video, @see:
    // https://github.com/winlinvip/simple-rtmp-server/issues/40
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    0x1b, 0xe1, 0x00, 0xf0, 0x00, /* h264, pid=0x100=256 */
    0x0f, 0xe1, 0x01, 0xf0, 0x00, /* aac, pid=0x101=257 */
    /*0x03, 0xe1, 0x01, 0xf0, 0x00,*/ /* mp3 */
    /* CRC */
    0x2f, 0x44, 0xb9, 0x9b, /* crc for aac */
    /*0x4e, 0x59, 0x3d, 0x1e,*/ /* crc for mp3 */
    /* stuffing 157 bytes */
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

// @see: ngx_rtmp_SrsMpegtsFrame_t
166
class SrsMpegtsFrame
167
{
168 169 170 171 172 173 174
public:
    int64_t         pts;
    int64_t         dts;
    int             pid;
    int             sid;
    int             cc;
    bool            key;
175 176 177 178 179 180 181 182 183 184 185 186 187 188
    
    SrsMpegtsFrame()
    {
        pts = dts = 0;
        pid = sid = cc = 0;
        key = false;
    }
};

// @see: ngx_rtmp_mpegts.c
// TODO: support full mpegts feature in future.
class SrsMpegtsWriter
{
public:
189
    static int write_header(SrsFileWriter* writer)
190 191 192
    {
        int ret = ERROR_SUCCESS;
        
193
        if ((ret = writer->write(mpegts_header, sizeof(mpegts_header), NULL)) != ERROR_SUCCESS) {
194 195 196 197 198 199 200
            ret = ERROR_HLS_WRITE_FAILED;
            srs_error("write ts file header failed. ret=%d", ret);
            return ret;
        }

        return ret;
    }
201
    static int write_frame(SrsFileWriter* writer, SrsMpegtsFrame* frame, SrsBuffer* buffer)
202 203 204
    {
        int ret = ERROR_SUCCESS;
        
205
        if (!buffer->bytes() || buffer->length() <= 0) {
206 207 208
            return ret;
        }
        
209 210
        char* last = buffer->bytes() + buffer->length();
        char* pos = buffer->bytes();
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
        
        bool first = true;
        while (pos < last) {
            static char packet[188];
            char* p = packet;
            
            frame->cc++;
            
            // sync_byte; //8bits
            *p++ = 0x47;
            // pid; //13bits
            *p++ = (frame->pid >> 8) & 0x1f;
            // payload_unit_start_indicator; //1bit
            if (first) {
                p[-1] |= 0x40;
            }
            *p++ = frame->pid;
            
            // transport_scrambling_control; //2bits
            // adaption_field_control; //2bits, 0x01: PayloadOnly
            // continuity_counter; //4bits
            *p++ = 0x10 | (frame->cc & 0x0f);
            
            if (first) {
                first = false;
                if (frame->key) {
                    p[-1] |= 0x20; // Both Adaption and Payload
                    *p++ = 7;    // size
                    *p++ = 0x50; // random access + PCR
240
                    p = write_pcr(p, frame->dts - SRS_AUTO_HLS_DELAY);
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
                }
                
                // PES header
                // packet_start_code_prefix; //24bits, '00 00 01'
                *p++ = 0x00;
                *p++ = 0x00;
                *p++ = 0x01;
                //8bits
                *p++ = frame->sid;
                
                // pts(33bits) need 5bytes.
                u_int8_t header_size = 5;
                u_int8_t flags = 0x80; // pts
                
                // dts(33bits) need 5bytes also
                if (frame->dts != frame->pts) {
                    header_size += 5;
                    flags |= 0x40; // dts
                }
                
                // 3bytes: flag fields from PES_packet_length to PES_header_data_length
                int pes_size = (last - pos) + header_size + 3;
                if (pes_size > 0xffff) {
                    /**
                    * when actual packet length > 0xffff(65535),
                    * which exceed the max u_int16_t packet length,
                    * use 0 packet length, the next unit start indicates the end of packet.
                    */
                    pes_size = 0;
                }
                
                // PES_packet_length; //16bits
                *p++ = (pes_size >> 8);
                *p++ = pes_size;
                
                // PES_scrambling_control; //2bits, '10'
                // PES_priority; //1bit
                // data_alignment_indicator; //1bit
                // copyright; //1bit
                // original_or_copy; //1bit    
                *p++ = 0x80; /* H222 */
                
                // PTS_DTS_flags; //2bits
                // ESCR_flag; //1bit
                // ES_rate_flag; //1bit
                // DSM_trick_mode_flag; //1bit
                // additional_copy_info_flag; //1bit
                // PES_CRC_flag; //1bit
                // PES_extension_flag; //1bit
                *p++ = flags;
                
                // PES_header_data_length; //8bits
                *p++ = header_size;

                // pts; // 33bits
296
                p = write_pts(p, flags >> 6, frame->pts + SRS_AUTO_HLS_DELAY);
297 298 299
                
                // dts; // 33bits
                if (frame->dts != frame->pts) {
300
                    p = write_pts(p, 1, frame->dts + SRS_AUTO_HLS_DELAY);
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
                }
            }
            
            int body_size = sizeof(packet) - (p - packet);
            int in_size = last - pos;
            
            if (body_size <= in_size) {
                memcpy(p, pos, body_size);
                pos += body_size;
            } else {
                p = fill_stuff(p, packet, body_size, in_size);
                memcpy(p, pos, in_size);
                pos = last;
            }
            
            // write ts packet
317
            if ((ret = writer->write(packet, sizeof(packet), NULL)) != ERROR_SUCCESS) {
318 319 320 321 322 323 324 325
                ret = ERROR_HLS_WRITE_FAILED;
                srs_error("write ts file failed. ret=%d", ret);
                return ret;
            }
        }
        
        return ret;
    }
326
private:
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
    static char* fill_stuff(char* pes_body_end, char* packet, int body_size, int in_size)
    {
        char* p = pes_body_end;
        
        // insert the stuff bytes before PES body
        int stuff_size = (body_size - in_size);
        
        // adaption_field_control; //2bits
        if (packet[3] & 0x20) {
            //  has adaptation
            // packet[4]: adaption_field_length
            // packet[5]: adaption field data
            // base: start of PES body
            char* base = &packet[5] + packet[4];
            int len = p - base;
            p = (char*)memmove(base + stuff_size, base, len) + len;
            // increase the adaption field size.
            packet[4] += stuff_size;
            
            return p;
        }

        // create adaption field.
        // adaption_field_control; //2bits
        packet[3] |= 0x20;
        // base: start of PES body
        char* base = &packet[4];
        int len = p - base;
        p = (char*)memmove(base + stuff_size, base, len) + len;
        // adaption_field_length; //8bits
        packet[4] = (stuff_size - 1);
        if (stuff_size >= 2) {
            // adaption field flags.
            packet[5] = 0;
            // adaption data.
            if (stuff_size > 2) {
                memset(&packet[6], 0xff, stuff_size - 2);
            }
        }
        
        return p;
    }
    static char* write_pcr(char* p, int64_t pcr)
    {
        *p++ = (char) (pcr >> 25);
        *p++ = (char) (pcr >> 17);
        *p++ = (char) (pcr >> 9);
        *p++ = (char) (pcr >> 1);
        *p++ = (char) (pcr << 7 | 0x7e);
        *p++ = 0;
    
        return p;
    }
    static char* write_pts(char* p, u_int8_t fb, int64_t pts)
    {
        int32_t val;
    
        val = fb << 4 | (((pts >> 30) & 0x07) << 1) | 1;
        *p++ = val;
    
        val = (((pts >> 15) & 0x7fff) << 1) | 1;
        *p++ = (val >> 8);
        *p++ = val;
    
        val = (((pts) & 0x7fff) << 1) | 1;
        *p++ = (val >> 8);
        *p++ = val;
    
        return p;
    }
397 398
};
399 400 401 402
SrsHlsAacJitter::~SrsHlsAacJitter()
{
}
403
int64_t SrsHlsAacJitter::on_buffer_start(int64_t flv_pts, int sample_rate, int aac_sample_rate)
404
{
405
    // use sample rate in flv/RTMP.
406 407
    int flv_sample_rate = flv_sample_rates[sample_rate & 0x03];
408
    // override the sample rate by sequence header
winlin authored
409
    if (aac_sample_rate != __SRS_AAC_SAMPLE_RATE_UNSET) {
410 411 412
        flv_sample_rate = aac_sample_rates[aac_sample_rate];
    }
413 414 415 416 417 418
    // sync time set to 0, donot adjust the aac timestamp.
    if (!sync_ms) {
        return flv_pts;
    }
    
    // @see: ngx_rtmp_hls_audio
419 420
    // drop the rtmp audio packet timestamp, re-calc it by sample rate.
    // 
421 422 423 424
    // resample for the tbn of ts is 90000, flv is 1000,
    // we will lost timestamp if use audio packet timestamp,
    // so we must resample. or audio will corupt in IOS.
    int64_t est_pts = base_pts + nb_samples * 90000LL * _SRS_AAC_SAMPLE_SIZE / flv_sample_rate;
425
    int64_t dpts = (int64_t) (est_pts - flv_pts);
426 427 428

    if (dpts <= (int64_t) sync_ms * 90 && dpts >= (int64_t) sync_ms * -90) {
        srs_info("HLS correct aac pts "
429 430
            "from %"PRId64" to %"PRId64", base=%"PRId64", nb_samples=%d, sample_rate=%d",
            flv_pts, est_pts, nb_samples, flv_sample_rate, base_pts);
431
432 433 434
        nb_samples++;
        
        return est_pts;
435 436 437
    }
    
    // resync
438 439 440 441
    srs_trace("HLS aac resync, dpts=%"PRId64", pts=%"PRId64
        ", base=%"PRId64", nb_samples=%"PRId64", sample_rate=%d",
        dpts, flv_pts, base_pts, nb_samples, flv_sample_rate);
    
442 443 444 445 446 447 448 449
    base_pts = flv_pts;
    nb_samples = 1;
    
    return flv_pts;
}

void SrsHlsAacJitter::on_buffer_continue()
{
450
    nb_samples++;
451 452
}
453 454
SrsTSMuxer::SrsTSMuxer()
{
455
    writer = new SrsFileWriter();
456 457 458 459
}

SrsTSMuxer::~SrsTSMuxer()
{
460
    close();
461
    srs_freep(writer);
462 463
}
464
int SrsTSMuxer::open(string _path)
465
{
466 467 468 469 470 471
    int ret = ERROR_SUCCESS;
    
    path = _path;
    
    close();
    
472
    if ((ret = writer->open(path)) != ERROR_SUCCESS) {
473 474 475 476
        return ret;
    }

    // write mpegts header
477
    if ((ret = SrsMpegtsWriter::write_header(writer)) != ERROR_SUCCESS) {
478 479 480 481
        return ret;
    }
    
    return ret;
482 483
}
484
int SrsTSMuxer::write_audio(SrsMpegtsFrame* af, SrsBuffer* ab)
485
{
486 487
    int ret = ERROR_SUCCESS;
    
488
    if ((ret = SrsMpegtsWriter::write_frame(writer, af, ab)) != ERROR_SUCCESS) {
489 490 491 492
        return ret;
    }
    
    return ret;
493 494
}
495
int SrsTSMuxer::write_video(SrsMpegtsFrame* vf, SrsBuffer* vb)
496
{
497 498
    int ret = ERROR_SUCCESS;
    
499
    if ((ret = SrsMpegtsWriter::write_frame(writer, vf, vb)) != ERROR_SUCCESS) {
500 501 502 503
        return ret;
    }
    
    return ret;
504 505 506 507
}

void SrsTSMuxer::close()
{
508
    writer->close();
509 510
}
511
SrsHlsSegment::SrsHlsSegment()
512
{
513 514 515 516
    duration = 0;
    sequence_no = 0;
    muxer = new SrsTSMuxer();
    segment_start_dts = 0;
winlin authored
517
    is_sequence_header = false;
518 519
}
520
SrsHlsSegment::~SrsHlsSegment()
521
{
522
    srs_freep(muxer);
winlin authored
523
}
524
525
void SrsHlsSegment::update_duration(int64_t current_frame_dts)
winlin authored
526
{
527 528 529 530 531 532 533 534
    // we use video/audio to update segment duration,
    // so when reap segment, some previous audio frame will
    // update the segment duration, which is nagetive,
    // just ignore it.
    if (current_frame_dts < segment_start_dts) {
        return;
    }
    
535
    duration = (current_frame_dts - segment_start_dts) / 90000.0;
536 537
    srs_assert(duration >= 0);
    
538
    return;
539 540
}
winlin authored
541
SrsHlsAacJitter::SrsHlsAacJitter()
542
{
543 544
    base_pts = 0;
    nb_samples = 0;
winlin authored
545
546 547
    // TODO: config it, 0 means no adjust
    sync_ms = SRS_CONF_DEFAULT_AAC_SYNC;
winlin authored
548 549
}
550
SrsHlsMuxer::SrsHlsMuxer()
winlin authored
551
{
552
    hls_fragment = hls_window = 0;
553
    _sequence_no = 0;
554
    current = NULL;
winlin authored
555
}
winlin authored
556
557
SrsHlsMuxer::~SrsHlsMuxer()
winlin authored
558
{
559
    std::vector<SrsHlsSegment*>::iterator it;
560
    for (it = segments.begin(); it != segments.end(); ++it) {
561
        SrsHlsSegment* segment = *it;
562 563 564 565 566
        srs_freep(segment);
    }
    segments.clear();
    
    srs_freep(current);
winlin authored
567 568
}
569 570 571 572 573
int SrsHlsMuxer::sequence_no()
{
    return _sequence_no;
}
574
int SrsHlsMuxer::update_config(
575
    string _app, string _stream, string path, int fragment, int window
winlin authored
576
) {
577 578 579 580 581 582 583 584 585
    int ret = ERROR_SUCCESS;
    
    app = _app;
    stream = _stream;
    hls_path = path;
    hls_fragment = fragment;
    hls_window = window;
    
    return ret;
586 587
}
588
int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
winlin authored
589
{
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
    int ret = ERROR_SUCCESS;
    
    if (current) {
        srs_warn("ignore the segment open, for segment is already open.");
        return ret;
    }
    
    // TODO: create all parents dirs.
    // create dir for app.
    if ((ret = create_dir()) != ERROR_SUCCESS) {
        return ret;
    }
    
    // when segment open, the current segment must be NULL.
    srs_assert(!current);
    
    // new segment.
607
    current = new SrsHlsSegment();
608
    current->sequence_no = _sequence_no++;
609
    current->segment_start_dts = segment_start_dts;
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    
    // generate filename.
    char filename[128];
    snprintf(filename, sizeof(filename), 
        "%s-%d.ts", stream.c_str(), current->sequence_no);
    
    // TODO: use temp file and rename it.
    current->full_path = hls_path;
    current->full_path += "/";
    current->full_path += app;
    current->full_path += "/";
    current->full_path += filename;
    
    // TODO: support base url, and so on.
    current->uri = filename;
    
626 627
    std::string tmp_file = current->full_path + ".tmp";
    if ((ret = current->muxer->open(tmp_file.c_str())) != ERROR_SUCCESS) {
628 629 630
        srs_error("open hls muxer failed. ret=%d", ret);
        return ret;
    }
631 632
    srs_info("open HLS muxer success. path=%s, tmp=%s", 
        current->full_path.c_str(), tmp_file.c_str());
633 634
    
    return ret;
winlin authored
635 636
}
winlin authored
637 638 639 640 641 642 643 644 645 646 647 648 649
int SrsHlsMuxer::on_sequence_header()
{
    int ret = ERROR_SUCCESS;
    
    srs_assert(current);
    
    // set the current segment to sequence header,
    // when close the segement, it will write a discontinuity to m3u8 file.
    current->is_sequence_header = true;
    
    return ret;
}
650 651 652 653 654 655 656
bool SrsHlsMuxer::is_segment_overflow()
{
    srs_assert(current);
    
    return current->duration >= hls_fragment;
}
657
int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsBuffer* ab)
winlin authored
658
{
659 660 661 662 663 664 665 666
    int ret = ERROR_SUCCESS;

    // if current is NULL, segment is not open, ignore the flush event.
    if (!current) {
        srs_warn("flush audio ignored, for segment is not open.");
        return ret;
    }
    
667
    if (ab->length() <= 0) {
668 669 670
        return ret;
    }
    
671 672 673
    // update the duration of segment.
    current->update_duration(af->pts);
    
674 675 676 677 678
    if ((ret = current->muxer->write_audio(af, ab)) != ERROR_SUCCESS) {
        return ret;
    }
    
    // write success, clear and free the buffer
679
    ab->erase(ab->length());
680 681

    return ret;
winlin authored
682 683
}
684
int SrsHlsMuxer::flush_video(SrsMpegtsFrame* /*af*/, SrsBuffer* /*ab*/, SrsMpegtsFrame* vf, SrsBuffer* vb)
winlin authored
685
{
686 687 688 689 690 691 692 693 694 695 696
    int ret = ERROR_SUCCESS;

    // if current is NULL, segment is not open, ignore the flush event.
    if (!current) {
        srs_warn("flush video ignored, for segment is not open.");
        return ret;
    }
    
    srs_assert(current);
    
    // update the duration of segment.
697
    current->update_duration(vf->dts);
698 699 700 701 702
    
    if ((ret = current->muxer->write_video(vf, vb)) != ERROR_SUCCESS) {
        return ret;
    }
    
703
    // write success, clear and free the buffer
704
    vb->erase(vb->length());
705
    
706
    return ret;
winlin authored
707 708
}
709
int SrsHlsMuxer::segment_close(string log_desc)
winlin authored
710
{
711 712 713 714 715 716 717 718 719 720 721
    int ret = ERROR_SUCCESS;
    
    if (!current) {
        srs_warn("ignore the segment close, for segment is not open.");
        return ret;
    }
    
    // when close current segment, the current segment must not be NULL.
    srs_assert(current);

    // assert segment duplicate.
722
    std::vector<SrsHlsSegment*>::iterator it;
723 724 725
    it = std::find(segments.begin(), segments.end(), current);
    srs_assert(it == segments.end());
726
    // valid, add to segments if segment duration is ok
727
    if (current->duration * 1000 >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) {
728
        segments.push_back(current);
729
    
730
        srs_info("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"",
731 732
            log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration, 
            current->segment_start_dts);
733
    
734 735
        // close the muxer of finished segment.
        srs_freep(current->muxer);
736 737 738
        std::string full_path = current->full_path;
        current = NULL;
        
739
        // rename from tmp to real path
740 741
        std::string tmp_file = full_path + ".tmp";
        if (rename(tmp_file.c_str(), full_path.c_str()) < 0) {
742 743
            ret = ERROR_HLS_WRITE_FAILED;
            srs_error("rename ts file failed, %s => %s. ret=%d", 
744
                tmp_file.c_str(), full_path.c_str(), ret);
745 746 747 748
            return ret;
        }
    } else {
        // reuse current segment index.
749
        _sequence_no--;
750 751 752 753 754 755 756 757 758 759
        
        srs_trace("%s drop ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64"",
            log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration, 
            current->segment_start_dts);
        
        // rename from tmp to real path
        std::string tmp_file = current->full_path + ".tmp";
        unlink(tmp_file.c_str());
        
        srs_freep(current);
760
    }
761 762
    
    // the segments to remove
763
    std::vector<SrsHlsSegment*> segment_to_remove;
764 765 766 767 768
    
    // shrink the segments.
    double duration = 0;
    int remove_index = -1;
    for (int i = segments.size() - 1; i >= 0; i--) {
769
        SrsHlsSegment* segment = segments[i];
770 771 772 773 774 775 776 777
        duration += segment->duration;
        
        if ((int)duration > hls_window) {
            remove_index = i;
            break;
        }
    }
    for (int i = 0; i < remove_index && !segments.empty(); i++) {
778
        SrsHlsSegment* segment = *segments.begin();
779 780 781 782 783 784 785 786 787
        segments.erase(segments.begin());
        segment_to_remove.push_back(segment);
    }
    
    // refresh the m3u8, donot contains the removed ts
    ret = refresh_m3u8();

    // remove the ts file.
    for (int i = 0; i < (int)segment_to_remove.size(); i++) {
788
        SrsHlsSegment* segment = segment_to_remove[i];
789 790 791 792 793 794 795 796 797 798 799 800
        unlink(segment->full_path.c_str());
        srs_freep(segment);
    }
    segment_to_remove.clear();
    
    // check ret of refresh m3u8
    if (ret != ERROR_SUCCESS) {
        srs_error("refresh m3u8 failed. ret=%d", ret);
        return ret;
    }
    
    return ret;
winlin authored
801 802
}
803
int SrsHlsMuxer::refresh_m3u8()
winlin authored
804
{
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
    int ret = ERROR_SUCCESS;
    
    std::string m3u8_file = hls_path;
    m3u8_file += "/";
    m3u8_file += app;
    m3u8_file += "/";
    m3u8_file += stream;
    m3u8_file += ".m3u8";
    
    m3u8 = m3u8_file;
    m3u8_file += ".temp";
    
    int fd = -1;
    ret = _refresh_m3u8(fd, m3u8_file);
    if (fd >= 0) {
        close(fd);
        if (rename(m3u8_file.c_str(), m3u8.c_str()) < 0) {
            ret = ERROR_HLS_WRITE_FAILED;
823 824
            srs_error("rename m3u8 file failed. "
                "%s => %s, ret=%d", m3u8_file.c_str(), m3u8.c_str(), ret);
825 826 827 828 829 830 831
        }
    }
    
    // remove the temp file.
    unlink(m3u8_file.c_str());
    
    return ret;
winlin authored
832 833
}
834
int SrsHlsMuxer::_refresh_m3u8(int& fd, string m3u8_file)
winlin authored
835
{
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
    int ret = ERROR_SUCCESS;
    
    // no segments, return.
    if (segments.size() == 0) {
        return ret;
    }
    
    int flags = O_CREAT|O_WRONLY|O_TRUNC;
    mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
    if ((fd = ::open(m3u8_file.c_str(), flags, mode)) < 0) {
        ret = ERROR_HLS_OPEN_FAILED;
        srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret);
        return ret;
    }
    srs_info("open m3u8 file %s success.", m3u8_file.c_str());
    
    // #EXTM3U\n#EXT-X-VERSION:3\n
    char header[] = {
        // #EXTM3U\n
        0x23, 0x45, 0x58, 0x54, 0x4d, 0x33, 0x55, 0xa, 
        // #EXT-X-VERSION:3\n
        0x23, 0x45, 0x58, 0x54, 0x2d, 0x58, 0x2d, 0x56, 0x45, 0x52, 
wenjiegit authored
858 859 860 861
        0x53, 0x49, 0x4f, 0x4e, 0x3a, 0x33, 0xa,
        // #EXT-X-ALLOW-CACHE:NO
        0x23, 0x45, 0x58, 0x54, 0x2d, 0x58, 0x2d, 0x41, 0x4c, 0x4c, 
        0x4f, 0x57, 0x2d, 0x43, 0x41, 0x43, 0x48, 0x45, 0x3a, 0x4e, 0x4f, 0x0a
862 863 864 865 866 867 868 869 870
    };
    if (::write(fd, header, sizeof(header)) != sizeof(header)) {
        ret = ERROR_HLS_WRITE_FAILED;
        srs_error("write m3u8 header failed. ret=%d", ret);
        return ret;
    }
    srs_verbose("write m3u8 header success.");
    
    // #EXT-X-MEDIA-SEQUENCE:4294967295\n
871
    SrsHlsSegment* first = *segments.begin();
872 873 874 875 876 877 878 879 880 881 882
    char sequence[34] = {};
    int len = snprintf(sequence, sizeof(sequence), "#EXT-X-MEDIA-SEQUENCE:%d\n", first->sequence_no);
    if (::write(fd, sequence, len) != len) {
        ret = ERROR_HLS_WRITE_FAILED;
        srs_error("write m3u8 sequence failed. ret=%d", ret);
        return ret;
    }
    srs_verbose("write m3u8 sequence success.");
    
    // #EXT-X-TARGETDURATION:4294967295\n
    int target_duration = 0;
883
    std::vector<SrsHlsSegment*>::iterator it;
884
    for (it = segments.begin(); it != segments.end(); ++it) {
885
        SrsHlsSegment* segment = *it;
886 887 888 889
        target_duration = srs_max(target_duration, (int)segment->duration);
    }
    // TODO: maybe need to take an around value
    target_duration += 1;
winlin authored
890
    char duration[34]; // 23+10+1
891 892 893 894 895 896 897 898 899 900
    len = snprintf(duration, sizeof(duration), "#EXT-X-TARGETDURATION:%d\n", target_duration);
    if (::write(fd, duration, len) != len) {
        ret = ERROR_HLS_WRITE_FAILED;
        srs_error("write m3u8 duration failed. ret=%d", ret);
        return ret;
    }
    srs_verbose("write m3u8 duration success.");
    
    // write all segments
    for (it = segments.begin(); it != segments.end(); ++it) {
901
        SrsHlsSegment* segment = *it;
902
        
winlin authored
903 904 905 906 907 908 909 910 911 912 913 914
        if (segment->is_sequence_header) {
            // #EXT-X-DISCONTINUITY\n
            char ext_discon[22]; // 21+1
            len = snprintf(ext_discon, sizeof(ext_discon), "#EXT-X-DISCONTINUITY\n");
            if (::write(fd, ext_discon, len) != len) {
                ret = ERROR_HLS_WRITE_FAILED;
                srs_error("write m3u8 segment discontinuity failed. ret=%d", ret);
                return ret;
            }
            srs_verbose("write m3u8 segment discontinuity success.");
        }
        
915
        // "#EXTINF:4294967295.208,\n"
winlin authored
916
        char ext_info[25]; // 14+10+1
917 918 919
        len = snprintf(ext_info, sizeof(ext_info), "#EXTINF:%.3f\n", segment->duration);
        if (::write(fd, ext_info, len) != len) {
            ret = ERROR_HLS_WRITE_FAILED;
winlin authored
920
            srs_error("write m3u8 segment info failed. ret=%d", ret);
921 922
            return ret;
        }
winlin authored
923
        srs_verbose("write m3u8 segment info success.");
924 925 926 927 928 929 930 931 932 933 934 935 936 937
        
        // file name
        std::string filename = segment->uri;
        filename += "\n";
        if (::write(fd, filename.c_str(), filename.length()) != (int)filename.length()) {
            ret = ERROR_HLS_WRITE_FAILED;
            srs_error("write m3u8 segment uri failed. ret=%d", ret);
            return ret;
        }
        srs_verbose("write m3u8 segment uri success.");
    }
    srs_info("write m3u8 %s success.", m3u8_file.c_str());
    
    return ret;
938 939
}
940
int SrsHlsMuxer::create_dir()
941
{
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960
    int ret = ERROR_SUCCESS;
    
    std::string app_dir = hls_path;
    app_dir += "/";
    app_dir += app;
    
    // TODO: cleanup the dir when startup.

    mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH;
    if (::mkdir(app_dir.c_str(), mode) < 0) {
        if (errno != EEXIST) {
            ret = ERROR_HLS_CREATE_DIR;
            srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret);
            return ret;
        }
    }
    srs_info("create app dir %s success.", app_dir.c_str());

    return ret;
winlin authored
961 962
}
963
SrsHlsCache::SrsHlsCache()
winlin authored
964
{
965 966
    aac_jitter = new SrsHlsAacJitter();
    
967 968
    ab = new SrsBuffer();
    vb = new SrsBuffer();
969 970 971
    
    af = new SrsMpegtsFrame();
    vf = new SrsMpegtsFrame();
winlin authored
972 973
}
974
SrsHlsCache::~SrsHlsCache()
winlin authored
975
{
976 977
    srs_freep(aac_jitter);
    
978 979
    ab->erase(ab->length());
    vb->erase(vb->length());
980 981 982 983 984 985
    
    srs_freep(ab);
    srs_freep(vb);
    
    srs_freep(af);
    srs_freep(vf);
986
}
987 988 989 990 991 992 993 994

int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment_start_dts)
{
    int ret = ERROR_SUCCESS;

    std::string vhost = req->vhost;
    std::string stream = req->stream;
    std::string app = req->app;
995
    
996 997
    int hls_fragment = (int)_srs_config->get_hls_fragment(vhost);
    int hls_window = (int)_srs_config->get_hls_window(vhost);
998 999 1000 1001
    
    // get the hls path config
    std::string hls_path = _srs_config->get_hls_path(vhost);
    
1002 1003 1004
    // TODO: FIXME: support load exists m3u8, to continue publish stream.
    // for the HLS donot requires the EXT-X-MEDIA-SEQUENCE be monotonically increase.
    
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
    // open muxer
    if ((ret = muxer->update_config(app, stream, hls_path, hls_fragment, hls_window)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer update config failed. ret=%d", ret);
        return ret;
    }
    
    if ((ret = muxer->segment_open(segment_start_dts)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer open segment failed. ret=%d", ret);
        return ret;
    }
    
    return ret;
}

int SrsHlsCache::on_unpublish(SrsHlsMuxer* muxer)
{
    int ret = ERROR_SUCCESS;
    
    if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
        return ret;
    }
    
1028
    if ((ret = muxer->segment_close("unpublish")) != ERROR_SUCCESS) {
1029 1030 1031 1032 1033
        return ret;
    }
    
    return ret;
}
winlin authored
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044

int SrsHlsCache::on_sequence_header(SrsHlsMuxer* muxer)
{
    // TODO: support discontinuity for the same stream
    // currently we reap and insert discontinity when encoder republish,
    // but actually, event when stream is not republish, the 
    // sequence header may change, for example,
    // ffmpeg ingest a external rtmp stream and push to srs,
    // when the sequence header changed, the stream is not republish.
    return muxer->on_sequence_header();
}
1045
    
1046
int SrsHlsCache::write_audio(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t pts, SrsCodecSample* sample)
1047
{
1048 1049 1050
    int ret = ERROR_SUCCESS;
    
    // start buffer, set the af
1051
    if (ab->length() == 0) {
1052
        pts = aac_jitter->on_buffer_start(pts, sample->sound_rate, codec->aac_sample_rate);
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
        
        af->dts = af->pts = audio_buffer_start_pts = pts;
        af->pid = TS_AUDIO_PID;
        af->sid = TS_AUDIO_AAC;
    } else {
        aac_jitter->on_buffer_continue();
    }
    
    // write audio to cache.
    if ((ret = cache_audio(codec, sample)) != ERROR_SUCCESS) {
        return ret;
    }
    
    // flush if buffer exceed max size.
1067
    if (ab->length() > SRS_AUTO_HLS_AUDIO_CACHE_SIZE) {
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
        if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
            return ret;
        }
    }
    // TODO: config it.
    // in ms, audio delay to flush the audios.
    int64_t audio_delay = SRS_CONF_DEFAULT_AAC_DELAY;
    // flush if audio delay exceed
    if (pts - audio_buffer_start_pts > audio_delay * 90) {
        if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
            return ret;
        }
    }
    
1082 1083 1084 1085 1086 1087 1088
    // reap when current source is pure audio.
    // it maybe changed when stream info changed,
    // for example, pure audio when start, audio/video when publishing,
    // pure audio again for audio disabled.
    // so we reap event when the audio incoming when segment overflow.
    // @see https://github.com/winlinvip/simple-rtmp-server/issues/151
    if (muxer->is_segment_overflow()) {
1089
        if ((ret = reap_segment("audio", muxer, af->pts)) != ERROR_SUCCESS) {
1090 1091 1092 1093
            return ret;
        }
    }
    
1094
    return ret;
1095
}
1096
    
1097
int SrsHlsCache::write_video(
1098
    SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t dts, SrsCodecSample* sample)
1099
{
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
    int ret = ERROR_SUCCESS;
    
    // write video to cache.
    if ((ret = cache_video(codec, sample)) != ERROR_SUCCESS) {
        return ret;
    }
    
    vf->dts = dts;
    vf->pts = vf->dts + sample->cts * 90;
    vf->pid = TS_VIDEO_PID;
    vf->sid = TS_VIDEO_AVC;
    vf->key = sample->frame_type == SrsCodecVideoAVCFrameKeyFrame;
    
1113 1114 1115
    // new segment when:
    // 1. base on gop.
    // 2. some gops duration overflow.
1116
    if (vf->key && muxer->is_segment_overflow()) {
1117
        if ((ret = reap_segment("video", muxer, vf->dts)) != ERROR_SUCCESS) {
1118 1119 1120 1121
            return ret;
        }
    }
    
1122 1123 1124 1125 1126 1127
    // flush video when got one
    if ((ret = muxer->flush_video(af, ab, vf, vb)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer flush video failed. ret=%d", ret);
        return ret;
    }
    
1128 1129 1130
    return ret;
}
1131
int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segment_start_dts)
1132 1133 1134
{
    int ret = ERROR_SUCCESS;
1135
    if ((ret = muxer->segment_close(log_desc)) != ERROR_SUCCESS) {
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
        srs_error("m3u8 muxer close segment failed. ret=%d", ret);
        return ret;
    }
    
    if ((ret = muxer->segment_open(segment_start_dts)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer open segment failed. ret=%d", ret);
        return ret;
    }

    // TODO: flush audio before or after segment?
    // segment open, flush the audio.
    // @see: ngx_rtmp_hls_open_fragment
    /* start fragment with audio to make iPhone happy */
    if ((ret = muxer->flush_audio(af, ab)) != ERROR_SUCCESS) {
        srs_error("m3u8 muxer flush audio failed. ret=%d", ret);
        return ret;
    }
1153 1154
    
    return ret;
1155 1156
}
1157
int SrsHlsCache::cache_audio(SrsAvcAacCodec* codec, SrsCodecSample* sample)
1158
{
1159 1160
    int ret = ERROR_SUCCESS;
    
1161 1162 1163
    for (int i = 0; i < sample->nb_sample_units; i++) {
        SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
        int32_t size = sample_unit->size;
1164
        
1165
        if (!sample_unit->bytes || size <= 0 || size > 0x1fff) {
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
            ret = ERROR_HLS_AAC_FRAME_LENGTH;
            srs_error("invalid aac frame length=%d, ret=%d", size, ret);
            return ret;
        }
        
        // the frame length is the AAC raw data plus the adts header size.
        int32_t frame_length = size + 7;
        
        // AAC-ADTS
        // 6.2 Audio Data Transport Stream, ADTS
        // in aac-iso-13818-7.pdf, page 26.
        // fixed 7bytes header
        static u_int8_t adts_header[7] = {0xff, 0xf1, 0x00, 0x00, 0x00, 0x0f, 0xfc};
        /*
        // adts_fixed_header
        // 2B, 16bits
        int16_t syncword; //12bits, '1111 1111 1111'
        int8_t ID; //1bit, '0'
        int8_t layer; //2bits, '00'
        int8_t protection_absent; //1bit, can be '1'
        // 12bits
        int8_t profile; //2bit, 7.1 Profiles, page 40
        TSAacSampleFrequency sampling_frequency_index; //4bits, Table 35, page 46
        int8_t private_bit; //1bit, can be '0'
        int8_t channel_configuration; //3bits, Table 8
        int8_t original_or_copy; //1bit, can be '0'
        int8_t home; //1bit, can be '0'
        
        // adts_variable_header
        // 28bits
        int8_t copyright_identification_bit; //1bit, can be '0'
        int8_t copyright_identification_start; //1bit, can be '0'
        int16_t frame_length; //13bits
        int16_t adts_buffer_fullness; //11bits, 7FF signals that the bitstream is a variable rate bitstream.
        int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block()
        */
        // profile, 2bits
        adts_header[2] = (codec->aac_profile << 6) & 0xc0;
        // sampling_frequency_index 4bits
        adts_header[2] |= (codec->aac_sample_rate << 2) & 0x3c;
        // channel_configuration 3bits
        adts_header[2] |= (codec->aac_channels >> 2) & 0x01;
        adts_header[3] = (codec->aac_channels << 6) & 0xc0;
        // frame_length 13bits
        adts_header[3] |= (frame_length >> 11) & 0x03;
        adts_header[4] = (frame_length >> 3) & 0xff;
        adts_header[5] = ((frame_length << 5) & 0xe0);
        // adts_buffer_fullness; //11bits
        adts_header[5] |= 0x1f;

        // copy to audio buffer
1217 1218
        ab->append((const char*)adts_header, sizeof(adts_header));
        ab->append(sample_unit->bytes, sample_unit->size);
1219 1220 1221
    }
    
    return ret;
1222 1223
}
1224
int SrsHlsCache::cache_video(SrsAvcAacCodec* codec, SrsCodecSample* sample)
1225
{
1226 1227
    int ret = ERROR_SUCCESS;
    
1228
    // for type1/5/6, insert aud packet.
1229 1230 1231
    static u_int8_t aud_nal[] = { 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0 };
    
    bool sps_pps_sent = false;
1232 1233 1234 1235 1236 1237 1238 1239 1240
    bool aud_sent = false;
    /**
    * a ts sample is format as:
    * 00 00 00 01 // header
    *       xxxxxxx // data bytes
    * 00 00 01 // continue header
    *       xxxxxxx // data bytes.
    * so, for each sample, we append header in aud_nal, then appends the bytes in sample.
    */
1241 1242 1243
    for (int i = 0; i < sample->nb_sample_units; i++) {
        SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
        int32_t size = sample_unit->size;
1244
        
1245
        if (!sample_unit->bytes || size <= 0) {
1246 1247 1248 1249 1250
            ret = ERROR_HLS_AVC_SAMPLE_SIZE;
            srs_error("invalid avc sample length=%d, ret=%d", size, ret);
            return ret;
        }
        
1251 1252 1253 1254 1255 1256 1257
        /**
        * step 1:
        * first, before each "real" sample, 
        * we add some packets according to the nal_unit_type,
        * for example, when got nal_unit_type=5, insert SPS/PPS before sample.
        */
        
1258 1259 1260
        // 5bits, 7.3.1 NAL unit syntax, 
        // H.264-AVC-ISO_IEC_14496-10.pdf, page 44.
        u_int8_t nal_unit_type;
1261
        nal_unit_type = *sample_unit->bytes;
1262 1263
        nal_unit_type &= 0x1f;
        
1264
        // @see: ngx_rtmp_hls_video
1265 1266 1267 1268 1269
        // Table 7-1 – NAL unit type codes, page 61
        // 1: Coded slice
        if (nal_unit_type == 1) {
            sps_pps_sent = false;
        }
1270 1271 1272 1273 1274 1275 1276 1277 1278
        
        // 6: Supplemental enhancement information (SEI) sei_rbsp( ), page 61
        // @see: ngx_rtmp_hls_append_aud
        if (!aud_sent) {
            if (nal_unit_type == 9) {
                aud_sent = true;
            }
            if (nal_unit_type == 1 || nal_unit_type == 5 || nal_unit_type == 6) {
                // for type 6, append a aud with type 9.
1279
                vb->append((const char*)aud_nal, sizeof(aud_nal));
1280
                aud_sent = true;
1281 1282 1283
            }
        }
        
1284 1285 1286 1287 1288
        // 5: Coded slice of an IDR picture.
        // insert sps/pps before IDR or key frame is ok.
        if (nal_unit_type == 5 && !sps_pps_sent) {
            sps_pps_sent = true;
            
1289
            // @see: ngx_rtmp_hls_append_sps_pps
1290
            if (codec->sequenceParameterSetLength > 0) {
1291
                // AnnexB prefix, for sps always 4 bytes header
1292
                vb->append((const char*)aud_nal, 4);
1293 1294 1295 1296
                // sps
                vb->append(codec->sequenceParameterSetNALUnit, codec->sequenceParameterSetLength);
            }
            if (codec->pictureParameterSetLength > 0) {
1297
                // AnnexB prefix, for pps always 4 bytes header
1298
                vb->append((const char*)aud_nal, 4);
1299 1300 1301 1302
                // pps
                vb->append(codec->pictureParameterSetNALUnit, codec->pictureParameterSetLength);
            }
        }
1303
        
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
        // 7-9, ignore, @see: ngx_rtmp_hls_video
        if (nal_unit_type >= 7 && nal_unit_type <= 9) {
            continue;
        }
        
        /**
        * step 2:
        * output the "real" sample, in buf.
        * when we output some special assist packets according to nal_unit_type
        */
1314 1315 1316 1317 1318 1319
        
        // sample start prefix, '00 00 00 01' or '00 00 01'
        u_int8_t* p = aud_nal + 1;
        u_int8_t* end = p + 3;
        
        // first AnnexB prefix is long (4 bytes)
1320
        if (vb->length() == 0) {
1321 1322
            p = aud_nal;
        }
1323
        vb->append((const char*)p, end - p);
1324 1325
        
        // sample data
1326
        vb->append(sample_unit->bytes, sample_unit->size);
1327 1328 1329
    }
    
    return ret;
1330 1331
}
1332
SrsHls::SrsHls(SrsSource* _source)
1333
{
1334 1335 1336
    hls_enabled = false;
    
    source = _source;
1337
    codec = new SrsAvcAacCodec();
1338 1339 1340
    sample = new SrsCodecSample();
    jitter = new SrsRtmpJitter();
    
1341 1342
    muxer = new SrsHlsMuxer();
    hls_cache = new SrsHlsCache();
1343
winlin authored
1344
    pithy_print = new SrsPithyPrint(SRS_CONSTS_STAGE_HLS);
1345
    stream_dts = 0;
1346 1347 1348 1349
}

SrsHls::~SrsHls()
{
1350 1351 1352 1353 1354
    srs_freep(codec);
    srs_freep(sample);
    srs_freep(jitter);
    
    srs_freep(muxer);
1355
    srs_freep(hls_cache);
1356 1357
    
    srs_freep(pithy_print);
winlin authored
1358 1359 1360 1361
}

int SrsHls::on_publish(SrsRequest* req)
{
1362 1363 1364 1365 1366 1367 1368
    int ret = ERROR_SUCCESS;
    
    // support multiple publish.
    if (hls_enabled) {
        return ret;
    }
    
1369
    std::string vhost = req->vhost;
1370 1371 1372 1373
    if (!_srs_config->get_hls_enabled(vhost)) {
        return ret;
    }
    
1374
    if ((ret = hls_cache->on_publish(muxer, req, stream_dts)) != ERROR_SUCCESS) {
1375 1376 1377
        return ret;
    }
    
winlin authored
1378 1379 1380
    // if enabled, open the muxer.
    hls_enabled = true;
    
1381
    // notice the source to get the cached sequence header.
1382 1383
    // when reload to start hls, hls will never get the sequence header in stream,
    // use the SrsSource.on_hls_start to push the sequence header to HLS.
1384 1385 1386 1387 1388 1389
    if ((ret = source->on_hls_start()) != ERROR_SUCCESS) {
        srs_error("callback source hls start failed. ret=%d", ret);
        return ret;
    }

    return ret;
winlin authored
1390 1391 1392 1393
}

void SrsHls::on_unpublish()
{
1394 1395 1396 1397 1398 1399 1400
    int ret = ERROR_SUCCESS;
    
    // support multiple unpublish.
    if (!hls_enabled) {
        return;
    }
1401
    if ((ret = hls_cache->on_unpublish(muxer)) != ERROR_SUCCESS) {
1402 1403 1404 1405
        srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret);
    }
    
    hls_enabled = false;
winlin authored
1406 1407
}
1408
int SrsHls::on_meta_data(SrsAmf0Object* metadata)
winlin authored
1409
{
1410 1411 1412 1413 1414 1415 1416
    int ret = ERROR_SUCCESS;

    if (!metadata) {
        srs_trace("no metadata persent, hls ignored it.");
        return ret;
    }
    
1417
    if (metadata->count() <= 0) {
1418 1419 1420 1421
        srs_trace("no metadata persent, hls ignored it.");
        return ret;
    }
    
1422 1423
    if ((ret = codec->metadata_demux(metadata)) != ERROR_SUCCESS) {
        return ret;
1424 1425 1426
    }
    
    return ret;
winlin authored
1427 1428
}
1429
int SrsHls::on_audio(SrsSharedPtrMessage* audio)
winlin authored
1430
{
1431 1432
    int ret = ERROR_SUCCESS;
    
1433
    SrsAutoFree(SrsSharedPtrMessage, audio);
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450
    
    if (!hls_enabled) {
        return ret;
    }
    
    sample->clear();
    if ((ret = codec->audio_aac_demux(audio->payload, audio->size, sample)) != ERROR_SUCCESS) {
        srs_error("codec demux audio failed. ret=%d", ret);
        return ret;
    }
    
    if (codec->audio_codec_id != SrsCodecAudioAAC) {
        return ret;
    }
    
    // ignore sequence header
    if (sample->aac_packet_type == SrsCodecAudioTypeSequenceHeader) {
winlin authored
1451
        return hls_cache->on_sequence_header(muxer);
1452 1453
    }
    
1454
    if ((ret = jitter->correct(audio, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
1455 1456 1457 1458 1459 1460 1461
        srs_error("rtmp jitter correct audio failed. ret=%d", ret);
        return ret;
    }
    
    // the pts calc from rtmp/flv header.
    int64_t pts = audio->header.timestamp * 90;
    
1462 1463 1464 1465 1466
    // for pure audio, we need to update the stream dts also.
    stream_dts = pts;
    
    if ((ret = hls_cache->write_audio(codec, muxer, pts, sample)) != ERROR_SUCCESS) {
        srs_error("hls cache write audio failed. ret=%d", ret);
1467 1468 1469 1470
        return ret;
    }
    
    return ret;
winlin authored
1471 1472
}
1473
int SrsHls::on_video(SrsSharedPtrMessage* video)
winlin authored
1474
{
1475 1476
    int ret = ERROR_SUCCESS;
    
1477
    SrsAutoFree(SrsSharedPtrMessage, video);
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
    
    if (!hls_enabled) {
        return ret;
    }
    
    sample->clear();
    if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) {
        srs_error("codec demux video failed. ret=%d", ret);
        return ret;
    }
    
    if (codec->video_codec_id != SrsCodecVideoAVC) {
        return ret;
    }
    
    // ignore sequence header
    if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame
         && sample->avc_packet_type == SrsCodecVideoAVCTypeSequenceHeader) {
winlin authored
1496
        return hls_cache->on_sequence_header(muxer);
1497 1498
    }
    
1499
    if ((ret = jitter->correct(video, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
1500 1501 1502 1503 1504
        srs_error("rtmp jitter correct video failed. ret=%d", ret);
        return ret;
    }
    
    int64_t dts = video->header.timestamp * 90;
1505 1506 1507
    stream_dts = dts;
    if ((ret = hls_cache->write_video(codec, muxer, dts, sample)) != ERROR_SUCCESS) {
        srs_error("hls cache write video failed. ret=%d", ret);
1508 1509 1510 1511 1512 1513
        return ret;
    }
    
    hls_mux();
    
    return ret;
1514 1515
}
1516
void SrsHls::hls_mux()
winlin authored
1517
{
1518 1519
    // reportable
    if (pithy_print->can_print()) {
1520 1521 1522
        // the run time is not equals to stream time,
        // @see: https://github.com/winlinvip/simple-rtmp-server/issues/81#issuecomment-48100994
        // it's ok.
1523
        srs_trace("-> "SRS_CONSTS_LOG_HLS
1524
            " time=%"PRId64", stream dts=%"PRId64"(%"PRId64"ms), sequence_no=%d", 
1525
            pithy_print->age(), stream_dts, stream_dts / 90, muxer->sequence_no());
1526 1527
    }
    
1528
    pithy_print->elapse();
winlin authored
1529 1530
}
1531 1532
#endif
1533