github.com/cnotch/ipchub@v1.1.0/av/format/hls/aac_jitter.go (about)

     1  // Copyright calabashdad. https://github.com/calabashdad/seal.git
     2  //
     3  // Copyright (c) 2019,CAOHONGJU All rights reserved.
     4  // Use of this source code is governed by a MIT-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package hls
     8  
     9  import "github.com/cnotch/ipchub/av/codec/aac"
    10  
    11  const (
    12  	// in ms, for HLS aac sync time.
    13  	hlsConfDefaultAacSync = 100
    14  )
    15  
    16  // jitter correct for audio,
    17  // the sample rate 44100/32000 will lost precise,
    18  // when mp4/ts(tbn=90000) covert to flv/rtmp(1000),
    19  // so the Hls on ipad or iphone will corrupt,
    20  // @see nginx-rtmp: est_pts
    21  type hlsAacJitter struct {
    22  	basePts   int64
    23  	nbSamples int64
    24  	syncMs    int
    25  }
    26  
    27  func newHlsAacJitter() *hlsAacJitter {
    28  	return &hlsAacJitter{
    29  		syncMs: hlsConfDefaultAacSync,
    30  	}
    31  }
    32  
    33  // when buffer start, calc the "correct" pts for ts,
    34  // @param flv_pts, the flv pts calc from flv header timestamp,
    35  // @param sample_rate, the sample rate in format(flv/RTMP packet header).
    36  // @param aac_sample_rate, the sample rate in codec(sequence header).
    37  // @return the calc correct pts.
    38  func (ha *hlsAacJitter) onBufferStart(pts int64, sampleRate int) (calcCorrectPts int64) {
    39  	// sync time set to 0, donot adjust the aac timestamp.
    40  	if 0 == ha.syncMs {
    41  		return pts
    42  	}
    43  
    44  	// @see: ngx_rtmp_hls_audio
    45  	// drop the rtmp audio packet timestamp, re-calc it by sample rate.
    46  	//
    47  	// resample for the tbn of ts is 90000, flv is 1000,
    48  	// we will lost timestamp if use audio packet timestamp,
    49  	// so we must resample. or audio will corrupt in IOS.
    50  	estPts := ha.basePts + ha.nbSamples*int64(90000)*int64(aac.SamplesPerFrame)/int64(sampleRate)
    51  	dpts := estPts - pts
    52  
    53  	if (dpts <= int64(ha.syncMs)*90) && (dpts >= int64(ha.syncMs)*int64(-90)) {
    54  		ha.nbSamples++
    55  		return estPts
    56  	}
    57  
    58  	// resync
    59  	ha.basePts = pts
    60  	ha.nbSamples = 1
    61  
    62  	return pts
    63  }
    64  
    65  // when buffer continue, muxer donot write to file,
    66  // the audio buffer continue grow and donot need a pts,
    67  // for the ts audio PES packet only has one pts at the first time.
    68  func (ha *hlsAacJitter) onBufferContinue() {
    69  	ha.nbSamples++
    70  
    71  	return
    72  }