diff --git a/amf.cc b/amf.cc index c3e2df3..5456cbf 100644 --- a/amf.cc +++ b/amf.cc @@ -782,81 +782,81 @@ void amf_data_free(amf_data * data) { } } -///* dump AMF data into a stream as text */ -//void amf_data_dump(FILE * stream, const amf_data * data, int indent_level) { -// if (data != NULL) { -// amf_node * node; -// time_t time; -// struct tm * t; -// char datestr[128]; -// switch (data->type) { -// case AMF_TYPE_NUMBER: +/* dump AMF data into a stream as text */ +void amf_data_dump(FILE * stream, const amf_data * data, int indent_level) { + if (data != NULL) { + amf_node * node; + time_t time; + struct tm * t; + char datestr[128]; + switch (data->type) { + case AMF_TYPE_NUMBER: // fprintf(stream, "%.12g", data->number_data); -// break; -// case AMF_TYPE_BOOLEAN: -// fprintf(stream, "%s", (data->boolean_data) ? "true" : "false"); -// break; -// case AMF_TYPE_STRING: -// fprintf(stream, "\'%.*s\'", data->string_data.size, data->string_data.mbstr); -// break; -// case AMF_TYPE_OBJECT: -// node = amf_object_first(data); -// fprintf(stream, "{\n"); -// while (node != NULL) { -// fprintf(stream, "%*s", (indent_level+1)*4, ""); -// amf_data_dump(stream, amf_object_get_name(node), indent_level+1); -// fprintf(stream, ": "); -// amf_data_dump(stream, amf_object_get_data(node), indent_level+1); -// node = amf_object_next(node); -// fprintf(stream, "\n"); -// } -// fprintf(stream, "%*s", indent_level*4 + 1, "}"); -// break; -// case AMF_TYPE_NULL: -// fprintf(stream, "null"); -// break; -// case AMF_TYPE_UNDEFINED: -// fprintf(stream, "undefined"); -// break; -// /*case AMF_TYPE_REFERENCE:*/ -// case AMF_TYPE_ASSOCIATIVE_ARRAY: -// node = amf_associative_array_first(data); -// fprintf(stream, "{\n"); -// while (node != NULL) { -// fprintf(stream, "%*s", (indent_level+1)*4, ""); -// amf_data_dump(stream, amf_associative_array_get_name(node), indent_level+1); -// fprintf(stream, " => "); -// amf_data_dump(stream, amf_associative_array_get_data(node), indent_level+1); -// node = amf_associative_array_next(node); -// fprintf(stream, "\n"); -// } -// fprintf(stream, "%*s", indent_level*4 + 1, "}"); -// break; -// case AMF_TYPE_ARRAY: -// node = amf_array_first(data); -// fprintf(stream, "[\n"); -// while (node != NULL) { -// fprintf(stream, "%*s", (indent_level+1)*4, ""); -// amf_data_dump(stream, node->data, indent_level+1); -// node = amf_array_next(node); -// fprintf(stream, "\n"); -// } -// fprintf(stream, "%*s", indent_level*4 + 1, "]"); -// break; -// case AMF_TYPE_DATE: -// time = amf_date_to_time_t(data); -// tzset(); -// t = localtime(&time); -// strftime(datestr, sizeof(datestr), "%a, %d %b %Y %H:%M:%S %z", t); -// fprintf(stream, "%s", datestr); -// break; -// /*case AMF_TYPE_SIMPLEOBJECT:*/ -// case AMF_TYPE_XML: break; -// case AMF_TYPE_CLASS: break; -// default: break; -// } -// } -//} + break; + case AMF_TYPE_BOOLEAN: + fprintf(stream, "%s", (data->boolean_data) ? "true" : "false"); + break; + case AMF_TYPE_STRING: + fprintf(stream, "\'%.*s\'", data->string_data.size, data->string_data.mbstr); + break; + case AMF_TYPE_OBJECT: + node = amf_object_first(data); + fprintf(stream, "{\n"); + while (node != NULL) { + fprintf(stream, "%*s", (indent_level+1)*4, ""); + amf_data_dump(stream, amf_object_get_name(node), indent_level+1); + fprintf(stream, ": "); + amf_data_dump(stream, amf_object_get_data(node), indent_level+1); + node = amf_object_next(node); + fprintf(stream, "\n"); + } + fprintf(stream, "%*s", indent_level*4 + 1, "}"); + break; + case AMF_TYPE_NULL: + fprintf(stream, "null"); + break; + case AMF_TYPE_UNDEFINED: + fprintf(stream, "undefined"); + break; + /*case AMF_TYPE_REFERENCE:*/ + case AMF_TYPE_ASSOCIATIVE_ARRAY: + node = amf_associative_array_first(data); + fprintf(stream, "{\n"); + while (node != NULL) { + fprintf(stream, "%*s", (indent_level+1)*4, ""); + amf_data_dump(stream, amf_associative_array_get_name(node), indent_level+1); + fprintf(stream, " => "); + amf_data_dump(stream, amf_associative_array_get_data(node), indent_level+1); + node = amf_associative_array_next(node); + fprintf(stream, "\n"); + } + fprintf(stream, "%*s", indent_level*4 + 1, "}"); + break; + case AMF_TYPE_ARRAY: + node = amf_array_first(data); + fprintf(stream, "[\n"); + while (node != NULL) { + fprintf(stream, "%*s", (indent_level+1)*4, ""); + amf_data_dump(stream, node->data, indent_level+1); + node = amf_array_next(node); + fprintf(stream, "\n"); + } + fprintf(stream, "%*s", indent_level*4 + 1, "]"); + break; + case AMF_TYPE_DATE: + time = amf_date_to_time_t(data); + tzset(); + t = localtime(&time); + strftime(datestr, sizeof(datestr), "%a, %d %b %Y %H:%M:%S %z", t); + fprintf(stream, "%s", datestr); + break; + /*case AMF_TYPE_SIMPLEOBJECT:*/ + case AMF_TYPE_XML: break; + case AMF_TYPE_CLASS: break; + default: break; + } + } +} /* return a null AMF object with the specified error code attached to it */ amf_data * amf_data_error(byte error_code) { diff --git a/amf.h b/amf.h index b6e73bb..ae0a814 100644 --- a/amf.h +++ b/amf.h @@ -146,7 +146,7 @@ amf_data * amf_data_clone(const amf_data * data); /* release the memory of AMF data */ void amf_data_free(amf_data * data); /* dump AMF data into a stream as text */ -//void amf_data_dump(TSIOBufferReader readerp, const amf_data * data, int indent_level); +void amf_data_dump(FILE * stream, const amf_data * data, int indent_level); /* return a null AMF object with the specified error code attached to it */ amf_data * amf_data_error(byte error_code); diff --git a/des.cc b/des.cc index 4fd471c..4607e58 100644 --- a/des.cc +++ b/des.cc @@ -12,7 +12,7 @@ static u_char des_block_size = 8; - +// note: Because each block size is 8, so not less than 8 bytes TSReturnCode des_encrypt(const u_char *key, u_char *data, unsigned len) { diff --git a/drm_flv.cc b/drm_flv.cc index f2f1a02..778c744 100644 --- a/drm_flv.cc +++ b/drm_flv.cc @@ -8,13 +8,15 @@ #include "flv_common.h" -static int drmvideo_handler(TSCont contp, TSEvent event, void *edata); -static void video_cache_lookup_complete(VideoContext *mc, TSHttpTxn txnp); -static void video_add_transform(VideoContext *videoc, TSHttpTxn txnp); -static int video_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */); -static int video_transform_handler(TSCont contp, VideoContext *videoc); -static void video_read_response(VideoContext *videoc, TSHttpTxn txnp); +static int drm_flv_handler(TSCont contp, TSEvent event, void *edata); +static void flv_cache_lookup_complete(FlvContext *fc, TSHttpTxn txnp); +static void flv_add_transform(FlvContext *fc, TSHttpTxn txnp); +static int flv_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */); +static int flv_transform_handler(TSCont contp, FlvContext *fc); +static void flv_read_response(FlvContext *fc, TSHttpTxn txnp); +//des key +static u_char *des_key = NULL; TSReturnCode TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size) @@ -41,6 +43,11 @@ TSRemapNewInstance(int argc, char *argv[], void **instance, char *errbuf, int er des_key = (u_char *)(TSstrdup(argv[2])); TSDebug(PLUGIN_NAME,"TSRemapNewInstance drm video des key is %s",des_key); + if(des_key == NULL) { + TSError("[%s] Plugin not initialized, must have des key", PLUGIN_NAME); + return TS_ERROR; + } + return TS_SUCCESS; } @@ -48,17 +55,13 @@ void TSRemapDeleteInstance(void *instance) { } -//只处理pcf (querty带 ?start=字节数) 和 pcm (带range 请求的) TSRemapStatus TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri) { - const char *method, *query, *path, *range; - int method_len, query_len, path_len, range_len; - size_t val_len; - const char *val; - int ret; + const char *method, *path, *range; + int method_len, path_len, range_len; int64_t start; - VideoContext *videoc; + FlvContext *fc; VideoType video_type; TSMLoc ae_field, range_field; TSCont contp; @@ -81,34 +84,10 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri return TSREMAP_NO_REMAP; } start = 0; -// if (video_type == VIDEO_PCF) { -// query = TSUrlHttpQueryGet(rri->requestBufp, rri->requestUrl, &query_len); -// -// val = ts_arg(query, query_len, "start", sizeof("start") - 1, &val_len); -// if (val != NULL) { -// ret = sscanf(val, "%ld", &start); -// if (ret != 1) -// start = 0; -// } -// -// if (start < 0 ) { -// TSHttpTxnSetHttpRetStatus(rh, TS_HTTP_STATUS_BAD_REQUEST); -// TSHttpTxnErrorBodySet(rh, TSstrdup("Invalid request."), sizeof("Invalid request.") - 1, NULL); -// //return TSREMAP_NO_REMAP;//?需不需要 删除query ,走正常的流程 -// } -// //删除query string -// if (TSUrlHttpQuerySet(rri->requestBufp, rri->requestUrl, "", -1) == TS_ERROR) { -// return TSREMAP_NO_REMAP; -// } -// // just for debug -// char *s; -// int len; -// s = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &len); -// TSDebug(PLUGIN_NAME, "new request string is [%.*s]", len, s); -// TSfree(s); -// } else if(video_type == VIDEO_PCM) { //TODO VIDEO_PCM -// -// } + + if (TSUrlHttpQuerySet(rri->requestBufp, rri->requestUrl, "", -1) == TS_ERROR) { + return TSREMAP_NO_REMAP; + } // remove Range request Range: bytes=500-999, response Content-Range: bytes 21010-47021/47022 range_field = TSMimeHdrFieldFind(rri->requestBufp, rri->requestHdrp, TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE); @@ -116,8 +95,9 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri range = TSMimeHdrFieldValueStringGet(rri->requestBufp, rri->requestHdrp, range_field, -1, &range_len); size_t b_len = sizeof("bytes=") -1; if (range && (strncasecmp(range, "bytes=", b_len) == 0)) { - //获取range value + //get range value start = (int64_t)strtol(range+b_len, NULL, 10); + TSDebug(PLUGIN_NAME, "TSRemapDoRemap start=%ld ", start); } TSMimeHdrFieldDestroy(rri->requestBufp, rri->requestHdrp, range_field); TSHandleMLocRelease(rri->requestBufp, rri->requestHdrp, range_field); @@ -126,10 +106,9 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri if (start < 0 ) { TSHttpTxnSetHttpRetStatus(rh, TS_HTTP_STATUS_BAD_REQUEST); TSHttpTxnErrorBodySet(rh, TSstrdup("Invalid request."), sizeof("Invalid request.") - 1, NULL); - return TSREMAP_NO_REMAP;//?需不需要 删除query ,走正常的流程 } - if (start == 0)//如果不是range 请求就不处理 + if (start == 0) return TSREMAP_NO_REMAP; // remove Accept-Encoding @@ -139,11 +118,11 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri TSHandleMLocRelease(rri->requestBufp, rri->requestHdrp, ae_field); } - videoc = new VideoContext(video_type,start); + fc = new FlvContext(video_type,start); TSDebug(PLUGIN_NAME, "TSRemapDoRemap start=%ld, type=%d", start, video_type); - contp = TSContCreate((TSEventFunc) drmvideo_handler, NULL); - TSContDataSet(contp, videoc); + contp = TSContCreate((TSEventFunc) drm_flv_handler, NULL); + TSContDataSet(contp, fc); TSHttpTxnHookAdd(rh, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, contp); TSHttpTxnHookAdd(rh, TS_HTTP_READ_RESPONSE_HDR_HOOK, contp); TSHttpTxnHookAdd(rh, TS_HTTP_TXN_CLOSE_HOOK, contp); @@ -152,26 +131,26 @@ TSRemapDoRemap(void * /* ih ATS_UNUSED */, TSHttpTxn rh, TSRemapRequestInfo *rri } static int -drmvideo_handler(TSCont contp, TSEvent event, void *edata) { +drm_flv_handler(TSCont contp, TSEvent event, void *edata) { TSHttpTxn txnp; - VideoContext *videoc; + FlvContext *fc; txnp = (TSHttpTxn)edata; - videoc = (VideoContext *)TSContDataGet(contp); + fc = (FlvContext *)TSContDataGet(contp); switch (event) { case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: - video_cache_lookup_complete(videoc, txnp); + flv_cache_lookup_complete(fc, txnp); break; case TS_EVENT_HTTP_READ_RESPONSE_HDR: - video_read_response(videoc, txnp); + flv_read_response(fc, txnp); break; case TS_EVENT_HTTP_TXN_CLOSE: TSDebug(PLUGIN_NAME, "TS_EVENT_HTTP_TXN_CLOSE"); - delete videoc; + delete fc; TSContDestroy(contp); break; @@ -184,7 +163,7 @@ drmvideo_handler(TSCont contp, TSEvent event, void *edata) { } static void -video_read_response(VideoContext *videoc, TSHttpTxn txnp) +flv_read_response(FlvContext *fc, TSHttpTxn txnp) { TSMBuffer bufp; TSMLoc hdrp; @@ -212,8 +191,8 @@ video_read_response(VideoContext *videoc, TSHttpTxn txnp) if (n <= 0) goto release; - videoc->cl = n; - video_add_transform(videoc, txnp); + fc->cl = n; + flv_add_transform(fc, txnp); release: @@ -222,7 +201,7 @@ video_read_response(VideoContext *videoc, TSHttpTxn txnp) } static void -video_cache_lookup_complete(VideoContext *videoc, TSHttpTxn txnp) +flv_cache_lookup_complete(FlvContext *fc, TSHttpTxn txnp) { TSMBuffer bufp; TSMLoc hdrp; @@ -260,8 +239,8 @@ video_cache_lookup_complete(VideoContext *videoc, TSHttpTxn txnp) if (n <= 0) goto release; - videoc->cl = n; - video_add_transform(videoc, txnp); + fc->cl = n; + flv_add_transform(fc, txnp); release: @@ -269,33 +248,33 @@ video_cache_lookup_complete(VideoContext *videoc, TSHttpTxn txnp) } static void -video_add_transform(VideoContext *videoc, TSHttpTxn txnp) +flv_add_transform(FlvContext *fc, TSHttpTxn txnp) { TSVConn connp; - VideoTransformContext *vtc; + FlvTransformContext *ftc; - if (videoc->transform_added) + if (fc->transform_added) return; - vtc = new VideoTransformContext(videoc->video_type,videoc->start, videoc->cl, des_key); + ftc = new FlvTransformContext(fc->video_type,fc->start, fc->cl, des_key); TSHttpTxnUntransformedRespCache(txnp, 1); TSHttpTxnTransformedRespCache(txnp, 0); - connp = TSTransformCreate(video_transform_entry, txnp); - TSContDataSet(connp, videoc); + connp = TSTransformCreate(flv_transform_entry, txnp); + TSContDataSet(connp, fc); TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp); - videoc->transform_added = true; - videoc->vtc = vtc; + fc->transform_added = true; + fc->ftc = ftc; } static int -video_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */) +flv_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */) { TSDebug(PLUGIN_NAME, "start TS_HTTP_RESPONSE_TRANSFORM_HOOK"); TSVIO input_vio; - VideoContext *videoc = (VideoContext *)TSContDataGet(contp); + FlvContext *fc = (FlvContext *)TSContDataGet(contp); if (TSVConnClosedGet(contp)) { TSContDestroy(contp); @@ -314,7 +293,7 @@ video_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */ case TS_EVENT_VCONN_WRITE_READY: default: - video_transform_handler(contp, videoc); + flv_transform_handler(contp, fc); break; } @@ -322,27 +301,27 @@ video_transform_entry(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */ } static int -video_transform_handler(TSCont contp, VideoContext *videoc) +flv_transform_handler(TSCont contp, FlvContext *fc) { TSVConn output_conn; TSVIO input_vio; TSIOBufferReader input_reader; - int64_t avail, toread, upstream_done, tag_avail; + int64_t avail, toread, upstream_done, tag_avail, dup_avail; int ret; bool write_down; FlvTag *ftag; - VideoTransformContext *vtc; - vtc = videoc->vtc; - ftag = &(vtc->ftag); + FlvTransformContext *ftc; + ftc = fc->ftc; + ftag = &(ftc->ftag); output_conn = TSTransformOutputVConnGet(contp); input_vio = TSVConnWriteVIOGet(contp); input_reader = TSVIOReaderGet(input_vio); if (!TSVIOBufferGet(input_vio)) { - if (vtc->output.vio) { - TSVIONBytesSet(vtc->output.vio, vtc->total); - TSVIOReenable(vtc->output.vio); + if (ftc->output.vio) { + TSVIONBytesSet(ftc->output.vio, ftc->total); + TSVIOReenable(ftc->output.vio); } return 1; } @@ -350,47 +329,57 @@ video_transform_handler(TSCont contp, VideoContext *videoc) avail = TSIOBufferReaderAvail(input_reader); upstream_done = TSVIONDoneGet(input_vio); - TSIOBufferCopy(vtc->res_buffer, input_reader, avail, 0); + TSIOBufferCopy(ftc->res_buffer, input_reader, avail, 0); TSIOBufferReaderConsume(input_reader, avail); TSVIONDoneSet(input_vio, upstream_done + avail); toread = TSVIONTodoGet(input_vio); write_down = false; - if (!vtc->parse_over) {//有没有开始解析 - ret = ftag->process_tag(vtc->res_reader, toread <= 0); - if (ret == 0) { //为0 说明还没解析好 + if (!ftc->parse_over) { + ret = ftag->process_tag(ftc->res_reader, toread <= 0); + if (ret == 0) { goto trans; } - vtc->parse_over = true; - - vtc->output.buffer = TSIOBufferCreate(); - vtc->output.reader = TSIOBufferReaderAlloc(vtc->output.buffer); - vtc->output.vio = TSVConnWrite(output_conn, contp, vtc->output.reader, ftag->content_length); - - tag_avail = ftag->write_out(vtc->output.buffer); - if (tag_avail > 0) {//专门来处理头的数据 - vtc->total += tag_avail; - write_down = true; + ftc->parse_over = true; + + ftc->output.buffer = TSIOBufferCreate(); + ftc->output.reader = TSIOBufferReaderAlloc(ftc->output.buffer); + ftc->output.vio = TSVConnWrite(output_conn, contp, ftc->output.reader, ftag->content_length); + + if(ret < 0) { + dup_avail = TSIOBufferReaderAvail(ftag->dup_reader); + if (dup_avail > 0) { + TSIOBufferCopy(ftc->output.buffer, ftag->dup_reader, dup_avail, 0); + TSIOBufferReaderConsume(ftag->dup_reader, dup_avail); + ftc->total += dup_avail; + write_down = true; + } + } else { + tag_avail = ftag->write_out(ftc->output.buffer); + if (tag_avail > 0) { + ftc->total += tag_avail; + write_down = true; + } } } - avail = TSIOBufferReaderAvail(vtc->res_reader); - if (avail > 0) {//将res_reader的数据copy 到output - TSIOBufferCopy(vtc->output.buffer, vtc->res_reader, avail, 0); - TSIOBufferReaderConsume(vtc->res_reader, avail); - vtc->total += avail; + avail = TSIOBufferReaderAvail(ftc->res_reader); + if (avail > 0) { + TSIOBufferCopy(ftc->output.buffer, ftc->res_reader, avail, 0); + TSIOBufferReaderConsume(ftc->res_reader, avail); + ftc->total += avail; write_down = true; } trans: if (write_down) - TSVIOReenable(vtc->output.vio); + TSVIOReenable(ftc->output.vio); - if (toread > 0) {//如果还有需要读的话,继续write_ready + if (toread > 0) { TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_READY, input_vio); - } else {//如果没有的话,就通知write_complete - TSVIONBytesSet(vtc->output.vio, vtc->total); + } else { + TSVIONBytesSet(ftc->output.vio, ftc->total); TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_COMPLETE, input_vio); } diff --git a/flv_common.h b/flv_common.h index 0403b96..8fedf9b 100644 --- a/flv_common.h +++ b/flv_common.h @@ -21,9 +21,6 @@ #include "flv_tag.h" -//#define PLUGIN_NAME "drm_video" -//des key -static u_char *des_key = NULL; class IOHandle { @@ -49,24 +46,21 @@ class IOHandle TSIOBufferReader reader; }; -class VideoTransformContext +class FlvTransformContext { public: - VideoTransformContext(int16_t video_type,int64_t st, int64_t n, u_char *des_key) : total(0), parse_over(false) + FlvTransformContext(int16_t video_type,int64_t st, int64_t n, u_char *des_key) : total(0), parse_over(false) { res_buffer = TSIOBufferCreate(); res_reader = TSIOBufferReaderAlloc(res_buffer); - ftag.start = st; //请求的range 起始位置 - ftag.cl = n; //加密之后文件的大小,即pcf,pcm 大小 - ftag.video_type = video_type;//文件类型 + ftag.start = st; + ftag.cl = n; + ftag.video_type = video_type; ftag.tdes_key = des_key; - if(video_type == FLV_VIDEO) { - ftag.set_flv_function(); - } } - ~VideoTransformContext() + ~FlvTransformContext() { if (res_reader) { TSIOBufferReaderFree(res_reader); @@ -88,26 +82,26 @@ class VideoTransformContext bool parse_over; }; -class VideoContext +class FlvContext { public: - VideoContext(int16_t videotype, int64_t s) :start(s), cl(0) , video_type(videotype), transform_added(false),vtc(NULL){}; + FlvContext(int16_t videotype, int64_t s) :start(s), cl(0) , video_type(videotype), transform_added(false),ftc(NULL){}; - ~VideoContext() + ~FlvContext() { - if(vtc) { - delete vtc; - vtc = NULL; + if(ftc) { + delete ftc; + ftc = NULL; } } public: - int64_t start; //请求的range 起始位置 - int64_t cl; //加密之后文件的大小,即pcf 大小 + int64_t start; + int64_t cl; int16_t video_type; bool transform_added; - VideoTransformContext *vtc; + FlvTransformContext *ftc; }; #endif /* __VIDEO_COMMON_H__ */ diff --git a/flv_tag.cc b/flv_tag.cc index d2ad124..2882313 100644 --- a/flv_tag.cc +++ b/flv_tag.cc @@ -5,11 +5,7 @@ * Author: xie */ -#ifndef __FLV_ENCRYPTION_CC__ -#define __FLV_ENCRYPTION_CC__ - #include "flv_tag.h" - #include "des.h" static int64_t IOBufferReaderCopy(TSIOBufferReader readerp, void *buf, int64_t length); @@ -29,10 +25,6 @@ static uint64_t double2int(double f) return v.i; } -void FlvTag::set_flv_function(){ - this->current_handler = &FlvTag::process_initial_flv_header; -} - int FlvTag::process_tag(TSIOBufferReader readerp, bool complete) { int64_t avail, head_avail; int rc; @@ -42,8 +34,11 @@ int FlvTag::process_tag(TSIOBufferReader readerp, bool complete) { TSIOBufferReaderConsume(readerp, avail); + if(video_type == FLV_VIDEO && !is_init_current_handler) { + this->current_handler = &FlvTag::process_initial_flv_header; + this->is_init_current_handler = true; + } rc = (this->*current_handler)(); - if (rc == 0 && complete) { rc = -1; } @@ -51,7 +46,11 @@ int FlvTag::process_tag(TSIOBufferReader readerp, bool complete) { if (rc) { head_avail = TSIOBufferReaderAvail(head_reader); content_length = (cl - tag_pos) + head_avail; - TSDebug(PLUGIN_NAME, " content_length = %ld, discard_size=%lu ",content_length, duration_file_size); +// TSDebug(PLUGIN_NAME, " content_length = %ld, discard_size=%lu ",content_length, duration_file_size); + } + + if(rc < 0) { + this->content_length = this->cl; } return rc; @@ -70,7 +69,7 @@ int64_t FlvTag::write_out(TSIOBuffer buffer) { return head_avail; } -int FlvTag::process_drm_header() //先解析pcf 的头 signature, version, videoid tag, userid tag, reserved tag +int FlvTag::process_drm_header() //parse pcf header signature, version, videoid tag, userid tag, reserved tag { int64_t avail; @@ -82,8 +81,6 @@ int FlvTag::process_drm_header() //先解析pcf 的头 signature, version, video if (avail < (int64_t)drm_header_size) return 0; - TSDebug(PLUGIN_NAME, "drm_header_size = %lu", drm_header_size); - //先拷贝 TSIOBufferCopy(head_buffer, tag_reader, drm_header_size, 0); result = flv_read_drm_header(tag_reader, &header); @@ -94,16 +91,13 @@ int FlvTag::process_drm_header() //先解析pcf 的头 signature, version, video } version = swap_uint32(header.version); - TSDebug(PLUGIN_NAME, "drm version = %d", version); if (version <= 0) return -1; videoid_size = swap_uint32(header.videoid_size); - TSDebug(PLUGIN_NAME, " drm videoid_size = %d", videoid_size); if (videoid_size <= 0) return -1; - TSDebug(PLUGIN_NAME, "process_header tag_pos=%ld", tag_pos); //已经消费了多少字节 this->current_handler = &FlvTag::process_drm_header_videoid; return process_drm_header_videoid(); @@ -128,13 +122,13 @@ int FlvTag::process_drm_header_videoid() { TSIOBufferCopy(head_buffer, tag_reader, userid_size_length, 0); TSIOBufferReaderConsume(tag_reader, userid_size_length); - tag_pos += read_size;//总共消费了多少字节 + tag_pos += read_size; if (userid_size <= 0) return -1; - TSDebug(PLUGIN_NAME,"process_header_videoid videoid=%.*s, userid_size=%d, tag_pos=%ld", - videoid_size, videoid, userid_size, tag_pos); +// TSDebug(PLUGIN_NAME,"process_header_videoid videoid=%.*s, userid_size=%d, tag_pos=%ld", +// videoid_size, videoid, userid_size, tag_pos); this->current_handler = &FlvTag::process_drm_header_userid; return process_drm_header_userid(); @@ -161,9 +155,9 @@ int FlvTag::process_drm_header_userid() { tag_pos += read_size; - drm_head_length = tag_pos;//drm head 的长度 + drm_head_length = tag_pos; - TSDebug(PLUGIN_NAME,"process_header_userid userid=%.*s, reserved_size=%d, tag_pos=%ld",userid_size, userid, reserved_size, tag_pos); +// TSDebug(PLUGIN_NAME,"process_header_userid userid=%.*s, reserved_size=%d, tag_pos=%ld",userid_size, userid, reserved_size, tag_pos); if (reserved_size <= 0) { this->current_handler = &FlvTag::process_decrypt_flv_body; @@ -189,21 +183,18 @@ int FlvTag::process_drm_header_reserved() { tag_pos += reserved_size; - drm_head_length = tag_pos; //drm head 的长度 + drm_head_length = tag_pos; - TSDebug(PLUGIN_NAME, "process_header_reserved reserved=%.*s", reserved_size,reserved); this->current_handler = &FlvTag::process_decrypt_flv_body; return process_decrypt_flv_body(); } -//解密FLV 前FLV_1_DES_LENGTH * FLV_1_DES_COUNT or FLV_3_DES_LENGTH * FLV_3_DES_COUNT int FlvTag::process_decrypt_flv_body() { int64_t avail; u_char *des_buf; uint32_t i; - //check 文件总长度,是否大于必须的,如果小于直接return -1 根据version 确定加密方式 size_t need_length; if(version == VIDEO_VERSION_1) { flv_need_des_length = FLV_1_NEED_DES_LENGTH; @@ -225,12 +216,12 @@ int FlvTag::process_decrypt_flv_body() { if (avail < (int64_t)need_length) return 0; - TSIOBufferCopy(des_buffer, tag_reader, avail, 0); //全部拷贝到des_buffer中 + TSIOBufferCopy(des_buffer, tag_reader, avail, 0); TSIOBufferReaderConsume(tag_reader, avail); des_buf = (u_char *)TSmalloc(sizeof(u_char) * flv_des_length); for(i = 0; i < flv_des_section_count; i++) { - memset(des_buf, 0, sizeof(des_buf)); + memset(des_buf, 0, flv_des_length); IOBufferReaderCopy(des_reader, des_buf, flv_des_length); des_decrypt(tdes_key, des_buf, flv_des_length); TSIOBufferWrite(tag_buffer, des_buf, flv_need_des_length); @@ -246,7 +237,7 @@ int FlvTag::process_decrypt_flv_body() { TSIOBufferCopy(tag_buffer, des_reader, avail, 0); } - tag_pos += (flv_des_length - flv_need_des_length) * flv_des_section_count; //已经消费了多少 解密之后 又放回去了,也就是 136 - 128 + tag_pos += (flv_des_length - flv_need_des_length) * flv_des_section_count; TSDebug(PLUGIN_NAME, "process_decrypt_body tag_pos=%ld", tag_pos); @@ -280,9 +271,6 @@ int FlvTag::process_initial_flv_header() { return -1; } - TSDebug(PLUGIN_NAME, "process_initial_video_header %.*s", 3, header.signature); - TSDebug(PLUGIN_NAME, "process_initial_video_header header.offset %d",swap_uint32(header.offset)); - TSDebug(PLUGIN_NAME, "process_initial_video_header tag_pos = %ld", tag_pos); this->current_handler = &FlvTag::process_initial_body; return process_initial_body(); @@ -293,9 +281,7 @@ int FlvTag::process_initial_body() { uint64_t avail, sz; uint32 body_length; size_t flv_tag_length = get_flv_tag_size(); // - TSDebug(PLUGIN_NAME, "process_initial_body"); avail = TSIOBufferReaderAvail(tag_reader); - TSDebug(PLUGIN_NAME, "process_initial_body avail=%lu", avail); do { flv_tag tag; @@ -303,20 +289,16 @@ int FlvTag::process_initial_body() { return 0; flv_read_flv_tag(tag_reader, &tag); -// IOBufferReaderCopy(tag_reader, &tag, flv_tag_length); body_length = flv_tag_get_body_length(tag); sz = flv_tag_length + body_length + sizeof(uint32_be); //tag->(tag header, tag body), tagsize - TSDebug(PLUGIN_NAME, "process_initial_body body_length=%d type = %d", body_length, tag.type); if (avail < sz) // insure the whole tag return 0; if (tag.type == FLV_TAG_TYPE_VIDEO ) { - TSDebug(PLUGIN_NAME, "process_initial_body FLV_VIDEODATA 9"); goto end; } else if(tag.type == FLV_TAG_TYPE_META) { - TSDebug(PLUGIN_NAME, "process_initial_body FLV_TAG_TYPE_META"); on_meta_data_size = body_length; } @@ -332,7 +314,6 @@ int FlvTag::process_initial_body() { end: - TSDebug(PLUGIN_NAME, "process_initial_body tag_pos %ld", tag_pos); avail = TSIOBufferReaderAvail(flv_reader); video_body_size += avail; //url?start=datasize (包括flv head + flv 脚本,即所有内容) @@ -346,7 +327,6 @@ int FlvTag::process_medial_body() { uint32 body_length, timestamp; size_t flv_tag_length = get_flv_tag_size(); - TSDebug(PLUGIN_NAME, "process_medial_body"); avail = TSIOBufferReaderAvail(tag_reader); do { @@ -355,7 +335,6 @@ int FlvTag::process_medial_body() { return 0; flv_read_flv_tag(tag_reader, &tag); -// IOBufferReaderCopy(tag_reader, &tag, flv_tag_length); body_length = flv_tag_get_body_length(tag); sz = flv_tag_length + body_length + sizeof(uint32_be); //tag->(tag header, tag body), tagsize @@ -365,33 +344,29 @@ int FlvTag::process_medial_body() { video_body_size += sz; if (tag.type == FLV_TAG_TYPE_VIDEO ) { - TSDebug(PLUGIN_NAME, "process_medial_body FLV_TAG_TYPE_VIDEO"); timestamp = flv_tag_get_timestamp(tag); if ((int64_t)video_body_size <= start) { - duration_time = timestamp; //毫秒 - duration_video_size += flv_tag_length + body_length; //丢弃的video - TSDebug(PLUGIN_NAME, "process_medial_body duration_time=%lf, ts= %d",duration_time,timestamp); + duration_time = timestamp; //ms + duration_video_size += flv_tag_length + body_length; } else { - TSDebug(PLUGIN_NAME, "video_body_size > start !!"); - TSDebug(PLUGIN_NAME, "process_medial_body video_body_size=%ld, start= %ld",video_body_size,start); TSIOBufferCopy(flv_buffer, tag_reader, avail, 0); TSIOBufferReaderConsume(tag_reader, avail); tag_pos += avail; duration_time = duration_time/1000; - TSDebug(PLUGIN_NAME, "process_medial_body success!!! duration_audio_size=%ld, tag_pos= %ld",duration_audio_size,tag_pos); +// TSDebug(PLUGIN_NAME, "process_medial_body success!!! duration_audio_size=%ld, tag_pos= %ld",duration_audio_size,tag_pos); this->current_handler = &FlvTag::process_check_des_body; return process_check_des_body(); } - } else if(tag.type == FLV_TAG_TYPE_AUDIO) { //音频 - duration_audio_size += flv_tag_length + body_length; //丢弃的audio + } else if(tag.type == FLV_TAG_TYPE_AUDIO) { + duration_audio_size += flv_tag_length + body_length; } TSIOBufferReaderConsume(tag_reader, sz); - duration_file_size += sz; //丢弃的多少数据 + duration_file_size += sz; avail -= sz; @@ -403,14 +378,13 @@ int FlvTag::process_medial_body() { } int FlvTag::update_flv_meta_data() { - //copy FLV HEADER + first TAG SIZE size_t flv_header_length = get_flv_header_size() + sizeof(uint32_be);//sizeof(flv_header) + sizeof(uint32_be); size_t flv_tag_size = get_flv_tag_size(); TSIOBufferCopy(new_flv_buffer, flv_reader, flv_header_length, 0); TSIOBufferReaderConsume(flv_reader, flv_header_length); TSDebug(PLUGIN_NAME, "update_flv_meta_data copy flv header + first tag size to new_flv_buffer"); - //解析flv tag + //parse flv tag flv_tag tag; uint32 body_length; amf_data * name; @@ -425,29 +399,24 @@ int FlvTag::update_flv_meta_data() { on_metadata_name = NULL; on_medata_size = 0; - TSDebug(PLUGIN_NAME, "update_flv_meta_data flv_tag_size = %lu",flv_tag_size); flv_read_flv_tag(flv_reader, &tag); -// IOBufferReaderCopy(flv_reader, &tag, flv_tag_size); TSIOBufferReaderConsume(flv_reader, flv_tag_size); body_length = flv_tag_get_body_length(tag); buf = (byte *)TSmalloc(sizeof(byte) * body_length); - memset(buf, 0, sizeof(buf)); + memset(buf, 0, body_length); IOBufferReaderCopy(flv_reader, buf, body_length); TSIOBufferReaderConsume(flv_reader, body_length); flv_read_metadata(buf, &name, &data,body_length); IOBufferReaderCopy(flv_reader, &prev_tag_size, sizeof(uint32_be)); TSIOBufferReaderConsume(flv_reader, sizeof(uint32_be)); prev_tag_size = swap_uint32(prev_tag_size); - TSDebug(PLUGIN_NAME,"unexpected end of file in previous tag size%d\n",prev_tag_size); /* onMetaData checking */ if (!strcmp((char*) amf_string_get_bytes(name),"onMetaData")) { on_medata_size = amf_data_size(data); - TSDebug(PLUGIN_NAME,"onMetaName= %lu\n",amf_data_size(name)); - TSDebug(PLUGIN_NAME,"onMetaData = %lu\n",on_medata_size); on_metadata = amf_data_clone(data); on_metadata_name = amf_data_clone(name); /* check onMetadata type */ @@ -463,10 +432,7 @@ int FlvTag::update_flv_meta_data() { amf_data_free(data); TSfree(buf); - TSDebug(PLUGIN_NAME,"copy onMetaName= %lu\n",amf_data_size(on_metadata_name)); - TSDebug(PLUGIN_NAME,"copy onMetaData = %lu\n",amf_data_size(on_metadata)); - - //解析 metadata + //parse metadata amf_node * n; /* more metadata checks */ for (n = amf_associative_array_first(on_metadata); n != NULL; n = @@ -481,7 +447,6 @@ int FlvTag::update_flv_meta_data() { type = amf_data_get_type(data); /* TODO: check UTF-8 strings, in key, and value if string type */ - //找出需要更改的value /* duration (number) */ if (!strcmp((char*) name, "duration")) { if (type == AMF_TYPE_NUMBER) { @@ -490,8 +455,7 @@ int FlvTag::update_flv_meta_data() { if(duration_time > file_duration) goto end; data_value = int2double(file_duration) - duration_time; - TSDebug(PLUGIN_NAME,"duration should got %lf %lf\n", data_value, int2double(file_duration)); - amf_number_set_value(data,double2int(data_value)); //修改总时间 + amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for duration: expected %s, got %s\n", get_amf_type_string(AMF_TYPE_NUMBER), @@ -507,8 +471,7 @@ int FlvTag::update_flv_meta_data() { if(duration_time > file_lasttimestamp) goto end; data_value = int2double(file_lasttimestamp) - duration_time; - TSDebug(PLUGIN_NAME,"lasttimestamp should be %lf %lf\n", data_value,int2double(file_lasttimestamp)); - amf_number_set_value(data,double2int(data_value)); //修改总时间 + amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for lasttimestamp: expected %s, got %s\n", get_amf_type_string(AMF_TYPE_NUMBER), @@ -524,7 +487,6 @@ int FlvTag::update_flv_meta_data() { if(duration_time > file_lastkeyframetimestamp) goto end; data_value = int2double(file_lastkeyframetimestamp) - duration_time;; - TSDebug(PLUGIN_NAME,"lastkeyframetimestamp should be %lf %lf\n", data_value,int2double(file_lastkeyframetimestamp)); amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for lastkeyframetimestamp: expected %s, got %s\n", @@ -539,8 +501,7 @@ int FlvTag::update_flv_meta_data() { number64 file_filesize; file_filesize = amf_number_get_value(data); - data_value = int2double(file_filesize) - duration_file_size; //此处有bug ,因为在删除onmetadata关键帧的时候, 大小会再次变化,还需要再次修改 - TSDebug(PLUGIN_NAME,"filesize should be got %lf %lf\n", data_value,int2double(file_filesize)); + data_value = int2double(file_filesize) - duration_file_size; amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for filesize: expected %s, got %s\n", @@ -555,7 +516,6 @@ int FlvTag::update_flv_meta_data() { number64 file_videosize; file_videosize = amf_number_get_value(data); data_value = int2double(file_videosize) - duration_video_size; - TSDebug(PLUGIN_NAME,"videosize should be got %lf %lf\n", data_value,int2double(file_videosize)); amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for videosize: expected %s, got %s\n", @@ -570,7 +530,6 @@ int FlvTag::update_flv_meta_data() { number64 file_audiosize; file_audiosize = amf_number_get_value(data); data_value = int2double(file_audiosize) - duration_audio_size; - TSDebug(PLUGIN_NAME,"audiosize should be got %lf %lf\n", data_value,int2double(file_audiosize)); amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for audiosize: expected %s, got %s\n", @@ -585,7 +544,6 @@ int FlvTag::update_flv_meta_data() { number64 file_datasize; file_datasize = amf_number_get_value(data); data_value = int2double(file_datasize) - duration_video_size - duration_audio_size; - TSDebug(PLUGIN_NAME,"datasize should be got %lf %lf\n", data_value,int2double(file_datasize)); amf_number_set_value(data,double2int(data_value)); } else { TSDebug(PLUGIN_NAME,"invalid type for datasize: expected %s, got %s\n", @@ -628,8 +586,7 @@ int FlvTag::update_flv_meta_data() { get_amf_type_string(fp_type)); } - if (times_type == AMF_TYPE_ARRAY - && fp_type == AMF_TYPE_ARRAY) { + if (times_type == AMF_TYPE_ARRAY && fp_type == AMF_TYPE_ARRAY) { number64 last_file_time; int have_last_time; amf_node * ff_node, *ft_node; @@ -640,8 +597,6 @@ int FlvTag::update_flv_meta_data() { ft_node = amf_array_first(file_times); ff_node = amf_array_first(file_filepositions); - TSDebug(PLUGIN_NAME,"file_times size = %u\n",amf_array_size(file_times)); - TSDebug(PLUGIN_NAME,"file_times byte = %lu\n",amf_data_size(file_times)); amf_node * first_t_node, *first_p_node; first_t_node = ft_node; @@ -655,26 +610,16 @@ int FlvTag::update_flv_meta_data() { df_time = 0; df_position = 0; /* time */ - if (amf_data_get_type( - amf_array_get( - ft_node)) != AMF_TYPE_NUMBER) { + if (amf_data_get_type(amf_array_get(ft_node)) != AMF_TYPE_NUMBER) { TSDebug(PLUGIN_NAME,"!= AMF_TYPE_NUMBER -- invalid type for time: expected %s, got %s\n", get_amf_type_string(AMF_TYPE_NUMBER), get_amf_type_string(type)); } else { - f_time = amf_number_get_value( - amf_array_get(ft_node)); - TSDebug(PLUGIN_NAME,"f_time = %lu\n",f_time); + f_time = amf_number_get_value(amf_array_get(ft_node)); df_time = int2double(f_time); - TSDebug(PLUGIN_NAME,"invalid keyframe time: expected got %lf\n", - df_time); - /* check for duplicate time, can happen in H.264 files */ - if (have_last_time - && last_file_time == f_time) { - double xie = int2double(f_time); - TSDebug(PLUGIN_NAME,"Duplicate keyframe time: %lf\n", - xie); + if (have_last_time && last_file_time == f_time) { + TSDebug(PLUGIN_NAME,"Duplicate keyframe time: %lf\n",int2double(f_time)); } have_last_time = 1; last_file_time = f_time; @@ -688,10 +633,7 @@ int FlvTag::update_flv_meta_data() { get_amf_type_string(type)); } else { f_position = amf_number_get_value(amf_array_get(ff_node)); - double df_position = int2double(f_position); - TSDebug(PLUGIN_NAME, - "invalid keyframe file position: expected got %lf\n", - df_position); + TSDebug(PLUGIN_NAME,"invalid keyframe file position: expected got %lf\n",int2double(f_position)); } if(df_time!= 0 && df_time <= duration_time) { first_t_node->next = amf_array_next(ft_node); @@ -779,7 +721,6 @@ int FlvTag::update_flv_meta_data() { } int FlvTag::process_check_des_body() { - TSDebug(PLUGIN_NAME, "process_check_des_body duration_file_size = %lu\n",duration_file_size); int64_t avail, b_avail; uint32_t i = 0; @@ -790,22 +731,19 @@ int FlvTag::process_check_des_body() { b_avail = TSIOBufferReaderAvail(flv_reader); avail = TSIOBufferReaderAvail(tag_reader); - if ((avail + b_avail) < ((int64_t)need_des_length < (int64_t)need_read_length ? (int64_t)need_read_length: (int64_t)need_des_length)) return 0; if (avail) { - TSIOBufferCopy(flv_buffer, tag_reader, avail, 0); //全部合并到flv_buffer + TSIOBufferCopy(flv_buffer, tag_reader, avail, 0); TSIOBufferReaderConsume(tag_reader, avail); tag_pos += avail; - TSDebug(PLUGIN_NAME, "process_check_des_body tag_pos = %ld\n",tag_pos); } - //更新 onmetadata update_flv_meta_data(); b_avail = TSIOBufferReaderAvail(flv_reader); - if(b_avail > 0) {//因为onmetadata 更新后放在new_flv_buffer 中,所以将flv_buffer 中的剩余的数据放到new_flv_buffer中去 + if(b_avail > 0) { TSIOBufferCopy(new_flv_buffer, flv_reader, b_avail, 0); TSIOBufferReaderConsume(flv_reader, b_avail); } @@ -815,10 +753,9 @@ int FlvTag::process_check_des_body() { buf = (u_char *)TSmalloc(sizeof(u_char) * flv_des_length); for(i = 0; i < flv_des_section_count; i++) { - memset(buf, 0, sizeof(buf)); + memset(buf, 0, flv_des_length); IOBufferReaderCopy(new_flv_reader, buf, flv_need_des_length); TSIOBufferReaderConsume(new_flv_reader, flv_need_des_length); - //进行des 加密 des_encrypt(tdes_key, buf, flv_need_des_length); TSIOBufferWrite(head_buffer, buf, flv_des_length); } @@ -993,5 +930,3 @@ int FlvTag::flv_read_drm_header(TSIOBufferReader readerp, drm_header * header) { return 0; } - -#endif /* __FLV_ENCRYPTION_CC__ */ diff --git a/flv_tag.h b/flv_tag.h index 140ea12..0eb8f2e 100644 --- a/flv_tag.h +++ b/flv_tag.h @@ -78,15 +78,17 @@ typedef int (FlvTag::*FTHandler) (); class FlvTag { public: - FlvTag() : tag_buffer(NULL), tag_reader(NULL),des_buffer(NULL), des_reader(NULL),head_buffer(NULL), head_reader(NULL), + FlvTag() : tag_buffer(NULL), tag_reader(NULL), dup_reader(NULL), des_buffer(NULL), des_reader(NULL),head_buffer(NULL), head_reader(NULL), flv_buffer(NULL),flv_reader(NULL),new_flv_buffer(NULL),new_flv_reader(NULL), tag_pos(0), cl(0),content_length(0), drm_head_length(0),version(0),videoid_size(0),videoid(NULL), userid_size(0), userid(NULL),reserved_size(0), reserved(NULL), flv_need_des_length(0),flv_des_length(0),flv_des_section_count(0),on_meta_data_size(0), - duration_file_size(0) ,duration_time(0),duration_video_size(0),duration_audio_size(0),video_body_size(0),start(0), video_type(0), tdes_key(NULL) + duration_file_size(0) ,duration_time(0),duration_video_size(0),duration_audio_size(0),video_body_size(0),start(0), video_type(0), tdes_key(NULL), + is_init_current_handler(false) { tag_buffer = TSIOBufferCreate(); tag_reader = TSIOBufferReaderAlloc(tag_buffer); + dup_reader = TSIOBufferReaderAlloc(tag_buffer); des_buffer = TSIOBufferCreate(); des_reader = TSIOBufferReaderAlloc(des_buffer); @@ -110,6 +112,11 @@ class FlvTag tag_reader = NULL; } + if (dup_reader) { + TSIOBufferReaderFree(dup_reader); + dup_reader = NULL; + } + if (tag_buffer) { TSIOBufferDestroy(tag_buffer); tag_buffer = NULL; @@ -172,8 +179,6 @@ class FlvTag tdes_key = NULL; } - void set_flv_function(); - int process_tag(TSIOBufferReader reader, bool complete); int64_t write_out(TSIOBuffer buffer); size_t get_drm_header_size(); @@ -189,13 +194,13 @@ class FlvTag int process_drm_header_videoid(); int process_drm_header_userid(); int process_drm_header_reserved(); - int process_decrypt_flv_body();//解密 + int process_decrypt_flv_body(); int process_initial_flv_header(); int process_initial_body(); int process_medial_body(); int process_check_des_body(); - int update_flv_meta_data(); //更新FLV on_meta_data信息 + int update_flv_meta_data(); int flv_read_metadata(byte *stream,amf_data ** name, amf_data ** data, size_t maxbytes); @@ -203,6 +208,7 @@ class FlvTag public: TSIOBuffer tag_buffer; TSIOBufferReader tag_reader; + TSIOBufferReader dup_reader; TSIOBuffer des_buffer; TSIOBufferReader des_reader; @@ -218,22 +224,22 @@ class FlvTag FTHandler current_handler; - int64_t tag_pos; //已经消费了多少字节 - int64_t cl; //文件总长度 + int64_t tag_pos; //How many bytes have been consumed + int64_t cl; int64_t content_length; //从start 处开始的文件总长度 int64_t drm_head_length; //drm head 的长度 //----DRM header start //char signature[3]; 标志位 - uint32_t version; //4 + uint32_t version; - uint32_t videoid_size; //4 tail_length - u_char *videoid; //视频 id 标签 + uint32_t videoid_size; + u_char *videoid; - uint32_t userid_size; //4 - u_char *userid; //用户 id 标签 + uint32_t userid_size; + u_char *userid; - uint32_t reserved_size; //4 + uint32_t reserved_size; u_char *reserved; //----DRM header end @@ -252,6 +258,7 @@ class FlvTag int64_t start; //请求flv 播放的起始字节数 int16_t video_type; u_char *tdes_key; //des key + bool is_init_current_handler;//如果是flv 格式的话,需要初始化一次 }; #endif /* __FLV_TAG_H__ */