正在显示
8 个修改的文件
包含
269 行增加
和
24 行删除
| @@ -38,6 +38,11 @@ using namespace std; | @@ -38,6 +38,11 @@ using namespace std; | ||
| 38 | #include <srs_kernel_codec.hpp> | 38 | #include <srs_kernel_codec.hpp> |
| 39 | #include <srs_kernel_flv.hpp> | 39 | #include <srs_kernel_flv.hpp> |
| 40 | #include <srs_kernel_file.hpp> | 40 | #include <srs_kernel_file.hpp> |
| 41 | +#include <srs_rtmp_amf0.hpp> | ||
| 42 | +#include <srs_kernel_stream.hpp> | ||
| 43 | + | ||
| 44 | +// update the flv duration and filesize every this interval in ms. | ||
| 45 | +#define __SRS_DVR_UPDATE_DURATION_INTERVAL 60000 | ||
| 41 | 46 | ||
| 42 | SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) | 47 | SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) |
| 43 | { | 48 | { |
| @@ -58,6 +63,9 @@ SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) | @@ -58,6 +63,9 @@ SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) | ||
| 58 | stream_previous_pkt_time = -1; | 63 | stream_previous_pkt_time = -1; |
| 59 | stream_duration = 0; | 64 | stream_duration = 0; |
| 60 | 65 | ||
| 66 | + duration_offset = 0; | ||
| 67 | + filesize_offset = 0; | ||
| 68 | + | ||
| 61 | _srs_config->subscribe(this); | 69 | _srs_config->subscribe(this); |
| 62 | } | 70 | } |
| 63 | 71 | ||
| @@ -150,6 +158,10 @@ int SrsFlvSegment::open(bool use_tmp_file) | @@ -150,6 +158,10 @@ int SrsFlvSegment::open(bool use_tmp_file) | ||
| 150 | return ret; | 158 | return ret; |
| 151 | } | 159 | } |
| 152 | } | 160 | } |
| 161 | + | ||
| 162 | + // update the duration and filesize offset. | ||
| 163 | + duration_offset = 0; | ||
| 164 | + filesize_offset = 0; | ||
| 153 | 165 | ||
| 154 | srs_trace("dvr stream %s to file %s", req->stream.c_str(), path.c_str()); | 166 | srs_trace("dvr stream %s to file %s", req->stream.c_str(), path.c_str()); |
| 155 | 167 | ||
| @@ -164,6 +176,11 @@ int SrsFlvSegment::close() | @@ -164,6 +176,11 @@ int SrsFlvSegment::close() | ||
| 164 | if (!fs->is_open()) { | 176 | if (!fs->is_open()) { |
| 165 | return ret; | 177 | return ret; |
| 166 | } | 178 | } |
| 179 | + | ||
| 180 | + // update duration and filesize. | ||
| 181 | + if ((ret = update_flv_metadata()) != ERROR_SUCCESS) { | ||
| 182 | + return ret; | ||
| 183 | + } | ||
| 167 | 184 | ||
| 168 | fs->close(); | 185 | fs->close(); |
| 169 | 186 | ||
| @@ -203,17 +220,61 @@ int SrsFlvSegment::close() | @@ -203,17 +220,61 @@ int SrsFlvSegment::close() | ||
| 203 | return ret; | 220 | return ret; |
| 204 | } | 221 | } |
| 205 | 222 | ||
| 206 | -int SrsFlvSegment::write_metadata(SrsOnMetaDataPacket* metadata) | 223 | +int SrsFlvSegment::write_metadata(SrsSharedPtrMessage* metadata) |
| 207 | { | 224 | { |
| 208 | int ret = ERROR_SUCCESS; | 225 | int ret = ERROR_SUCCESS; |
| 209 | - | ||
| 210 | - int size = 0; | ||
| 211 | - char* payload = NULL; | ||
| 212 | - if ((ret = metadata->encode(size, payload)) != ERROR_SUCCESS) { | 226 | + |
| 227 | + if (duration_offset || filesize_offset) { | ||
| 228 | + return ret; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + SrsStream stream; | ||
| 232 | + if ((ret = stream.initialize(metadata->payload, metadata->size)) != ERROR_SUCCESS) { | ||
| 233 | + return ret; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + SrsAmf0Any* name = SrsAmf0Any::str(); | ||
| 237 | + SrsAutoFree(SrsAmf0Any, name); | ||
| 238 | + if ((ret = name->read(&stream)) != ERROR_SUCCESS) { | ||
| 213 | return ret; | 239 | return ret; |
| 214 | } | 240 | } |
| 241 | + | ||
| 242 | + SrsAmf0Object* obj = SrsAmf0Any::object(); | ||
| 243 | + SrsAutoFree(SrsAmf0Object, obj); | ||
| 244 | + if ((ret = obj->read(&stream)) != ERROR_SUCCESS) { | ||
| 245 | + return ret; | ||
| 246 | + } | ||
| 247 | + | ||
| 248 | + // remove duration and filesize. | ||
| 249 | + obj->set("filesize", NULL); | ||
| 250 | + obj->set("duration", NULL); | ||
| 251 | + | ||
| 252 | + // add properties. | ||
| 253 | + obj->set("service", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); | ||
| 254 | + obj->set("filesize", SrsAmf0Any::number(0)); | ||
| 255 | + obj->set("duration", SrsAmf0Any::number(0)); | ||
| 256 | + | ||
| 257 | + int size = name->total_size() + obj->total_size(); | ||
| 258 | + char* payload = new char[size]; | ||
| 215 | SrsAutoFree(char, payload); | 259 | SrsAutoFree(char, payload); |
| 260 | + | ||
| 261 | + // 11B flv header, 3B object EOF, 8B number value, 1B number flag. | ||
| 262 | + duration_offset = fs->tellg() + size + 11 - SrsAmf0Size::object_eof() - SrsAmf0Size::number(); | ||
| 263 | + // 2B string flag, 8B number value, 8B string 'duration', 1B number flag | ||
| 264 | + filesize_offset = duration_offset - SrsAmf0Size::utf8("duration") - SrsAmf0Size::number(); | ||
| 265 | + | ||
| 266 | + // convert metadata to bytes. | ||
| 267 | + if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) { | ||
| 268 | + return ret; | ||
| 269 | + } | ||
| 270 | + if ((ret = name->write(&stream)) != ERROR_SUCCESS) { | ||
| 271 | + return ret; | ||
| 272 | + } | ||
| 273 | + if ((ret = obj->write(&stream)) != ERROR_SUCCESS) { | ||
| 274 | + return ret; | ||
| 275 | + } | ||
| 216 | 276 | ||
| 277 | + // to flv file. | ||
| 217 | if ((ret = enc->write_metadata(18, payload, size)) != ERROR_SUCCESS) { | 278 | if ((ret = enc->write_metadata(18, payload, size)) != ERROR_SUCCESS) { |
| 218 | return ret; | 279 | return ret; |
| 219 | } | 280 | } |
| @@ -287,6 +348,62 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* __video) | @@ -287,6 +348,62 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* __video) | ||
| 287 | return ret; | 348 | return ret; |
| 288 | } | 349 | } |
| 289 | 350 | ||
| 351 | +int SrsFlvSegment::update_flv_metadata() | ||
| 352 | +{ | ||
| 353 | + int ret = ERROR_SUCCESS; | ||
| 354 | + | ||
| 355 | + // no duration or filesize specified. | ||
| 356 | + if (!duration_offset || !filesize_offset) { | ||
| 357 | + return ret; | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + int64_t cur = fs->tellg(); | ||
| 361 | + | ||
| 362 | + // buffer to write the size. | ||
| 363 | + char* buf = new char[SrsAmf0Size::number()]; | ||
| 364 | + SrsAutoFree(char, buf); | ||
| 365 | + | ||
| 366 | + SrsStream stream; | ||
| 367 | + if ((ret = stream.initialize(buf, SrsAmf0Size::number())) != ERROR_SUCCESS) { | ||
| 368 | + return ret; | ||
| 369 | + } | ||
| 370 | + | ||
| 371 | + // filesize to buf. | ||
| 372 | + SrsAmf0Any* size = SrsAmf0Any::number((double)cur); | ||
| 373 | + SrsAutoFree(SrsAmf0Any, size); | ||
| 374 | + | ||
| 375 | + stream.skip(-1 * stream.pos()); | ||
| 376 | + if ((ret = size->write(&stream)) != ERROR_SUCCESS) { | ||
| 377 | + return ret; | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + // update the flesize. | ||
| 381 | + fs->lseek(filesize_offset); | ||
| 382 | + if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) { | ||
| 383 | + return ret; | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + // duration to buf | ||
| 387 | + SrsAmf0Any* dur = SrsAmf0Any::number((double)duration / 1000.0); | ||
| 388 | + SrsAutoFree(SrsAmf0Any, dur); | ||
| 389 | + | ||
| 390 | + stream.skip(-1 * stream.pos()); | ||
| 391 | + if ((ret = dur->write(&stream)) != ERROR_SUCCESS) { | ||
| 392 | + return ret; | ||
| 393 | + } | ||
| 394 | + | ||
| 395 | + // update the duration | ||
| 396 | + fs->lseek(duration_offset); | ||
| 397 | + if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) { | ||
| 398 | + return ret; | ||
| 399 | + } | ||
| 400 | + | ||
| 401 | + // reset the offset. | ||
| 402 | + fs->lseek(cur); | ||
| 403 | + | ||
| 404 | + return ret; | ||
| 405 | +} | ||
| 406 | + | ||
| 290 | string SrsFlvSegment::generate_path() | 407 | string SrsFlvSegment::generate_path() |
| 291 | { | 408 | { |
| 292 | // the path in config, for example, | 409 | // the path in config, for example, |
| @@ -498,7 +615,7 @@ int64_t SrsDvrPlan::filter_timestamp(int64_t timestamp) | @@ -498,7 +615,7 @@ int64_t SrsDvrPlan::filter_timestamp(int64_t timestamp) | ||
| 498 | return timestamp; | 615 | return timestamp; |
| 499 | } | 616 | } |
| 500 | 617 | ||
| 501 | -int SrsDvrPlan::on_meta_data(SrsOnMetaDataPacket* metadata) | 618 | +int SrsDvrPlan::on_meta_data(SrsSharedPtrMessage* __metadata) |
| 502 | { | 619 | { |
| 503 | int ret = ERROR_SUCCESS; | 620 | int ret = ERROR_SUCCESS; |
| 504 | 621 | ||
| @@ -506,7 +623,7 @@ int SrsDvrPlan::on_meta_data(SrsOnMetaDataPacket* metadata) | @@ -506,7 +623,7 @@ int SrsDvrPlan::on_meta_data(SrsOnMetaDataPacket* metadata) | ||
| 506 | return ret; | 623 | return ret; |
| 507 | } | 624 | } |
| 508 | 625 | ||
| 509 | - return segment->write_metadata(metadata); | 626 | + return segment->write_metadata(__metadata); |
| 510 | } | 627 | } |
| 511 | 628 | ||
| 512 | int SrsDvrPlan::on_audio(SrsSharedPtrMessage* __audio) | 629 | int SrsDvrPlan::on_audio(SrsSharedPtrMessage* __audio) |
| @@ -606,6 +723,7 @@ void SrsDvrSessionPlan::on_unpublish() | @@ -606,6 +723,7 @@ void SrsDvrSessionPlan::on_unpublish() | ||
| 606 | 723 | ||
| 607 | SrsDvrAppendPlan::SrsDvrAppendPlan() | 724 | SrsDvrAppendPlan::SrsDvrAppendPlan() |
| 608 | { | 725 | { |
| 726 | + last_update_time = 0; | ||
| 609 | } | 727 | } |
| 610 | 728 | ||
| 611 | SrsDvrAppendPlan::~SrsDvrAppendPlan() | 729 | SrsDvrAppendPlan::~SrsDvrAppendPlan() |
| @@ -638,16 +756,74 @@ void SrsDvrAppendPlan::on_unpublish() | @@ -638,16 +756,74 @@ void SrsDvrAppendPlan::on_unpublish() | ||
| 638 | { | 756 | { |
| 639 | } | 757 | } |
| 640 | 758 | ||
| 759 | +int SrsDvrAppendPlan::on_audio(SrsSharedPtrMessage* audio) | ||
| 760 | +{ | ||
| 761 | + int ret = ERROR_SUCCESS; | ||
| 762 | + | ||
| 763 | + if ((ret = update_duration(audio)) != ERROR_SUCCESS) { | ||
| 764 | + return ret; | ||
| 765 | + } | ||
| 766 | + | ||
| 767 | + if ((ret = SrsDvrPlan::on_audio(audio)) != ERROR_SUCCESS) { | ||
| 768 | + return ret; | ||
| 769 | + } | ||
| 770 | + | ||
| 771 | + return ret; | ||
| 772 | +} | ||
| 773 | + | ||
| 774 | +int SrsDvrAppendPlan::on_video(SrsSharedPtrMessage* video) | ||
| 775 | +{ | ||
| 776 | + int ret = ERROR_SUCCESS; | ||
| 777 | + | ||
| 778 | + if ((ret = update_duration(video)) != ERROR_SUCCESS) { | ||
| 779 | + return ret; | ||
| 780 | + } | ||
| 781 | + | ||
| 782 | + if ((ret = SrsDvrPlan::on_video(video)) != ERROR_SUCCESS) { | ||
| 783 | + return ret; | ||
| 784 | + } | ||
| 785 | + | ||
| 786 | + return ret; | ||
| 787 | +} | ||
| 788 | + | ||
| 789 | +int SrsDvrAppendPlan::update_duration(SrsSharedPtrMessage* msg) | ||
| 790 | +{ | ||
| 791 | + int ret = ERROR_SUCCESS; | ||
| 792 | + | ||
| 793 | + if (last_update_time <= 0) { | ||
| 794 | + last_update_time = msg->timestamp; | ||
| 795 | + return ret; | ||
| 796 | + } | ||
| 797 | + | ||
| 798 | + if (msg->timestamp < last_update_time) { | ||
| 799 | + last_update_time = msg->timestamp; | ||
| 800 | + return ret; | ||
| 801 | + } | ||
| 802 | + | ||
| 803 | + if (__SRS_DVR_UPDATE_DURATION_INTERVAL > msg->timestamp - last_update_time) { | ||
| 804 | + return ret; | ||
| 805 | + } | ||
| 806 | + last_update_time = msg->timestamp; | ||
| 807 | + | ||
| 808 | + srs_assert(segment); | ||
| 809 | + if (!segment->update_flv_metadata()) { | ||
| 810 | + return ret; | ||
| 811 | + } | ||
| 812 | + | ||
| 813 | + return ret; | ||
| 814 | +} | ||
| 815 | + | ||
| 641 | SrsDvrSegmentPlan::SrsDvrSegmentPlan() | 816 | SrsDvrSegmentPlan::SrsDvrSegmentPlan() |
| 642 | { | 817 | { |
| 643 | segment_duration = -1; | 818 | segment_duration = -1; |
| 644 | - sh_video = sh_audio = NULL; | 819 | + metadata = sh_video = sh_audio = NULL; |
| 645 | } | 820 | } |
| 646 | 821 | ||
| 647 | SrsDvrSegmentPlan::~SrsDvrSegmentPlan() | 822 | SrsDvrSegmentPlan::~SrsDvrSegmentPlan() |
| 648 | { | 823 | { |
| 649 | srs_freep(sh_video); | 824 | srs_freep(sh_video); |
| 650 | srs_freep(sh_audio); | 825 | srs_freep(sh_audio); |
| 826 | + srs_freep(metadata); | ||
| 651 | } | 827 | } |
| 652 | 828 | ||
| 653 | int SrsDvrSegmentPlan::initialize(SrsSource* source, SrsRequest* req) | 829 | int SrsDvrSegmentPlan::initialize(SrsSource* source, SrsRequest* req) |
| @@ -695,6 +871,20 @@ void SrsDvrSegmentPlan::on_unpublish() | @@ -695,6 +871,20 @@ void SrsDvrSegmentPlan::on_unpublish() | ||
| 695 | { | 871 | { |
| 696 | } | 872 | } |
| 697 | 873 | ||
| 874 | +int SrsDvrSegmentPlan::on_meta_data(SrsSharedPtrMessage* __metadata) | ||
| 875 | +{ | ||
| 876 | + int ret = ERROR_SUCCESS; | ||
| 877 | + | ||
| 878 | + srs_freep(metadata); | ||
| 879 | + metadata = __metadata->copy(); | ||
| 880 | + | ||
| 881 | + if ((ret = SrsDvrPlan::on_meta_data(__metadata)) != ERROR_SUCCESS) { | ||
| 882 | + return ret; | ||
| 883 | + } | ||
| 884 | + | ||
| 885 | + return ret; | ||
| 886 | +} | ||
| 887 | + | ||
| 698 | int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* audio) | 888 | int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* audio) |
| 699 | { | 889 | { |
| 700 | int ret = ERROR_SUCCESS; | 890 | int ret = ERROR_SUCCESS; |
| @@ -774,6 +964,9 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) | @@ -774,6 +964,9 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) | ||
| 774 | } | 964 | } |
| 775 | 965 | ||
| 776 | // update sequence header | 966 | // update sequence header |
| 967 | + if (metadata && (ret = SrsDvrPlan::on_meta_data(metadata)) != ERROR_SUCCESS) { | ||
| 968 | + return ret; | ||
| 969 | + } | ||
| 777 | if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) { | 970 | if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) { |
| 778 | return ret; | 971 | return ret; |
| 779 | } | 972 | } |
| @@ -828,8 +1021,19 @@ void SrsDvr::on_unpublish() | @@ -828,8 +1021,19 @@ void SrsDvr::on_unpublish() | ||
| 828 | int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m) | 1021 | int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m) |
| 829 | { | 1022 | { |
| 830 | int ret = ERROR_SUCCESS; | 1023 | int ret = ERROR_SUCCESS; |
| 831 | - | ||
| 832 | - if ((ret = plan->on_meta_data(m)) != ERROR_SUCCESS) { | 1024 | + |
| 1025 | + int size = 0; | ||
| 1026 | + char* payload = NULL; | ||
| 1027 | + if ((ret = m->encode(size, payload)) != ERROR_SUCCESS) { | ||
| 1028 | + return ret; | ||
| 1029 | + } | ||
| 1030 | + | ||
| 1031 | + SrsSharedPtrMessage metadata; | ||
| 1032 | + if ((ret = metadata.create(NULL, payload, size)) != ERROR_SUCCESS) { | ||
| 1033 | + return ret; | ||
| 1034 | + } | ||
| 1035 | + | ||
| 1036 | + if ((ret = plan->on_meta_data(&metadata)) != ERROR_SUCCESS) { | ||
| 833 | return ret; | 1037 | return ret; |
| 834 | } | 1038 | } |
| 835 | 1039 |
| @@ -67,6 +67,17 @@ private: | @@ -67,6 +67,17 @@ private: | ||
| 67 | SrsRtmpJitterAlgorithm jitter_algorithm; | 67 | SrsRtmpJitterAlgorithm jitter_algorithm; |
| 68 | SrsFileWriter* fs; | 68 | SrsFileWriter* fs; |
| 69 | private: | 69 | private: |
| 70 | + /** | ||
| 71 | + * the offset of file for duration value. | ||
| 72 | + * the next 8 bytes is the double value. | ||
| 73 | + */ | ||
| 74 | + int64_t duration_offset; | ||
| 75 | + /** | ||
| 76 | + * the offset of file for filesize value. | ||
| 77 | + * the next 8 bytes is the double value. | ||
| 78 | + */ | ||
| 79 | + int64_t filesize_offset; | ||
| 80 | +private: | ||
| 70 | std::string tmp_flv_file; | 81 | std::string tmp_flv_file; |
| 71 | private: | 82 | private: |
| 72 | /** | 83 | /** |
| @@ -124,7 +135,7 @@ public: | @@ -124,7 +135,7 @@ public: | ||
| 124 | /** | 135 | /** |
| 125 | * write the metadata to segment. | 136 | * write the metadata to segment. |
| 126 | */ | 137 | */ |
| 127 | - virtual int write_metadata(SrsOnMetaDataPacket* metadata); | 138 | + virtual int write_metadata(SrsSharedPtrMessage* metadata); |
| 128 | /** | 139 | /** |
| 129 | * @param __audio, directly ptr, copy it if need to save it. | 140 | * @param __audio, directly ptr, copy it if need to save it. |
| 130 | */ | 141 | */ |
| @@ -133,6 +144,10 @@ public: | @@ -133,6 +144,10 @@ public: | ||
| 133 | * @param __video, directly ptr, copy it if need to save it. | 144 | * @param __video, directly ptr, copy it if need to save it. |
| 134 | */ | 145 | */ |
| 135 | virtual int write_video(SrsSharedPtrMessage* __video); | 146 | virtual int write_video(SrsSharedPtrMessage* __video); |
| 147 | + /** | ||
| 148 | + * update the flv metadata. | ||
| 149 | + */ | ||
| 150 | + virtual int update_flv_metadata(); | ||
| 136 | private: | 151 | private: |
| 137 | /** | 152 | /** |
| 138 | * generate the flv segment path. | 153 | * generate the flv segment path. |
| @@ -178,7 +193,7 @@ public: | @@ -178,7 +193,7 @@ public: | ||
| 178 | /** | 193 | /** |
| 179 | * when got metadata. | 194 | * when got metadata. |
| 180 | */ | 195 | */ |
| 181 | - virtual int on_meta_data(SrsOnMetaDataPacket* metadata); | 196 | + virtual int on_meta_data(SrsSharedPtrMessage* __metadata); |
| 182 | /** | 197 | /** |
| 183 | * @param __audio, directly ptr, copy it if need to save it. | 198 | * @param __audio, directly ptr, copy it if need to save it. |
| 184 | */ | 199 | */ |
| @@ -213,12 +228,24 @@ public: | @@ -213,12 +228,24 @@ public: | ||
| 213 | */ | 228 | */ |
| 214 | class SrsDvrAppendPlan : public SrsDvrPlan | 229 | class SrsDvrAppendPlan : public SrsDvrPlan |
| 215 | { | 230 | { |
| 231 | +private: | ||
| 232 | + int64_t last_update_time; | ||
| 216 | public: | 233 | public: |
| 217 | SrsDvrAppendPlan(); | 234 | SrsDvrAppendPlan(); |
| 218 | virtual ~SrsDvrAppendPlan(); | 235 | virtual ~SrsDvrAppendPlan(); |
| 219 | public: | 236 | public: |
| 220 | virtual int on_publish(); | 237 | virtual int on_publish(); |
| 221 | virtual void on_unpublish(); | 238 | virtual void on_unpublish(); |
| 239 | + /** | ||
| 240 | + * @param audio, directly ptr, copy it if need to save it. | ||
| 241 | + */ | ||
| 242 | + virtual int on_audio(SrsSharedPtrMessage* audio); | ||
| 243 | + /** | ||
| 244 | + * @param video, directly ptr, copy it if need to save it. | ||
| 245 | + */ | ||
| 246 | + virtual int on_video(SrsSharedPtrMessage* video); | ||
| 247 | +private: | ||
| 248 | + virtual int update_duration(SrsSharedPtrMessage* msg); | ||
| 222 | }; | 249 | }; |
| 223 | 250 | ||
| 224 | /** | 251 | /** |
| @@ -231,6 +258,7 @@ private: | @@ -231,6 +258,7 @@ private: | ||
| 231 | int segment_duration; | 258 | int segment_duration; |
| 232 | SrsSharedPtrMessage* sh_audio; | 259 | SrsSharedPtrMessage* sh_audio; |
| 233 | SrsSharedPtrMessage* sh_video; | 260 | SrsSharedPtrMessage* sh_video; |
| 261 | + SrsSharedPtrMessage* metadata; | ||
| 234 | public: | 262 | public: |
| 235 | SrsDvrSegmentPlan(); | 263 | SrsDvrSegmentPlan(); |
| 236 | virtual ~SrsDvrSegmentPlan(); | 264 | virtual ~SrsDvrSegmentPlan(); |
| @@ -239,6 +267,10 @@ public: | @@ -239,6 +267,10 @@ public: | ||
| 239 | virtual int on_publish(); | 267 | virtual int on_publish(); |
| 240 | virtual void on_unpublish(); | 268 | virtual void on_unpublish(); |
| 241 | /** | 269 | /** |
| 270 | + * when got metadata. | ||
| 271 | + */ | ||
| 272 | + virtual int on_meta_data(SrsSharedPtrMessage* __metadata); | ||
| 273 | + /** | ||
| 242 | * @param audio, directly ptr, copy it if need to save it. | 274 | * @param audio, directly ptr, copy it if need to save it. |
| 243 | */ | 275 | */ |
| 244 | virtual int on_audio(SrsSharedPtrMessage* audio); | 276 | virtual int on_audio(SrsSharedPtrMessage* audio); |
| @@ -116,6 +116,11 @@ bool SrsFileWriter::is_open() | @@ -116,6 +116,11 @@ bool SrsFileWriter::is_open() | ||
| 116 | return fd > 0; | 116 | return fd > 0; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | +void SrsFileWriter::lseek(int64_t offset) | ||
| 120 | +{ | ||
| 121 | + ::lseek(fd, (off_t)offset, SEEK_SET); | ||
| 122 | +} | ||
| 123 | + | ||
| 119 | int64_t SrsFileWriter::tellg() | 124 | int64_t SrsFileWriter::tellg() |
| 120 | { | 125 | { |
| 121 | return (int64_t)::lseek(fd, 0, SEEK_CUR); | 126 | return (int64_t)::lseek(fd, 0, SEEK_CUR); |
| @@ -54,6 +54,7 @@ public: | @@ -54,6 +54,7 @@ public: | ||
| 54 | virtual void close(); | 54 | virtual void close(); |
| 55 | public: | 55 | public: |
| 56 | virtual bool is_open(); | 56 | virtual bool is_open(); |
| 57 | + virtual void lseek(int64_t offset); | ||
| 57 | virtual int64_t tellg(); | 58 | virtual int64_t tellg(); |
| 58 | public: | 59 | public: |
| 59 | /** | 60 | /** |
| @@ -448,11 +448,6 @@ SrsAmf0Any* SrsUnSortedHashtable::value_at(int index) | @@ -448,11 +448,6 @@ SrsAmf0Any* SrsUnSortedHashtable::value_at(int index) | ||
| 448 | 448 | ||
| 449 | void SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) | 449 | void SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) |
| 450 | { | 450 | { |
| 451 | - if (!value) { | ||
| 452 | - srs_warn("add a NULL propertity %s", key.c_str()); | ||
| 453 | - return; | ||
| 454 | - } | ||
| 455 | - | ||
| 456 | std::vector<SrsAmf0ObjectPropertyType>::iterator it; | 451 | std::vector<SrsAmf0ObjectPropertyType>::iterator it; |
| 457 | 452 | ||
| 458 | for (it = properties.begin(); it != properties.end(); ++it) { | 453 | for (it = properties.begin(); it != properties.end(); ++it) { |
| @@ -467,7 +462,9 @@ void SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) | @@ -467,7 +462,9 @@ void SrsUnSortedHashtable::set(string key, SrsAmf0Any* value) | ||
| 467 | } | 462 | } |
| 468 | } | 463 | } |
| 469 | 464 | ||
| 470 | - properties.push_back(std::make_pair(key, value)); | 465 | + if (value) { |
| 466 | + properties.push_back(std::make_pair(key, value)); | ||
| 467 | + } | ||
| 471 | } | 468 | } |
| 472 | 469 | ||
| 473 | SrsAmf0Any* SrsUnSortedHashtable::get_property(string name) | 470 | SrsAmf0Any* SrsUnSortedHashtable::get_property(string name) |
| @@ -794,6 +794,10 @@ namespace _srs_internal | @@ -794,6 +794,10 @@ namespace _srs_internal | ||
| 794 | virtual std::string key_at(int index); | 794 | virtual std::string key_at(int index); |
| 795 | virtual const char* key_raw_at(int index); | 795 | virtual const char* key_raw_at(int index); |
| 796 | virtual SrsAmf0Any* value_at(int index); | 796 | virtual SrsAmf0Any* value_at(int index); |
| 797 | + /** | ||
| 798 | + * set the value of hashtable. | ||
| 799 | + * @param value, the value to set. NULL to delete the property. | ||
| 800 | + */ | ||
| 797 | virtual void set(std::string key, SrsAmf0Any* value); | 801 | virtual void set(std::string key, SrsAmf0Any* value); |
| 798 | public: | 802 | public: |
| 799 | virtual SrsAmf0Any* get_property(std::string name); | 803 | virtual SrsAmf0Any* get_property(std::string name); |
| @@ -434,7 +434,6 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | @@ -434,7 +434,6 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | ||
| 434 | { | 434 | { |
| 435 | int ret = ERROR_SUCCESS; | 435 | int ret = ERROR_SUCCESS; |
| 436 | 436 | ||
| 437 | - srs_assert(pheader != NULL); | ||
| 438 | if (ptr) { | 437 | if (ptr) { |
| 439 | ret = ERROR_SYSTEM_ASSERT_FAILED; | 438 | ret = ERROR_SYSTEM_ASSERT_FAILED; |
| 440 | srs_error("should not set the payload twice. ret=%d", ret); | 439 | srs_error("should not set the payload twice. ret=%d", ret); |
| @@ -446,11 +445,13 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | @@ -446,11 +445,13 @@ int SrsSharedPtrMessage::create(SrsMessageHeader* pheader, char* payload, int si | ||
| 446 | ptr = new __SrsSharedPtr(); | 445 | ptr = new __SrsSharedPtr(); |
| 447 | 446 | ||
| 448 | // direct attach the data. | 447 | // direct attach the data. |
| 449 | - ptr->header.message_type = pheader->message_type; | ||
| 450 | - ptr->header.payload_length = size; | ||
| 451 | - ptr->header.perfer_cid = pheader->perfer_cid; | ||
| 452 | - this->timestamp = pheader->timestamp; | ||
| 453 | - this->stream_id = pheader->stream_id; | 448 | + if (pheader) { |
| 449 | + ptr->header.message_type = pheader->message_type; | ||
| 450 | + ptr->header.payload_length = size; | ||
| 451 | + ptr->header.perfer_cid = pheader->perfer_cid; | ||
| 452 | + this->timestamp = pheader->timestamp; | ||
| 453 | + this->stream_id = pheader->stream_id; | ||
| 454 | + } | ||
| 454 | ptr->payload = payload; | 455 | ptr->payload = payload; |
| 455 | ptr->size = size; | 456 | ptr->size = size; |
| 456 | 457 |
| @@ -283,6 +283,7 @@ public: | @@ -283,6 +283,7 @@ public: | ||
| 283 | * create shared ptr message, | 283 | * create shared ptr message, |
| 284 | * from the header and payload. | 284 | * from the header and payload. |
| 285 | * @remark user should never free the payload. | 285 | * @remark user should never free the payload. |
| 286 | + * @param pheader, the header to copy to the message. NULL to ignore. | ||
| 286 | */ | 287 | */ |
| 287 | virtual int create(SrsMessageHeader* pheader, char* payload, int size); | 288 | virtual int create(SrsMessageHeader* pheader, char* payload, int size); |
| 288 | /** | 289 | /** |
-
请 注册 或 登录 后发表评论