正在显示
6 个修改的文件
包含
45 行增加
和
4 行删除
@@ -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); |
-
请 注册 或 登录 后发表评论