int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t *pstarttime, u_int32_t *ptimestamp) { int ret = 0; // packet data char type; int size; char *data = NULL; srs_human_trace("start ingest flv to RTMP stream"); for (; ;) { // tag header if ((ret = srs_flv_read_tag_header(flv, &type, &size, ptimestamp)) != 0) { if (srs_flv_is_eof(ret)) { srs_human_trace("parse completed."); return 0; } srs_human_trace("flv get packet failed. ret=%d", ret); return ret; } if (size <= 0) { srs_human_trace("invalid size=%d", size); break; } // TODO: FIXME: mem leak when error. data = (char *) malloc(size); if ((ret = srs_flv_read_tag_data(flv, data, size)) != 0) { return ret; } u_int32_t timestamp = *ptimestamp; if ((ret = srs_human_print_rtmp_packet(type, timestamp, data, size)) != 0) { srs_human_trace("print packet failed. ret=%d", ret); return ret; } if ((ret = srs_rtmp_write_packet(ortmp, type, *ptimestamp, data, size)) != 0) { srs_human_trace("irtmp get packet failed. ret=%d", ret); return ret; } if (*pstarttime < 0) { *pstarttime = *ptimestamp; } re_update(re, *pstarttime, *ptimestamp); } return ret; }
PushEngine::PushEngine(JobQueue<OneStreamSharePtr> &jobQueue, JobQueue<StreamEventSharePtr> &streamEventQueue) : m_jobQueue(jobQueue) , m_streamEventQueue(streamEventQueue) , m_thread("PushEngine") , m_timeTick(0) , m_logger(Poco::Logger::get("PushEngine")){ int ret = 0; if ((m_flv = srs_flv_open_read("nba.flv")) == NULL) { m_logger.error("open flv file failed."); m_flv = NULL; } char header[13]; if ((ret = srs_flv_read_header(m_flv, header)) != 0) { m_logger.error("read header error."); } for (;;) { // tag header Frame f; if ((ret = srs_flv_read_tag_header(m_flv, &f.type, &f.size, &f.timestamp)) != 0) { if (srs_flv_is_eof(ret)) { m_logger.information("parse completed."); break; } m_logger.error("flv get packet failed. ret=%d"); break; } if (f.size <= 0) { m_logger.error("invalid size."); break; } f.data = (char*)malloc(f.size); if ((ret = srs_flv_read_tag_data(m_flv, f.data, f.size)) != 0) { m_logger.error("read data error."); break; } m_flvFrame.push_back(f); } m_logger.information("frame size = %d", (int)m_flvFrame.size()); m_thread.start(*this); }
int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t amf0_data, srs_amf0_t filepositions, int64_t metadata_end_offset) { int ret = 0; // flv header char header[13]; // packet data char type; u_int32_t timestamp = 0; char* data = NULL; int32_t size; // metadata srs_amf0_t fileposition = NULL; int amf0_name_size = 0; int i; // the metadata end offset, the next tag start offset. int64_t new_metadata_end_offset = 0; int offset_adjust = 0; // reset to write injected file srs_flv_lseek(ic, 0); if ((ret = srs_flv_read_header(ic, header)) != 0) { return ret; } if ((ret = srs_flv_write_header(oc, header)) != 0) { return ret; } // write metadata if (amf0_name != NULL && amf0_data != NULL) { amf0_name_size = srs_amf0_size(amf0_name); size = amf0_name_size + srs_amf0_size(amf0_data); // adjust all offset of keyframes. new_metadata_end_offset = srs_flv_tellg(oc) + srs_flv_size_tag(size); // the adjust is new offset sub the old offset of metadata end. offset_adjust = new_metadata_end_offset - metadata_end_offset; for (i = 0; i < srs_amf0_strict_array_property_count(filepositions); i++) { fileposition = srs_amf0_strict_array_property_at(filepositions, i); srs_amf0_set_number(fileposition, srs_amf0_to_number(fileposition) + offset_adjust); } data = (char*)malloc(size); memset(data, 0, size); if ((ret = srs_amf0_serialize(amf0_name, data, amf0_name_size)) != 0) { return ret; } if ((ret = srs_amf0_serialize(amf0_data, data + amf0_name_size, size - amf0_name_size)) != 0) { return ret; } if ((ret = srs_flv_write_tag(oc, SRS_RTMP_TYPE_SCRIPT, 0, data, size)) != 0) { return ret; } free(data); } srs_human_trace("build keyframe infos from flv"); for (;;) { // tag header if ((ret = srs_flv_read_tag_header(ic, &type, &size, ×tamp)) != 0) { if (srs_flv_is_eof(ret)) { srs_human_trace("parse completed."); return 0; } srs_human_trace("flv get packet failed. ret=%d", ret); return ret; } if (size <= 0) { srs_human_trace("invalid size=%d", size); break; } // TODO: FIXME: mem leak when error. data = (char*)malloc(size); if ((ret = srs_flv_read_tag_data(ic, data, size)) != 0) { return ret; } // data tag if (type == SRS_RTMP_TYPE_SCRIPT) { continue; } // copy if ((ret = srs_flv_write_tag(oc, type, timestamp, data, size)) != 0) { return ret; } free(data); } return ret; }
int build_keyframes(srs_flv_t ic, srs_amf0_t *pname, srs_amf0_t* pdata, srs_amf0_t* pfilepositions, int64_t* pmetadata_end_offset) { int ret = 0; // flv header char header[13]; // packet data char type; u_int32_t timestamp = 0; char* data = NULL; int32_t size; int64_t offset = 0; // metadata srs_amf0_t amf0_name = NULL; srs_amf0_t amf0_data = NULL; srs_amf0_t keyframes = NULL; srs_amf0_t filepositions = NULL; srs_amf0_t times = NULL; // reset to generate metadata srs_flv_lseek(ic, 0); if ((ret = srs_flv_read_header(ic, header)) != 0) { return ret; } srs_human_trace("build keyframe infos from flv"); for (;;) { offset = srs_flv_tellg(ic); // tag header if ((ret = srs_flv_read_tag_header(ic, &type, &size, ×tamp)) != 0) { if (srs_flv_is_eof(ret)) { srs_human_trace("parse completed."); return 0; } srs_human_trace("flv get packet failed. ret=%d", ret); return ret; } if (size <= 0) { srs_human_trace("invalid size=%d", size); return ret; } // TODO: FIXME: mem leak when error. data = (char*)malloc(size); if ((ret = srs_flv_read_tag_data(ic, data, size)) != 0) { return ret; } // data tag if (type == SRS_RTMP_TYPE_VIDEO) { if (!srs_flv_is_sequence_header(data, size) && srs_flv_is_keyframe(data, size)) { srs_amf0_strict_array_append(filepositions, srs_amf0_create_number(offset)); srs_amf0_strict_array_append(times, srs_amf0_create_number(((double)timestamp)/ 1000)); } } else if (type == SRS_RTMP_TYPE_SCRIPT) { *pmetadata_end_offset = srs_flv_tellg(ic); if ((ret = parse_metadata(data, size, &amf0_name, &amf0_data)) != 0) { return ret; } *pname = amf0_name; *pdata = amf0_data; if (srs_amf0_is_object(amf0_data)) { keyframes = srs_amf0_object_property(amf0_data, "keyframes"); if (keyframes == NULL) { keyframes = srs_amf0_create_object(); srs_amf0_object_property_set(amf0_data, "keyframes", keyframes); } // always clear the old keyframes. srs_amf0_object_clear(keyframes); *pfilepositions = filepositions = srs_amf0_create_strict_array(); srs_amf0_object_property_set(keyframes, "filepositions", filepositions); times = srs_amf0_create_strict_array(); srs_amf0_object_property_set(keyframes, "times", times); } else if (srs_amf0_is_ecma_array(amf0_data)) { keyframes = srs_amf0_ecma_array_property(amf0_data, "keyframes"); if (keyframes == NULL) { keyframes = srs_amf0_create_object(); srs_amf0_ecma_array_property_set(amf0_data, "keyframes", keyframes); } // always clear the old keyframes. srs_amf0_object_clear(keyframes); *pfilepositions = filepositions = srs_amf0_create_strict_array(); srs_amf0_object_property_set(keyframes, "filepositions", filepositions); times = srs_amf0_create_strict_array(); srs_amf0_object_property_set(keyframes, "times", times); } } free(data); } return ret; }