正在显示
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); |
-
请 注册 或 登录 后发表评论