winlin

fix #635, hls support NonIDR(open gop). 2.0.226

@@ -345,6 +345,7 @@ Remark: @@ -345,6 +345,7 @@ Remark:
345 345
346 ## History 346 ## History
347 347
  348 +* v2.0, 2017-01-10, fix [#635][bug #635], hls support NonIDR(open gop). 2.0.226
348 * v2.0, 2017-01-06, for [#730][bug #730], reset ack follow flash player rules. 2.0.225 349 * v2.0, 2017-01-06, for [#730][bug #730], reset ack follow flash player rules. 2.0.225
349 * v2.0, 2016-12-15, for [#513][bug #513], remove hls ram from srs2 to srs3+. 2.0.224 350 * v2.0, 2016-12-15, for [#513][bug #513], remove hls ram from srs2 to srs3+. 2.0.224
350 * <strong>v2.0, 2016-12-13, [2.0 beta3(2.0.223)][r2.0b3] released. 86685 lines.</strong> 351 * <strong>v2.0, 2016-12-13, [2.0 beta3(2.0.223)][r2.0b3] released. 86685 lines.</strong>
@@ -1268,6 +1269,7 @@ Winlin @@ -1268,6 +1269,7 @@ Winlin
1268 [bug #713]: https://github.com/ossrs/srs/issues/713 1269 [bug #713]: https://github.com/ossrs/srs/issues/713
1269 [bug #513]: https://github.com/ossrs/srs/issues/513 1270 [bug #513]: https://github.com/ossrs/srs/issues/513
1270 [bug #730]: https://github.com/ossrs/srs/issues/730 1271 [bug #730]: https://github.com/ossrs/srs/issues/730
  1272 +[bug #635]: https://github.com/ossrs/srs/issues/635
1271 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx 1273 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
1272 1274
1273 [exo #828]: https://github.com/google/ExoPlayer/pull/828 1275 [exo #828]: https://github.com/google/ExoPlayer/pull/828
@@ -1070,8 +1070,8 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t @@ -1070,8 +1070,8 @@ int SrsHlsCache::write_video(SrsAvcAacCodec* codec, SrsHlsMuxer* muxer, int64_t
1070 // a. wait keyframe and got keyframe. 1070 // a. wait keyframe and got keyframe.
1071 // b. always reap when not wait keyframe. 1071 // b. always reap when not wait keyframe.
1072 if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) { 1072 if (!muxer->wait_keyframe() || sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
1073 - // when wait keyframe, there must exists idr frame in sample.  
1074 - if (!sample->has_idr && muxer->wait_keyframe()) { 1073 + // when wait keyframe, there must exists idr frame in sample, or NonIDR(open gop) specified.
  1074 + if (!sample->has_non_idr && !sample->has_idr && muxer->wait_keyframe()) {
1075 srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr); 1075 srs_warn("hls: ts starts without IDR, first nalu=%d, idr=%d", sample->first_nalu_type, sample->has_idr);
1076 } 1076 }
1077 1077
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 225 34 +#define VERSION_REVISION 226
35 35
36 // generated by configure, only macros. 36 // generated by configure, only macros.
37 #include <srs_auto_headers.hpp> 37 #include <srs_auto_headers.hpp>
@@ -339,7 +339,7 @@ void SrsCodecSample::clear() @@ -339,7 +339,7 @@ void SrsCodecSample::clear()
339 cts = 0; 339 cts = 0;
340 frame_type = SrsCodecVideoAVCFrameReserved; 340 frame_type = SrsCodecVideoAVCFrameReserved;
341 avc_packet_type = SrsCodecVideoAVCTypeReserved; 341 avc_packet_type = SrsCodecVideoAVCTypeReserved;
342 - has_idr = false; 342 + has_aud = has_sei = has_non_idr = has_idr = false;
343 first_nalu_type = SrsAvcNaluTypeReserved; 343 first_nalu_type = SrsAvcNaluTypeReserved;
344 344
345 acodec = SrsCodecAudioReserved1; 345 acodec = SrsCodecAudioReserved1;
@@ -370,6 +370,12 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) @@ -370,6 +370,12 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size)
370 370
371 if (nal_unit_type == SrsAvcNaluTypeIDR) { 371 if (nal_unit_type == SrsAvcNaluTypeIDR) {
372 has_idr = true; 372 has_idr = true;
  373 + } else if (nal_unit_type == SrsAvcNaluTypeNonIDR) {
  374 + has_non_idr = true;
  375 + } else if (nal_unit_type == SrsAvcNaluTypeSEI) {
  376 + has_sei = true;
  377 + } else if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) {
  378 + has_aud = true;
373 } 379 }
374 380
375 if (first_nalu_type == SrsAvcNaluTypeReserved) { 381 if (first_nalu_type == SrsAvcNaluTypeReserved) {
@@ -385,6 +385,13 @@ public: @@ -385,6 +385,13 @@ public:
385 SrsCodecVideoAVCType avc_packet_type; 385 SrsCodecVideoAVCType avc_packet_type;
386 // whether sample_units contains IDR frame. 386 // whether sample_units contains IDR frame.
387 bool has_idr; 387 bool has_idr;
  388 + // Whether exists NonIDR NALU.
  389 + bool has_non_idr;
  390 + // Whether exists SEI NALU.
  391 + bool has_sei;
  392 + // Whether exists AUD NALU.
  393 + bool has_aud;
  394 + // The first nalu type.
388 SrsAvcNaluType first_nalu_type; 395 SrsAvcNaluType first_nalu_type;
389 public: 396 public:
390 // audio specified 397 // audio specified
@@ -3009,6 +3009,32 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample) @@ -3009,6 +3009,32 @@ int SrsTsCache::do_cache_avc(SrsAvcAacCodec* codec, SrsCodecSample* sample)
3009 // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 105. 3009 // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 105.
3010 static u_int8_t aud_nalu_7[] = { 0x09, 0xf0}; 3010 static u_int8_t aud_nalu_7[] = { 0x09, 0xf0};
3011 3011
  3012 + // For NonIDR(open gop), we directly appends all frames.
  3013 + if (sample->has_non_idr || (sample->has_aud && sample->has_sei)) {
  3014 + for (int i = 0; i < sample->nb_sample_units; i++) {
  3015 + SrsCodecSampleUnit* sample_unit = &sample->sample_units[i];
  3016 + int32_t size = sample_unit->size;
  3017 +
  3018 + if (!sample_unit->bytes || size <= 0) {
  3019 + ret = ERROR_HLS_AVC_SAMPLE_SIZE;
  3020 + srs_error("invalid avc sample length=%d, ret=%d", size, ret);
  3021 + return ret;
  3022 + }
  3023 +
  3024 + // insert nalu header before rbsp.
  3025 + if (i == 0) {
  3026 + video->payload->append((const char*)fresh_nalu_header, 4);
  3027 + } else {
  3028 + video->payload->append((const char*)cont_nalu_header, 3);
  3029 + }
  3030 +
  3031 + // sample data
  3032 + video->payload->append(sample_unit->bytes, sample_unit->size);
  3033 + }
  3034 +
  3035 + return ret;
  3036 + }
  3037 +
3012 // always append a aud nalu for each frame. 3038 // always append a aud nalu for each frame.
3013 video->payload->append((const char*)fresh_nalu_header, 4); 3039 video->payload->append((const char*)fresh_nalu_header, 4);
3014 video->payload->append((const char*)aud_nalu_7, 2); 3040 video->payload->append((const char*)aud_nalu_7, 2);