for bug #251, the shared ptr message share the header. 2.0.64
正在显示
11 个修改的文件
包含
308 行增加
和
120 行删除
| @@ -213,7 +213,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* __audio) | @@ -213,7 +213,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* __audio) | ||
| 213 | 213 | ||
| 214 | char* payload = audio->payload; | 214 | char* payload = audio->payload; |
| 215 | int size = audio->size; | 215 | int size = audio->size; |
| 216 | - int64_t timestamp = filter_timestamp(audio->header.timestamp); | 216 | + int64_t timestamp = filter_timestamp(audio->timestamp); |
| 217 | if ((ret = enc->write_audio(timestamp, payload, size)) != ERROR_SUCCESS) { | 217 | if ((ret = enc->write_audio(timestamp, payload, size)) != ERROR_SUCCESS) { |
| 218 | return ret; | 218 | return ret; |
| 219 | } | 219 | } |
| @@ -262,7 +262,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* __video) | @@ -262,7 +262,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* __video) | ||
| 262 | return ret; | 262 | return ret; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | - int32_t timestamp = filter_timestamp(video->header.timestamp); | 265 | + int32_t timestamp = filter_timestamp(video->timestamp); |
| 266 | if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { | 266 | if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { |
| 267 | return ret; | 267 | return ret; |
| 268 | } | 268 | } |
| @@ -332,20 +332,20 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg) | @@ -332,20 +332,20 @@ int SrsDvrPlan::update_duration(SrsSharedPtrMessage* msg) | ||
| 332 | 332 | ||
| 333 | // set the segment starttime at first time | 333 | // set the segment starttime at first time |
| 334 | if (segment->starttime < 0) { | 334 | if (segment->starttime < 0) { |
| 335 | - segment->starttime = msg->header.timestamp; | 335 | + segment->starttime = msg->timestamp; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | // no previous packet or timestamp overflow. | 338 | // no previous packet or timestamp overflow. |
| 339 | - if (segment->stream_previous_pkt_time < 0 || segment->stream_previous_pkt_time > msg->header.timestamp) { | ||
| 340 | - segment->stream_previous_pkt_time = msg->header.timestamp; | 339 | + if (segment->stream_previous_pkt_time < 0 || segment->stream_previous_pkt_time > msg->timestamp) { |
| 340 | + segment->stream_previous_pkt_time = msg->timestamp; | ||
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | // collect segment and stream duration, timestamp overflow is ok. | 343 | // collect segment and stream duration, timestamp overflow is ok. |
| 344 | - segment->duration += msg->header.timestamp - segment->stream_previous_pkt_time; | ||
| 345 | - segment->stream_duration += msg->header.timestamp - segment->stream_previous_pkt_time; | 344 | + segment->duration += msg->timestamp - segment->stream_previous_pkt_time; |
| 345 | + segment->stream_duration += msg->timestamp - segment->stream_previous_pkt_time; | ||
| 346 | 346 | ||
| 347 | // update previous packet time | 347 | // update previous packet time |
| 348 | - segment->stream_previous_pkt_time = msg->header.timestamp; | 348 | + segment->stream_previous_pkt_time = msg->timestamp; |
| 349 | 349 | ||
| 350 | return ret; | 350 | return ret; |
| 351 | } | 351 | } |
| @@ -488,7 +488,7 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) | @@ -488,7 +488,7 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) | ||
| 488 | // when wait keyframe, ignore if no frame arrived. | 488 | // when wait keyframe, ignore if no frame arrived. |
| 489 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/177 | 489 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/177 |
| 490 | if (_srs_config->get_dvr_wait_keyframe(_req->vhost)) { | 490 | if (_srs_config->get_dvr_wait_keyframe(_req->vhost)) { |
| 491 | - if (!msg->header.is_video()) { | 491 | + if (!msg->is_video()) { |
| 492 | return ret; | 492 | return ret; |
| 493 | } | 493 | } |
| 494 | 494 |
| @@ -560,7 +560,7 @@ int SrsEdgeForwarder::proxy(SrsCommonMessage* msg) | @@ -560,7 +560,7 @@ int SrsEdgeForwarder::proxy(SrsCommonMessage* msg) | ||
| 560 | } | 560 | } |
| 561 | srs_verbose("initialize shared ptr msg success."); | 561 | srs_verbose("initialize shared ptr msg success."); |
| 562 | 562 | ||
| 563 | - copy.header.stream_id = stream_id; | 563 | + copy.stream_id = stream_id; |
| 564 | if ((ret = queue->enqueue(copy.copy())) != ERROR_SUCCESS) { | 564 | if ((ret = queue->enqueue(copy.copy())) != ERROR_SUCCESS) { |
| 565 | srs_error("enqueue edge publish msg failed. ret=%d", ret); | 565 | srs_error("enqueue edge publish msg failed. ret=%d", ret); |
| 566 | } | 566 | } |
| @@ -1458,7 +1458,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* __audio) | @@ -1458,7 +1458,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* __audio) | ||
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | // the pts calc from rtmp/flv header. | 1460 | // the pts calc from rtmp/flv header. |
| 1461 | - int64_t pts = audio->header.timestamp * 90; | 1461 | + int64_t pts = audio->timestamp * 90; |
| 1462 | 1462 | ||
| 1463 | // for pure audio, we need to update the stream dts also. | 1463 | // for pure audio, we need to update the stream dts also. |
| 1464 | stream_dts = pts; | 1464 | stream_dts = pts; |
| @@ -1503,7 +1503,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* __video) | @@ -1503,7 +1503,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* __video) | ||
| 1503 | return ret; | 1503 | return ret; |
| 1504 | } | 1504 | } |
| 1505 | 1505 | ||
| 1506 | - int64_t dts = video->header.timestamp * 90; | 1506 | + int64_t dts = video->timestamp * 90; |
| 1507 | stream_dts = dts; | 1507 | stream_dts = dts; |
| 1508 | if ((ret = hls_cache->write_video(codec, muxer, dts, sample)) != ERROR_SUCCESS) { | 1508 | if ((ret = hls_cache->write_video(codec, muxer, dts, sample)) != ERROR_SUCCESS) { |
| 1509 | srs_error("hls cache write video failed. ret=%d", ret); | 1509 | srs_error("hls cache write video failed. ret=%d", ret); |
| @@ -642,11 +642,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd) | @@ -642,11 +642,11 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd) | ||
| 642 | 642 | ||
| 643 | // foreach msg, collect the duration. | 643 | // foreach msg, collect the duration. |
| 644 | // @remark: never use msg when sent it, for the protocol sdk will free it. | 644 | // @remark: never use msg when sent it, for the protocol sdk will free it. |
| 645 | - if (starttime < 0 || starttime > msg->header.timestamp) { | ||
| 646 | - starttime = msg->header.timestamp; | 645 | + if (starttime < 0 || starttime > msg->timestamp) { |
| 646 | + starttime = msg->timestamp; | ||
| 647 | } | 647 | } |
| 648 | - duration += msg->header.timestamp - starttime; | ||
| 649 | - starttime = msg->header.timestamp; | 648 | + duration += msg->timestamp - starttime; |
| 649 | + starttime = msg->timestamp; | ||
| 650 | } | 650 | } |
| 651 | } | 651 | } |
| 652 | 652 |
| @@ -85,10 +85,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -85,10 +85,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
| 85 | if (ag == SrsRtmpJitterAlgorithmZERO) { | 85 | if (ag == SrsRtmpJitterAlgorithmZERO) { |
| 86 | // for the first time, last_pkt_correct_time is zero. | 86 | // for the first time, last_pkt_correct_time is zero. |
| 87 | // while when timestamp overflow, the timestamp become smaller, reset the last_pkt_correct_time. | 87 | // while when timestamp overflow, the timestamp become smaller, reset the last_pkt_correct_time. |
| 88 | - if (last_pkt_correct_time <= 0 || last_pkt_correct_time > msg->header.timestamp) { | ||
| 89 | - last_pkt_correct_time = msg->header.timestamp; | 88 | + if (last_pkt_correct_time <= 0 || last_pkt_correct_time > msg->timestamp) { |
| 89 | + last_pkt_correct_time = msg->timestamp; | ||
| 90 | } | 90 | } |
| 91 | - msg->header.timestamp -= last_pkt_correct_time; | 91 | + msg->timestamp -= last_pkt_correct_time; |
| 92 | return ret; | 92 | return ret; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -99,8 +99,8 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -99,8 +99,8 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
| 99 | // full jitter algorithm, do jitter correct. | 99 | // full jitter algorithm, do jitter correct. |
| 100 | 100 | ||
| 101 | // set to 0 for metadata. | 101 | // set to 0 for metadata. |
| 102 | - if (!msg->header.is_audio() && !msg->header.is_video()) { | ||
| 103 | - msg->header.timestamp = 0; | 102 | + if (!msg->is_av()) { |
| 103 | + msg->timestamp = 0; | ||
| 104 | return ret; | 104 | return ret; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -117,15 +117,15 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -117,15 +117,15 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
| 117 | * 3. last_pkt_correct_time: simply add the positive delta, | 117 | * 3. last_pkt_correct_time: simply add the positive delta, |
| 118 | * and enforce the time monotonically. | 118 | * and enforce the time monotonically. |
| 119 | */ | 119 | */ |
| 120 | - int64_t time = msg->header.timestamp; | 120 | + int64_t time = msg->timestamp; |
| 121 | int64_t delta = time - last_pkt_time; | 121 | int64_t delta = time - last_pkt_time; |
| 122 | 122 | ||
| 123 | // if jitter detected, reset the delta. | 123 | // if jitter detected, reset the delta. |
| 124 | if (delta < 0 || delta > CONST_MAX_JITTER_MS) { | 124 | if (delta < 0 || delta > CONST_MAX_JITTER_MS) { |
| 125 | // calc the right diff by audio sample rate | 125 | // calc the right diff by audio sample rate |
| 126 | - if (msg->header.is_audio() && sample_rate > 0) { | 126 | + if (msg->is_audio() && sample_rate > 0) { |
| 127 | delta = (int64_t)(delta * 1000.0 / sample_rate); | 127 | delta = (int64_t)(delta * 1000.0 / sample_rate); |
| 128 | - } else if (msg->header.is_video() && frame_rate > 0) { | 128 | + } else if (msg->is_video() && frame_rate > 0) { |
| 129 | delta = (int64_t)(delta * 1.0 / frame_rate); | 129 | delta = (int64_t)(delta * 1.0 / frame_rate); |
| 130 | } else { | 130 | } else { |
| 131 | delta = DEFAULT_FRAME_TIME_MS; | 131 | delta = DEFAULT_FRAME_TIME_MS; |
| @@ -145,7 +145,7 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -145,7 +145,7 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
| 145 | 145 | ||
| 146 | last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta); | 146 | last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta); |
| 147 | 147 | ||
| 148 | - msg->header.timestamp = last_pkt_correct_time; | 148 | + msg->timestamp = last_pkt_correct_time; |
| 149 | last_pkt_time = time; | 149 | last_pkt_time = time; |
| 150 | 150 | ||
| 151 | return ret; | 151 | return ret; |
| @@ -186,12 +186,12 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg) | @@ -186,12 +186,12 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg) | ||
| 186 | { | 186 | { |
| 187 | int ret = ERROR_SUCCESS; | 187 | int ret = ERROR_SUCCESS; |
| 188 | 188 | ||
| 189 | - if (msg->header.is_audio() || msg->header.is_video()) { | 189 | + if (msg->is_av()) { |
| 190 | if (av_start_time == -1) { | 190 | if (av_start_time == -1) { |
| 191 | - av_start_time = msg->header.timestamp; | 191 | + av_start_time = msg->timestamp; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | - av_end_time = msg->header.timestamp; | 194 | + av_end_time = msg->timestamp; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | msgs.push_back(msg); | 197 | msgs.push_back(msg); |
| @@ -221,7 +221,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in | @@ -221,7 +221,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in | ||
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | SrsSharedPtrMessage* last = omsgs[count - 1]; | 223 | SrsSharedPtrMessage* last = omsgs[count - 1]; |
| 224 | - av_start_time = last->header.timestamp; | 224 | + av_start_time = last->timestamp; |
| 225 | 225 | ||
| 226 | if (count >= nb_msgs) { | 226 | if (count >= nb_msgs) { |
| 227 | // the pmsgs is big enough and clear msgs at most time. | 227 | // the pmsgs is big enough and clear msgs at most time. |
| @@ -248,13 +248,13 @@ void SrsMessageQueue::shrink() | @@ -248,13 +248,13 @@ void SrsMessageQueue::shrink() | ||
| 248 | for (int i = 1; i < (int)msgs.size(); i++) { | 248 | for (int i = 1; i < (int)msgs.size(); i++) { |
| 249 | SrsSharedPtrMessage* msg = msgs[i]; | 249 | SrsSharedPtrMessage* msg = msgs[i]; |
| 250 | 250 | ||
| 251 | - if (msg->header.is_video()) { | 251 | + if (msg->is_video()) { |
| 252 | if (SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { | 252 | if (SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { |
| 253 | // the max frame index to remove. | 253 | // the max frame index to remove. |
| 254 | iframe_index = i; | 254 | iframe_index = i; |
| 255 | 255 | ||
| 256 | // set the start time, we will remove until this frame. | 256 | // set the start time, we will remove until this frame. |
| 257 | - av_start_time = msg->header.timestamp; | 257 | + av_start_time = msg->timestamp; |
| 258 | 258 | ||
| 259 | break; | 259 | break; |
| 260 | } | 260 | } |
| @@ -471,7 +471,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | @@ -471,7 +471,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | ||
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | // got video, update the video count if acceptable | 473 | // got video, update the video count if acceptable |
| 474 | - if (msg->header.is_video()) { | 474 | + if (msg->is_video()) { |
| 475 | cached_video_count++; | 475 | cached_video_count++; |
| 476 | audio_after_last_video_count = 0; | 476 | audio_after_last_video_count = 0; |
| 477 | } | 477 | } |
| @@ -483,7 +483,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | @@ -483,7 +483,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | ||
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | // ok, gop cache enabled, and got an audio. | 485 | // ok, gop cache enabled, and got an audio. |
| 486 | - if (msg->header.is_audio()) { | 486 | + if (msg->is_audio()) { |
| 487 | audio_after_last_video_count++; | 487 | audio_after_last_video_count++; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| @@ -495,7 +495,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | @@ -495,7 +495,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* __msg) | ||
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | // clear gop cache when got key frame | 497 | // clear gop cache when got key frame |
| 498 | - if (msg->header.is_video() && SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { | 498 | + if (msg->is_video() && SrsFlvCodec::video_is_keyframe(msg->payload, msg->size)) { |
| 499 | srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", | 499 | srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", |
| 500 | cached_video_count, (int)gop_cache.size()); | 500 | cached_video_count, (int)gop_cache.size()); |
| 501 | 501 | ||
| @@ -556,7 +556,7 @@ int64_t SrsGopCache::start_time() | @@ -556,7 +556,7 @@ int64_t SrsGopCache::start_time() | ||
| 556 | SrsSharedPtrMessage* msg = gop_cache[0]; | 556 | SrsSharedPtrMessage* msg = gop_cache[0]; |
| 557 | srs_assert(msg); | 557 | srs_assert(msg); |
| 558 | 558 | ||
| 559 | - return msg->header.timestamp; | 559 | + return msg->timestamp; |
| 560 | } | 560 | } |
| 561 | 561 | ||
| 562 | bool SrsGopCache::pure_audio() | 562 | bool SrsGopCache::pure_audio() |
| @@ -1239,7 +1239,7 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) | @@ -1239,7 +1239,7 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) | ||
| 1239 | srs_trace("%dB audio sh, " | 1239 | srs_trace("%dB audio sh, " |
| 1240 | "codec(%d, profile=%d, %dchannels, %dkbps, %dHZ), " | 1240 | "codec(%d, profile=%d, %dchannels, %dkbps, %dHZ), " |
| 1241 | "flv(%dbits, %dchannels, %dHZ)", | 1241 | "flv(%dbits, %dchannels, %dHZ)", |
| 1242 | - msg.header.payload_length, codec.audio_codec_id, | 1242 | + msg.size, codec.audio_codec_id, |
| 1243 | codec.aac_profile, codec.aac_channels, | 1243 | codec.aac_profile, codec.aac_channels, |
| 1244 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], | 1244 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], |
| 1245 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], | 1245 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], |
| @@ -1257,10 +1257,10 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) | @@ -1257,10 +1257,10 @@ int SrsSource::on_audio(SrsCommonMessage* __audio) | ||
| 1257 | // if atc, update the sequence header to abs time. | 1257 | // if atc, update the sequence header to abs time. |
| 1258 | if (atc) { | 1258 | if (atc) { |
| 1259 | if (cache_sh_audio) { | 1259 | if (cache_sh_audio) { |
| 1260 | - cache_sh_audio->header.timestamp = msg.header.timestamp; | 1260 | + cache_sh_audio->timestamp = msg.timestamp; |
| 1261 | } | 1261 | } |
| 1262 | if (cache_metadata) { | 1262 | if (cache_metadata) { |
| 1263 | - cache_metadata->header.timestamp = msg.header.timestamp; | 1263 | + cache_metadata->timestamp = msg.timestamp; |
| 1264 | } | 1264 | } |
| 1265 | } | 1265 | } |
| 1266 | 1266 | ||
| @@ -1352,7 +1352,7 @@ int SrsSource::on_video(SrsCommonMessage* __video) | @@ -1352,7 +1352,7 @@ int SrsSource::on_video(SrsCommonMessage* __video) | ||
| 1352 | 1352 | ||
| 1353 | srs_trace("%dB video sh, " | 1353 | srs_trace("%dB video sh, " |
| 1354 | "codec(%d, profile=%d, level=%d, %dx%d, %dkbps, %dfps, %ds)", | 1354 | "codec(%d, profile=%d, level=%d, %dx%d, %dkbps, %dfps, %ds)", |
| 1355 | - msg.header.payload_length, codec.video_codec_id, | 1355 | + msg.size, codec.video_codec_id, |
| 1356 | codec.avc_profile, codec.avc_level, codec.width, codec.height, | 1356 | codec.avc_profile, codec.avc_level, codec.width, codec.height, |
| 1357 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); | 1357 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); |
| 1358 | return ret; | 1358 | return ret; |
| @@ -1368,10 +1368,10 @@ int SrsSource::on_video(SrsCommonMessage* __video) | @@ -1368,10 +1368,10 @@ int SrsSource::on_video(SrsCommonMessage* __video) | ||
| 1368 | // if atc, update the sequence header to abs time. | 1368 | // if atc, update the sequence header to abs time. |
| 1369 | if (atc) { | 1369 | if (atc) { |
| 1370 | if (cache_sh_video) { | 1370 | if (cache_sh_video) { |
| 1371 | - cache_sh_video->header.timestamp = msg.header.timestamp; | 1371 | + cache_sh_video->timestamp = msg.timestamp; |
| 1372 | } | 1372 | } |
| 1373 | if (cache_metadata) { | 1373 | if (cache_metadata) { |
| 1374 | - cache_metadata->header.timestamp = msg.header.timestamp; | 1374 | + cache_metadata->timestamp = msg.timestamp; |
| 1375 | } | 1375 | } |
| 1376 | } | 1376 | } |
| 1377 | 1377 | ||
| @@ -1593,13 +1593,13 @@ void SrsSource::on_unpublish() | @@ -1593,13 +1593,13 @@ void SrsSource::on_unpublish() | ||
| 1593 | // if atc, update the sequence header to gop cache time. | 1593 | // if atc, update the sequence header to gop cache time. |
| 1594 | if (atc && !gop_cache->empty()) { | 1594 | if (atc && !gop_cache->empty()) { |
| 1595 | if (cache_metadata) { | 1595 | if (cache_metadata) { |
| 1596 | - cache_metadata->header.timestamp = gop_cache->start_time(); | 1596 | + cache_metadata->timestamp = gop_cache->start_time(); |
| 1597 | } | 1597 | } |
| 1598 | if (cache_sh_video) { | 1598 | if (cache_sh_video) { |
| 1599 | - cache_sh_video->header.timestamp = gop_cache->start_time(); | 1599 | + cache_sh_video->timestamp = gop_cache->start_time(); |
| 1600 | } | 1600 | } |
| 1601 | if (cache_sh_audio) { | 1601 | if (cache_sh_audio) { |
| 1602 | - cache_sh_audio->header.timestamp = gop_cache->start_time(); | 1602 | + cache_sh_audio->timestamp = gop_cache->start_time(); |
| 1603 | } | 1603 | } |
| 1604 | } | 1604 | } |
| 1605 | 1605 |
| @@ -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 63 | 34 | +#define VERSION_REVISION 64 |
| 35 | // server info. | 35 | // server info. |
| 36 | #define RTMP_SIG_SRS_KEY "SRS" | 36 | #define RTMP_SIG_SRS_KEY "SRS" |
| 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" | 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" |
| @@ -96,7 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -96,7 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 96 | * that is, 1+4=5bytes. | 96 | * that is, 1+4=5bytes. |
| 97 | */ | 97 | */ |
| 98 | // always use fmt0 as cache. | 98 | // always use fmt0 as cache. |
| 99 | -//#define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5 | 99 | +#define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5 |
| 100 | 100 | ||
| 101 | /** | 101 | /** |
| 102 | * for performance issue, | 102 | * for performance issue, |
| @@ -405,21 +405,25 @@ SrsSharedPtrMessage::__SrsSharedPtr::~__SrsSharedPtr() | @@ -405,21 +405,25 @@ SrsSharedPtrMessage::__SrsSharedPtr::~__SrsSharedPtr() | ||
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | #ifdef SRS_PERF_MW_MSG_IOVS_CACHE | 407 | #ifdef SRS_PERF_MW_MSG_IOVS_CACHE |
| 408 | -int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate( | ||
| 409 | - SrsMessageHeader* mh, int chunk_size | ||
| 410 | -) { | 408 | +int SrsSharedPtrMessage::__SrsSharedPtr::mic_evaluate(int chunk_size) |
| 409 | +{ | ||
| 411 | int ret = ERROR_SUCCESS; | 410 | int ret = ERROR_SUCCESS; |
| 412 | 411 | ||
| 413 | // use the chunk size, shuold not be changed. | 412 | // use the chunk size, shuold not be changed. |
| 414 | this->chunk_size = chunk_size; | 413 | this->chunk_size = chunk_size; |
| 415 | 414 | ||
| 416 | - // ignore size | ||
| 417 | - srs_chunk_header(mic_c0, mh, true); | ||
| 418 | - mic_c3 = 0xC0 | (mh->perfer_cid & 0x3F); | 415 | + // c0 header |
| 416 | + int nbh = srs_chunk_header_c0( | ||
| 417 | + header.perfer_cid, 0, header.payload_length, | ||
| 418 | + header.message_type, 0, | ||
| 419 | + mic_c0, sizeof(mic_c0)); | ||
| 420 | + srs_assert(nbh > 0);; | ||
| 421 | + // c3 header | ||
| 422 | + mic_c3 = 0xC0 | (header.perfer_cid & 0x3F); | ||
| 419 | 423 | ||
| 420 | // calc number of iovs | 424 | // calc number of iovs |
| 421 | - nb_chunks = mh->payload_length / chunk_size; | ||
| 422 | - if (mh->payload_length % chunk_size) { | 425 | + nb_chunks = header.payload_length / chunk_size; |
| 426 | + if (header.payload_length % chunk_size) { | ||
| 423 | nb_chunks++; | 427 | nb_chunks++; |
| 424 | } | 428 | } |
| 425 | nb_iovs = 1/*cid*/ + 1/*size*//*type*/+ 1/*chunk*/; | 429 | nb_iovs = 1/*cid*/ + 1/*size*//*type*/+ 1/*chunk*/; |
| @@ -529,12 +533,14 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | @@ -529,12 +533,14 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | ||
| 529 | return ret; | 533 | return ret; |
| 530 | } | 534 | } |
| 531 | 535 | ||
| 532 | - header = *pheader; | ||
| 533 | - header.payload_length = size; | ||
| 534 | - | ||
| 535 | ptr = new __SrsSharedPtr(); | 536 | ptr = new __SrsSharedPtr(); |
| 536 | 537 | ||
| 537 | // direct attach the data. | 538 | // direct attach the data. |
| 539 | + ptr->header.message_type = pheader->message_type; | ||
| 540 | + ptr->header.payload_length = size; | ||
| 541 | + ptr->header.perfer_cid = pheader->perfer_cid; | ||
| 542 | + this->timestamp = pheader->timestamp; | ||
| 543 | + this->stream_id = pheader->stream_id; | ||
| 538 | ptr->payload = payload; | 544 | ptr->payload = payload; |
| 539 | ptr->size = size; | 545 | ptr->size = size; |
| 540 | 546 | ||
| @@ -551,17 +557,68 @@ int SrsSharedPtrMessage::count() | @@ -551,17 +557,68 @@ int SrsSharedPtrMessage::count() | ||
| 551 | return ptr->shared_count; | 557 | return ptr->shared_count; |
| 552 | } | 558 | } |
| 553 | 559 | ||
| 560 | +bool SrsSharedPtrMessage::check(int stream_id) | ||
| 561 | +{ | ||
| 562 | + // we donot use the complex basic header, | ||
| 563 | + // ensure the basic header is 1bytes. | ||
| 564 | + if (ptr->header.perfer_cid < 2) { | ||
| 565 | + srs_info("change the chunk_id=%d to default=%d", | ||
| 566 | + ptr->header.perfer_cid, RTMP_CID_ProtocolControl); | ||
| 567 | + ptr->header.perfer_cid = RTMP_CID_ProtocolControl; | ||
| 568 | + } | ||
| 569 | + | ||
| 570 | + // we assume that the stream_id in a group must be the same. | ||
| 571 | + if (this->stream_id == stream_id) { | ||
| 572 | + return true; | ||
| 573 | + } | ||
| 574 | + this->stream_id = stream_id; | ||
| 575 | + | ||
| 576 | + return false; | ||
| 577 | +} | ||
| 578 | + | ||
| 579 | +bool SrsSharedPtrMessage::is_av() | ||
| 580 | +{ | ||
| 581 | + return ptr->header.message_type == RTMP_MSG_AudioMessage | ||
| 582 | + || ptr->header.message_type == RTMP_MSG_VideoMessage; | ||
| 583 | +} | ||
| 584 | + | ||
| 585 | +bool SrsSharedPtrMessage::is_audio() | ||
| 586 | +{ | ||
| 587 | + return ptr->header.message_type == RTMP_MSG_AudioMessage; | ||
| 588 | +} | ||
| 589 | + | ||
| 590 | +bool SrsSharedPtrMessage::is_video() | ||
| 591 | +{ | ||
| 592 | + return ptr->header.message_type == RTMP_MSG_VideoMessage; | ||
| 593 | +} | ||
| 594 | + | ||
| 595 | +#ifndef SRS_PERF_MW_MSG_IOVS_CACHE | ||
| 596 | +int SrsSharedPtrMessage::chunk_header(char* cache, int nb_cache, bool c0) | ||
| 597 | +{ | ||
| 598 | + if (c0) { | ||
| 599 | + return srs_chunk_header_c0( | ||
| 600 | + ptr->header.perfer_cid, timestamp, ptr->header.payload_length, | ||
| 601 | + ptr->header.message_type, stream_id, | ||
| 602 | + cache, nb_cache); | ||
| 603 | + } else { | ||
| 604 | + return srs_chunk_header_c3( | ||
| 605 | + ptr->header.perfer_cid, timestamp, | ||
| 606 | + cache, nb_cache); | ||
| 607 | + } | ||
| 608 | +} | ||
| 609 | +#endif | ||
| 610 | + | ||
| 554 | SrsSharedPtrMessage* SrsSharedPtrMessage::copy() | 611 | SrsSharedPtrMessage* SrsSharedPtrMessage::copy() |
| 555 | { | 612 | { |
| 556 | srs_assert(ptr); | 613 | srs_assert(ptr); |
| 557 | 614 | ||
| 558 | SrsSharedPtrMessage* copy = new SrsSharedPtrMessage(); | 615 | SrsSharedPtrMessage* copy = new SrsSharedPtrMessage(); |
| 559 | 616 | ||
| 560 | - copy->header = header; | ||
| 561 | - | ||
| 562 | copy->ptr = ptr; | 617 | copy->ptr = ptr; |
| 563 | ptr->shared_count++; | 618 | ptr->shared_count++; |
| 564 | 619 | ||
| 620 | + copy->timestamp = timestamp; | ||
| 621 | + copy->stream_id = stream_id; | ||
| 565 | copy->payload = ptr->payload; | 622 | copy->payload = ptr->payload; |
| 566 | copy->size = ptr->size; | 623 | copy->size = ptr->size; |
| 567 | 624 | ||
| @@ -583,7 +640,7 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size) | @@ -583,7 +640,7 @@ int SrsSharedPtrMessage::mic_evaluate(int chunk_size) | ||
| 583 | 640 | ||
| 584 | // calc the shared ptr iovs at the first time. | 641 | // calc the shared ptr iovs at the first time. |
| 585 | if (ptr->chunk_size <= 0) { | 642 | if (ptr->chunk_size <= 0) { |
| 586 | - if ((ret = ptr->mic_evaluate(&header, chunk_size)) != ERROR_SUCCESS) { | 643 | + if ((ret = ptr->mic_evaluate(chunk_size)) != ERROR_SUCCESS) { |
| 587 | srs_warn("mic evaluate source iovs failed. ret=%d", ret); | 644 | srs_warn("mic evaluate source iovs failed. ret=%d", ret); |
| 588 | return ret; | 645 | return ret; |
| 589 | } | 646 | } |
| @@ -610,7 +667,7 @@ int SrsSharedPtrMessage::mic_iovs_dump(iovec* iovs, int max_nb_iovs) | @@ -610,7 +667,7 @@ int SrsSharedPtrMessage::mic_iovs_dump(iovec* iovs, int max_nb_iovs) | ||
| 610 | } | 667 | } |
| 611 | 668 | ||
| 612 | // timestamp for c0/c3 | 669 | // timestamp for c0/c3 |
| 613 | - u_int32_t timestamp = (u_int32_t)header.timestamp; | 670 | + u_int32_t timestamp = (u_int32_t)this->timestamp; |
| 614 | mic_etime_present = timestamp >= RTMP_EXTENDED_TIMESTAMP; | 671 | mic_etime_present = timestamp >= RTMP_EXTENDED_TIMESTAMP; |
| 615 | 672 | ||
| 616 | // chunk message header, 11 bytes | 673 | // chunk message header, 11 bytes |
| @@ -629,7 +686,7 @@ int SrsSharedPtrMessage::mic_iovs_dump(iovec* iovs, int max_nb_iovs) | @@ -629,7 +686,7 @@ int SrsSharedPtrMessage::mic_iovs_dump(iovec* iovs, int max_nb_iovs) | ||
| 629 | 686 | ||
| 630 | // stream_id, 4bytes, little-endian | 687 | // stream_id, 4bytes, little-endian |
| 631 | p = mic_c0_sid; | 688 | p = mic_c0_sid; |
| 632 | - pp = (char*)&header.stream_id; | 689 | + pp = (char*)&stream_id; |
| 633 | *p++ = pp[0]; | 690 | *p++ = pp[0]; |
| 634 | *p++ = pp[1]; | 691 | *p++ = pp[1]; |
| 635 | *p++ = pp[2]; | 692 | *p++ = pp[2]; |
| @@ -964,14 +1021,6 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | @@ -964,14 +1021,6 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | ||
| 964 | srs_info("ignore empty message."); | 1021 | srs_info("ignore empty message."); |
| 965 | continue; | 1022 | continue; |
| 966 | } | 1023 | } |
| 967 | - | ||
| 968 | - // we donot use the complex basic header, | ||
| 969 | - // ensure the basic header is 1bytes. | ||
| 970 | - if (msg->header.perfer_cid < 2) { | ||
| 971 | - srs_info("change the chunk_id=%d to default=%d", | ||
| 972 | - msg->header.perfer_cid, RTMP_CID_ProtocolControl); | ||
| 973 | - msg->header.perfer_cid = RTMP_CID_ProtocolControl; | ||
| 974 | - } | ||
| 975 | 1024 | ||
| 976 | // p set to current write position, | 1025 | // p set to current write position, |
| 977 | // it's ok when payload is NULL and size is 0. | 1026 | // it's ok when payload is NULL and size is 0. |
| @@ -981,7 +1030,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | @@ -981,7 +1030,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | ||
| 981 | // always write the header event payload is empty. | 1030 | // always write the header event payload is empty. |
| 982 | while (p < pend) { | 1031 | while (p < pend) { |
| 983 | // always has header | 1032 | // always has header |
| 984 | - int nbh = srs_chunk_header(c0c3_cache, &msg->header, p == msg->payload); | 1033 | + int nb_cache = SRS_CONSTS_C0C3_HEADERS_MAX - c0c3_cache_index; |
| 1034 | + int nbh = msg->chunk_header(c0c3_cache, nb_cache, p == msg->payload); | ||
| 985 | srs_assert(nbh > 0); | 1035 | srs_assert(nbh > 0); |
| 986 | 1036 | ||
| 987 | // header iov | 1037 | // header iov |
| @@ -1066,8 +1116,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | @@ -1066,8 +1116,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) | ||
| 1066 | for (int i = msg_sent; i < nb_msgs; i++) { | 1116 | for (int i = msg_sent; i < nb_msgs; i++) { |
| 1067 | SrsSharedPtrMessage* msg = msgs[i]; | 1117 | SrsSharedPtrMessage* msg = msgs[i]; |
| 1068 | 1118 | ||
| 1069 | - // evaluate | ||
| 1070 | - if ((ret = msg->mic_evaluate(out_chunk_size)) != ERROR_SUCCESS) { | 1119 | + // evaluate the first |
| 1120 | + if (i == 0 && (ret = msg->mic_evaluate(out_chunk_size)) != ERROR_SUCCESS) { | ||
| 1071 | return ret; | 1121 | return ret; |
| 1072 | } | 1122 | } |
| 1073 | 1123 | ||
| @@ -1185,7 +1235,18 @@ int SrsProtocol::do_simple_send(SrsMessageHeader* mh, char* payload, int size) | @@ -1185,7 +1235,18 @@ int SrsProtocol::do_simple_send(SrsMessageHeader* mh, char* payload, int size) | ||
| 1185 | char* end = p + size; | 1235 | char* end = p + size; |
| 1186 | char c0c3[SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE]; | 1236 | char c0c3[SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE]; |
| 1187 | while (p < end) { | 1237 | while (p < end) { |
| 1188 | - int nbh = srs_chunk_header(c0c3, mh, p == payload); | 1238 | + int nbh = 0; |
| 1239 | + if (p == payload) { | ||
| 1240 | + nbh = srs_chunk_header_c0( | ||
| 1241 | + mh->perfer_cid, mh->timestamp, mh->payload_length, | ||
| 1242 | + mh->message_type, mh->stream_id, | ||
| 1243 | + c0c3, sizeof(c0c3)); | ||
| 1244 | + } else { | ||
| 1245 | + nbh = srs_chunk_header_c3( | ||
| 1246 | + mh->perfer_cid, mh->timestamp, | ||
| 1247 | + c0c3, sizeof(c0c3)); | ||
| 1248 | + } | ||
| 1249 | + srs_assert(nbh > 0);; | ||
| 1189 | 1250 | ||
| 1190 | iovec iovs[2]; | 1251 | iovec iovs[2]; |
| 1191 | iovs[0].iov_base = c0c3; | 1252 | iovs[0].iov_base = c0c3; |
| @@ -1388,11 +1449,12 @@ int SrsProtocol::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, | @@ -1388,11 +1449,12 @@ int SrsProtocol::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, | ||
| 1388 | // update the stream id in header. | 1449 | // update the stream id in header. |
| 1389 | for (int i = 0; i < nb_msgs; i++) { | 1450 | for (int i = 0; i < nb_msgs; i++) { |
| 1390 | SrsSharedPtrMessage* msg = msgs[i]; | 1451 | SrsSharedPtrMessage* msg = msgs[i]; |
| 1391 | - // we assume that the stream_id in a group must be the same. | ||
| 1392 | - if (msg->header.stream_id == stream_id) { | 1452 | + |
| 1453 | + // check perfer cid and stream, | ||
| 1454 | + // when one msg stream id is ok, ignore left. | ||
| 1455 | + if (msg->check(stream_id)) { | ||
| 1393 | break; | 1456 | break; |
| 1394 | } | 1457 | } |
| 1395 | - msg->header.stream_id = stream_id; | ||
| 1396 | } | 1458 | } |
| 1397 | 1459 | ||
| 1398 | // donot use the auto free to free the msg, | 1460 | // donot use the auto free to free the msg, |
| @@ -182,6 +182,32 @@ public: | @@ -182,6 +182,32 @@ public: | ||
| 182 | }; | 182 | }; |
| 183 | 183 | ||
| 184 | /** | 184 | /** |
| 185 | +* the message header for shared ptr message. | ||
| 186 | +* only the message for all msgs are same. | ||
| 187 | +*/ | ||
| 188 | +struct SrsSharedMessageHeader | ||
| 189 | +{ | ||
| 190 | + /** | ||
| 191 | + * 3bytes. | ||
| 192 | + * Three-byte field that represents the size of the payload in bytes. | ||
| 193 | + * It is set in big-endian format. | ||
| 194 | + */ | ||
| 195 | + int32_t payload_length; | ||
| 196 | + /** | ||
| 197 | + * 1byte. | ||
| 198 | + * One byte field to represent the message type. A range of type IDs | ||
| 199 | + * (1-7) are reserved for protocol control messages. | ||
| 200 | + */ | ||
| 201 | + int8_t message_type; | ||
| 202 | + /** | ||
| 203 | + * get the perfered cid(chunk stream id) which sendout over. | ||
| 204 | + * set at decoding, and canbe used for directly send message, | ||
| 205 | + * for example, dispatch to all connections. | ||
| 206 | + */ | ||
| 207 | + int perfer_cid; | ||
| 208 | +}; | ||
| 209 | + | ||
| 210 | +/** | ||
| 185 | * shared ptr message. | 211 | * shared ptr message. |
| 186 | * for audio/video/data message that need less memory copy. | 212 | * for audio/video/data message that need less memory copy. |
| 187 | * and only for output. | 213 | * and only for output. |
| @@ -194,7 +220,22 @@ class SrsSharedPtrMessage | @@ -194,7 +220,22 @@ class SrsSharedPtrMessage | ||
| 194 | { | 220 | { |
| 195 | // 4.1. Message Header | 221 | // 4.1. Message Header |
| 196 | public: | 222 | public: |
| 197 | - SrsMessageHeader header; | 223 | + // the header can shared, only set the timestamp and stream id. |
| 224 | + // @see https://github.com/winlinvip/simple-rtmp-server/issues/251 | ||
| 225 | + //SrsSharedMessageHeader header; | ||
| 226 | + /** | ||
| 227 | + * Four-byte field that contains a timestamp of the message. | ||
| 228 | + * The 4 bytes are packed in the big-endian order. | ||
| 229 | + * @remark, used as calc timestamp when decode and encode time. | ||
| 230 | + * @remark, we use 64bits for large time for jitter detect and hls. | ||
| 231 | + */ | ||
| 232 | + int64_t timestamp; | ||
| 233 | + /** | ||
| 234 | + * 4bytes. | ||
| 235 | + * Four-byte field that identifies the stream of the message. These | ||
| 236 | + * bytes are set in big-endian format. | ||
| 237 | + */ | ||
| 238 | + int32_t stream_id; | ||
| 198 | // 4.2. Message Payload | 239 | // 4.2. Message Payload |
| 199 | public: | 240 | public: |
| 200 | /** | 241 | /** |
| @@ -214,6 +255,9 @@ private: | @@ -214,6 +255,9 @@ private: | ||
| 214 | class __SrsSharedPtr | 255 | class __SrsSharedPtr |
| 215 | { | 256 | { |
| 216 | public: | 257 | public: |
| 258 | + // shared message header. | ||
| 259 | + // @see https://github.com/winlinvip/simple-rtmp-server/issues/251 | ||
| 260 | + SrsSharedMessageHeader header; | ||
| 217 | // actual shared payload. | 261 | // actual shared payload. |
| 218 | char* payload; | 262 | char* payload; |
| 219 | // size of payload. | 263 | // size of payload. |
| @@ -269,7 +313,7 @@ private: | @@ -269,7 +313,7 @@ private: | ||
| 269 | * for iovs msg cache, calc the iovs. | 313 | * for iovs msg cache, calc the iovs. |
| 270 | * @param chunk_size use the specified chunk size to evaluate the iovs. | 314 | * @param chunk_size use the specified chunk size to evaluate the iovs. |
| 271 | */ | 315 | */ |
| 272 | - virtual int mic_evaluate(SrsMessageHeader* mh, int chunk_size); | 316 | + virtual int mic_evaluate(int chunk_size); |
| 273 | #endif | 317 | #endif |
| 274 | }; | 318 | }; |
| 275 | __SrsSharedPtr* ptr; | 319 | __SrsSharedPtr* ptr; |
| @@ -312,6 +356,23 @@ public: | @@ -312,6 +356,23 @@ public: | ||
| 312 | * @remark, assert object is created. | 356 | * @remark, assert object is created. |
| 313 | */ | 357 | */ |
| 314 | virtual int count(); | 358 | virtual int count(); |
| 359 | + /** | ||
| 360 | + * check perfer cid and stream id. | ||
| 361 | + * @return whether stream id already set. | ||
| 362 | + */ | ||
| 363 | + virtual bool check(int stream_id); | ||
| 364 | +public: | ||
| 365 | + virtual bool is_av(); | ||
| 366 | + virtual bool is_audio(); | ||
| 367 | + virtual bool is_video(); | ||
| 368 | +public: | ||
| 369 | +#ifndef SRS_PERF_MW_MSG_IOVS_CACHE | ||
| 370 | + /** | ||
| 371 | + * generate the chunk header to cache. | ||
| 372 | + * @return the size of header. | ||
| 373 | + */ | ||
| 374 | + virtual int chunk_header(char* cache, int nb_cache, bool c0); | ||
| 375 | +#endif | ||
| 315 | public: | 376 | public: |
| 316 | /** | 377 | /** |
| 317 | * copy current shared ptr message, use ref-count. | 378 | * copy current shared ptr message, use ref-count. |
| @@ -204,7 +204,11 @@ bool srs_aac_startswith_adts(SrsStream* stream) | @@ -204,7 +204,11 @@ bool srs_aac_startswith_adts(SrsStream* stream) | ||
| 204 | return true; | 204 | return true; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | -int srs_chunk_header(char* cache, SrsMessageHeader* mh, bool c0) | 207 | +int srs_chunk_header_c0( |
| 208 | + int perfer_cid, u_int32_t timestamp, int32_t payload_length, | ||
| 209 | + int8_t message_type, int32_t stream_id, | ||
| 210 | + char* cache, int nb_cache | ||
| 211 | +) | ||
| 208 | { | 212 | { |
| 209 | // to directly set the field. | 213 | // to directly set the field. |
| 210 | char* pp = NULL; | 214 | char* pp = NULL; |
| @@ -212,48 +216,94 @@ int srs_chunk_header(char* cache, SrsMessageHeader* mh, bool c0) | @@ -212,48 +216,94 @@ int srs_chunk_header(char* cache, SrsMessageHeader* mh, bool c0) | ||
| 212 | // generate the header. | 216 | // generate the header. |
| 213 | char* p = cache; | 217 | char* p = cache; |
| 214 | 218 | ||
| 215 | - // timestamp for c0/c3 | ||
| 216 | - u_int32_t timestamp = (u_int32_t)mh->timestamp; | 219 | + // no header. |
| 220 | + if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE) { | ||
| 221 | + return 0; | ||
| 222 | + } | ||
| 217 | 223 | ||
| 218 | - if (c0) { | ||
| 219 | - // write new chunk stream header, fmt is 0 | ||
| 220 | - *p++ = 0x00 | (mh->perfer_cid & 0x3F); | ||
| 221 | - | ||
| 222 | - // chunk message header, 11 bytes | ||
| 223 | - // timestamp, 3bytes, big-endian | ||
| 224 | - if (timestamp < RTMP_EXTENDED_TIMESTAMP) { | ||
| 225 | - pp = (char*)×tamp; | ||
| 226 | - *p++ = pp[2]; | ||
| 227 | - *p++ = pp[1]; | ||
| 228 | - *p++ = pp[0]; | ||
| 229 | - } else { | ||
| 230 | - *p++ = 0xFF; | ||
| 231 | - *p++ = 0xFF; | ||
| 232 | - *p++ = 0xFF; | ||
| 233 | - } | ||
| 234 | - | ||
| 235 | - // message_length, 3bytes, big-endian | ||
| 236 | - pp = (char*)&mh->payload_length; | 224 | + // write new chunk stream header, fmt is 0 |
| 225 | + *p++ = 0x00 | (perfer_cid & 0x3F); | ||
| 226 | + | ||
| 227 | + // chunk message header, 11 bytes | ||
| 228 | + // timestamp, 3bytes, big-endian | ||
| 229 | + if (timestamp < RTMP_EXTENDED_TIMESTAMP) { | ||
| 230 | + pp = (char*)×tamp; | ||
| 237 | *p++ = pp[2]; | 231 | *p++ = pp[2]; |
| 238 | *p++ = pp[1]; | 232 | *p++ = pp[1]; |
| 239 | *p++ = pp[0]; | 233 | *p++ = pp[0]; |
| 240 | - | ||
| 241 | - // message_type, 1bytes | ||
| 242 | - *p++ = mh->message_type; | ||
| 243 | - | ||
| 244 | - // stream_id, 4bytes, little-endian | ||
| 245 | - pp = (char*)&mh->stream_id; | ||
| 246 | - *p++ = pp[0]; | ||
| 247 | - *p++ = pp[1]; | ||
| 248 | - *p++ = pp[2]; | ||
| 249 | - *p++ = pp[3]; | ||
| 250 | } else { | 234 | } else { |
| 251 | - // write no message header chunk stream, fmt is 3 | ||
| 252 | - // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, | ||
| 253 | - // SRS will rollback to 1B chunk header. | ||
| 254 | - *p++ = 0xC0 | (mh->perfer_cid & 0x3F); | 235 | + *p++ = 0xFF; |
| 236 | + *p++ = 0xFF; | ||
| 237 | + *p++ = 0xFF; | ||
| 255 | } | 238 | } |
| 256 | 239 | ||
| 240 | + // message_length, 3bytes, big-endian | ||
| 241 | + pp = (char*)&payload_length; | ||
| 242 | + *p++ = pp[2]; | ||
| 243 | + *p++ = pp[1]; | ||
| 244 | + *p++ = pp[0]; | ||
| 245 | + | ||
| 246 | + // message_type, 1bytes | ||
| 247 | + *p++ = message_type; | ||
| 248 | + | ||
| 249 | + // stream_id, 4bytes, little-endian | ||
| 250 | + pp = (char*)&stream_id; | ||
| 251 | + *p++ = pp[0]; | ||
| 252 | + *p++ = pp[1]; | ||
| 253 | + *p++ = pp[2]; | ||
| 254 | + *p++ = pp[3]; | ||
| 255 | + | ||
| 256 | + // for c0 | ||
| 257 | + // chunk extended timestamp header, 0 or 4 bytes, big-endian | ||
| 258 | + // | ||
| 259 | + // for c3: | ||
| 260 | + // chunk extended timestamp header, 0 or 4 bytes, big-endian | ||
| 261 | + // 6.1.3. Extended Timestamp | ||
| 262 | + // This field is transmitted only when the normal time stamp in the | ||
| 263 | + // chunk message header is set to 0x00ffffff. If normal time stamp is | ||
| 264 | + // set to any value less than 0x00ffffff, this field MUST NOT be | ||
| 265 | + // present. This field MUST NOT be present if the timestamp field is not | ||
| 266 | + // present. Type 3 chunks MUST NOT have this field. | ||
| 267 | + // adobe changed for Type3 chunk: | ||
| 268 | + // FMLE always sendout the extended-timestamp, | ||
| 269 | + // must send the extended-timestamp to FMS, | ||
| 270 | + // must send the extended-timestamp to flash-player. | ||
| 271 | + // @see: ngx_rtmp_prepare_message | ||
| 272 | + // @see: http://blog.csdn.net/win_lin/article/details/13363699 | ||
| 273 | + // TODO: FIXME: extract to outer. | ||
| 274 | + if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { | ||
| 275 | + pp = (char*)×tamp; | ||
| 276 | + *p++ = pp[3]; | ||
| 277 | + *p++ = pp[2]; | ||
| 278 | + *p++ = pp[1]; | ||
| 279 | + *p++ = pp[0]; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + // always has header | ||
| 283 | + return p - cache; | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +int srs_chunk_header_c3( | ||
| 287 | + int perfer_cid, u_int32_t timestamp, | ||
| 288 | + char* cache, int nb_cache | ||
| 289 | +) | ||
| 290 | +{ | ||
| 291 | + // to directly set the field. | ||
| 292 | + char* pp = NULL; | ||
| 293 | + | ||
| 294 | + // generate the header. | ||
| 295 | + char* p = cache; | ||
| 296 | + | ||
| 297 | + // no header. | ||
| 298 | + if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE) { | ||
| 299 | + return 0; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + // write no message header chunk stream, fmt is 3 | ||
| 303 | + // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, | ||
| 304 | + // SRS will rollback to 1B chunk header. | ||
| 305 | + *p++ = 0xC0 | (perfer_cid & 0x3F); | ||
| 306 | + | ||
| 257 | // for c0 | 307 | // for c0 |
| 258 | // chunk extended timestamp header, 0 or 4 bytes, big-endian | 308 | // chunk extended timestamp header, 0 or 4 bytes, big-endian |
| 259 | // | 309 | // |
| @@ -105,12 +105,27 @@ extern bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code = N | @@ -105,12 +105,27 @@ extern bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code = N | ||
| 105 | extern bool srs_aac_startswith_adts(SrsStream* stream); | 105 | extern bool srs_aac_startswith_adts(SrsStream* stream); |
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | -* generate the chunk header for msg. | ||
| 109 | -* @param mh, the header of msg to send. | ||
| 110 | -* @param c0, whether the first chunk, the c0 chunk. | ||
| 111 | -* @return the size of header. | 108 | +* generate the c0 chunk header for msg. |
| 109 | +* @param cache, the cache to write header. | ||
| 110 | +* @param nb_cache, the size of cache. | ||
| 111 | +* @return the size of header. 0 if cache not enough. | ||
| 112 | */ | 112 | */ |
| 113 | -extern int srs_chunk_header(char* cache, SrsMessageHeader* mh, bool c0); | 113 | +extern int srs_chunk_header_c0( |
| 114 | + int perfer_cid, u_int32_t timestamp, int32_t payload_length, | ||
| 115 | + int8_t message_type, int32_t stream_id, | ||
| 116 | + char* cache, int nb_cache | ||
| 117 | +); | ||
| 118 | + | ||
| 119 | +/** | ||
| 120 | +* generate the c3 chunk header for msg. | ||
| 121 | +* @param cache, the cache to write header. | ||
| 122 | +* @param nb_cache, the size of cache. | ||
| 123 | +* @return the size of header. 0 if cache not enough. | ||
| 124 | +*/ | ||
| 125 | +extern int srs_chunk_header_c3( | ||
| 126 | + int perfer_cid, u_int32_t timestamp, | ||
| 127 | + char* cache, int nb_cache | ||
| 128 | +); | ||
| 114 | 129 | ||
| 115 | #endif | 130 | #endif |
| 116 | 131 |
-
请 注册 或 登录 后发表评论