diff options
| author | Xiaoqing MA <[email protected]> | 2018-07-20 17:26:34 +0800 |
|---|---|---|
| committer | Xiaoqing MA <[email protected]> | 2018-07-20 17:26:34 +0800 |
| commit | 621174db070d060b0996eef3593c5944322c82b3 (patch) | |
| tree | 1ae64aec20626cb0037502fb10fb1e41752b127e | |
| parent | aade0897112e0a25c0b3a8e96af3490ba256b6ed (diff) | |
1.按照mp4修改思路修改ts与flv-待继续修改
| -rw-r--r-- | inc/av_format_identify.h | 1 | ||||
| -rw-r--r-- | src/av_format_identify.c | 308 |
2 files changed, 154 insertions, 155 deletions
diff --git a/inc/av_format_identify.h b/inc/av_format_identify.h index 63dbb87..108930d 100644 --- a/inc/av_format_identify.h +++ b/inc/av_format_identify.h @@ -8,7 +8,6 @@ #define AV_CONTAINER_MP4 3 - /*To identify the container type of the whole byte stream*/ int AV_container_identify(const char* buff, size_t size); diff --git a/src/av_format_identify.c b/src/av_format_identify.c index f0764dc..09d93a4 100644 --- a/src/av_format_identify.c +++ b/src/av_format_identify.c @@ -11,121 +11,125 @@ #include <arpa/inet.h> -#define FIT_TIMES 1 +#define FIT_TIMES 2 #define TS_SYNC_BYTE 0x47 #define TS_PKT_SIZE 188 #define FLV_TAG_AUDIO 0x08 #define FLV_TAG_VIDEO 0x09 #define FLV_TAG_SCRIPT_DATA 0x12 - - -const char *g_mp4_box_type_all[] = { "ftyp", "pdin", "moov", "mvhd", "trak", "tkhd", "tref", "edts", "elst", "mdia", "mdhd", -"hdlr", "minf", "vmhd", "smhd", "hmhd", "nmhd", "dinf", "dref", "stbl", "stsd", "stts", "ctts", "stsc", "stsz", -"stz2", "stco", "co64", "stss", "stsh", "padb", "stdp", "sdtp", "sbgp", "sgpd", "subs", "mvex", "mehd", "trex", -"ipmc", "moof", "mfhd", "traf", "tfhd", "trun", "sdtp", "sbgp", "subs", "mfra", "tfra", "mfro", "mdat", "free", -"skip", "udta", "cprt", "meta", "hdlr", "dinf", "dref", "ipmc", "iloc", "ipro", "sinf", "frma", "imif", "schm", -"schi", "iinf", "xml", "bxml", "pitm", "fiin", "paen", "fpar", "fecr", "segr", "gitn", "tsel", "meco", "mere", "uuid" }; +const char *g_mp4_box_type_all[] = { "ftyp","pdin","moov","mvhd","meta", +"trak","tkhd","tref","trgr","edts","elst","mdia","mdhd","hdlr","elng", +"minf","vmhd","smhd","hmhd","sthd","nmhd","dinf","dref","stbl","stsd", +"stts","ctts","cslg","stsc","stsz","stz2","stco","co64","stss","stsh", +"padb","stdp","sdtp","sbgp","sgpd","subs","saiz","saio","udta","mvex", +"mehd","trex","leva","moof","mfhd","traf","tfhd","trun","tfdt","mfra", +"tfra","mfro","mdat","free","skip","cprt","tsel","strk","stri","strd", +"iloc","ipro","sinf","frma","schm","schi","iinf","xml","bxml","pitm", +"fiin","paen","fire","fpar","fecr","segr","gitn","idat","iref","meco", +"mere","styp","sidx","ssix","prft", "uuid" }; const int g_mp4_box_type_count = sizeof(g_mp4_box_type_all) / sizeof(char *); /*To find that whether the initial size bytes pointed to by buff satisfies the rules of MPEG-TS AV Container * by supposing that its first 1 byte is sync_byte in ts header.*/ -int is_mpeg_ts_each(const char *buff, size_t size); + /*To identify whether the whole byte stream belongs to MPEG_TS container*/ -int is_mpeg_ts(const char* buff, size_t size); + /*To find that whether the initial size bytes pointed to by buff satisfies the rules of FLV AV Container * by supposing that its first 1 byte is TagType in FLV Tag Header.*/ -int is_flv_each(const char* buff, size_t size); + /*To identify whether the whole byte stream belongs to FLV container*/ -int is_flv(const char* buff, size_t size); /*To find that whether the initial size bytes pointed to by buff satisfies the rules of MP4 AV Container * by supposing that its first 4 byte is Boxtype in Box of MP4 file.*/ -int is_mp4_each(const char* buff, size_t size); -/*To identify whether the whole byte stream belongs to MP4 container*/ -int is_mp4(const char* buff, size_t size); + /*To identify whether the whole byte stream belongs to MP4 container*/ + +struct ts_pkg_t +{ + uint8_t sync_byte; + uint16_t con_pid; + uint8_t con_cnt; + char *pyld_data; +}; +#define MIN_TS_PKT_LEN (sizeof(struct ts_pack_t)-8) int is_mpeg_ts_each(const char *buff, size_t size) { - int ret_ts_each = 0; - const char *p = buff; + int ret = 0; int fit_times = 0; + const char *p = buff; + const struct ts_pkg_t *pkg = NULL; - size_t cont_cout_pre=0, cont_cout_aft=0; - cont_cout_pre = htonl(*(size_t *)buff) & 0x0000000f; + //uint16_t cont_cnt_pre=0, cont_cnt_cur=0; + //cont_cnt_pre = (*(uint16_t *)(pkg->con_cnt)) & 0x0f; + uint8_t cont_cnt_pre = 0, cont_cnt_cur = 0; + //cont_cnt_pre = pkg->con_cnt; - uint32_t pid_pre=0, pid_aft=0; - pid_pre = ((htonl(*(uint32_t *)buff) & 0x000fff00) >> 8) + ((((htonl(*(uint32_t *)buff) & 0x00f00000) >> 20) % 2) << 12); + uint16_t pid_pre=0, pid_cur=0; + //pid_pre = (htons(*(uint16_t *)(pkg->con_pid))) << 3 >> 3; - const char *pack_tail=NULL; - const char *pack_half=NULL; - const char *pack_quarter=NULL; + + int group[3] = { 1,2,4 }; - size_t whole_pack_cnt=0; - size_t half_pack_cnt=0; - size_t quarter_pack_cnt=0; - - p += TS_PKT_SIZE; - while (p < (buff + size)) + //p += TS_PKT_SIZE; + /*when p == buff(first of while), record pid and continuous_count of package head and go to fit_times++ directly. + special for mpeg-ts cause of the format requirement for two packages together.*/ + if (p - buff + MIN_TS_PKT_LEN <= size) { - if (*p != TS_SYNC_BYTE) + pkg = (const struct ts_pkg_t *)p; + pid_pre = (htons(*(uint16_t *)(pkg->con_pid))) << 3 >> 3; + cont_cnt_pre = pkt->con_cnt; + p += TS_PKT_SIZE; + fit_times++; + } + while (p - buff + MIN_TS_PKT_LEN <= size)//while (p < (buff + size)) + { + pkg = (const struct ts_pkg_t *)p; + if (pkg->sync_byte != TS_SYNC_BYTE) { break; } - - if ((p + 3) < (buff + size)) + + pid_cur = (htons(*(uint16_t *)(pkg->con_pid))) << 3 >> 3; + //pid_cur = ((htonl(*(uint32_t *)(p+TS_PKT_SIZE)) & 0x000fff00) >> 8) + ((((htonl(*(uint32_t *)(p + TS_PKT_SIZE)) & 0x00f00000) >> 20) % 2) << 12); + if (pid_cur == pid_pre && pid_cur != 8191)// { - pid_aft = ((htonl(*(uint32_t *)p) & 0x000fff00) >> 8) + ((((htonl(*(uint32_t *)p) & 0x00f00000) >> 20) % 2) << 12); - if (pid_aft == pid_pre && pid_aft!=8191) - { - cont_cout_aft = htonl(*(size_t *)p) & 0x0000000f; - if (cont_cout_aft == (cont_cout_pre + 1) % 16) - { - fit_times++; - } - else - { - break; - } - } - else - { - fit_times++; - } + cont_cnt_cur = pkt->con_cnt;// p + TS_PKT_SIZE;//cont_cnt_cur = (*(uint16_t *)(p + TS_PKT_SIZE)) & 0x0f; + if (cont_cnt_cur != (cont_cnt_pre + 1) % 16) + { + break; + } } + fit_times++; + if (fit_times >= FIT_TIMES) { - whole_pack_cnt = size / TS_PKT_SIZE; - if (size % TS_PKT_SIZE == 0) + size_t whole_pkg_cnt = (size - 1) / TS_PKT_SIZE; + if (whole_pkg_cnt < 4) { - whole_pack_cnt--; + break; } - half_pack_cnt = whole_pack_cnt/2; - quarter_pack_cnt = whole_pack_cnt/4; - if (whole_pack_cnt < 3 || half_pack_cnt < 2 || quarter_pack_cnt < 1) - { - break; - } - pack_tail = buff + whole_pack_cnt * TS_PKT_SIZE; - pack_half = buff + half_pack_cnt * TS_PKT_SIZE; - pack_quarter = buff + quarter_pack_cnt * TS_PKT_SIZE; - //if (*pack_tail == TS_SYNC_BYTE && *(pack_tail - TS_PKT_SIZE) == TS_SYNC_BYTE) - if (*pack_tail == TS_SYNC_BYTE && *pack_half == TS_SYNC_BYTE && *pack_quarter == TS_SYNC_BYTE) + int i; + for (i = 0; i < 3; i++) { - ret_ts_each = 1; - break; + char *pkg_seg = buff + whole_pkg_cnt / group[i] * TS_PKT_SIZE; + if (*pkg_seg != TS_SYNC_BYTE) + { + break; + } } + ret = 1; break; } - cont_cout_pre = cont_cout_aft; - pid_pre = pid_aft; + cont_cnt_pre = cont_cnt_cur; + pid_pre = pid_cur; p += TS_PKT_SIZE; } - return ret_ts_each; + return ret; } int is_mpeg_ts(const char* buff, size_t size) @@ -166,70 +170,71 @@ void *memchr_flv(const char *buff, size_t size) return ret_memflv; } +struct flv_tag_t +{ + uint8_t tag_type; + uint8_t pyld_len[3];//payload length +}; +#define MIN_FLV_TAG_LEN (sizeof(struct flv_tag_t)) + int is_flv_each(const char* buff, size_t size) { - int ret_flv_each = 0; - const char *p = buff; + int ret = 0; int fit_times = 0; - uint32_t left=0; - uint32_t right = 11 + (htonl(*(size_t *)p) & 0x00ffffff); - p += (right + 4); - - while (p < (buff + size)) + const char *p = buff; + const struct flv_tag_t *tag = NULL; + + //uint32_t tag_len_show = 0; + //uint32_t tag_len_cnt = 0;// = 11 + (htonl(*(size_t *)p) & 0x00ffffff); + //p += (tag_len_cnt + 4); + while (p - buff + MIN_FLV_TAG_SIZE <= size)//while (p < (buff + size)) { - left = htonl(*(uint32_t *)(p - 4)); - if (right == left && (*(p) == FLV_TAG_AUDIO || *(p) == FLV_TAG_VIDEO || *(p) == FLV_TAG_SCRIPT_DATA)) + tag = (const struct flv_tag_t *)p; + if (*(tag->tag_type) != FLV_TAG_AUDIO && *(tag->tag_type) != FLV_TAG_VIDEO && *(tag->tag_type) != FLV_TAG_SCRIPT_DATA) { - fit_times++; - if (fit_times >= FIT_TIMES) - { - ret_flv_each = 1; - break; - } + break; } - else + uint32_t tag_len_cnt = 11 + *(uint32_t *)(tag->pyld_len);//(htonl(*(uint32_t *)tag)) & 0x00ffffff; + if (p - buff + tag_len_cnt + 4 > size) + { + break; + } + uint32_t tag_len_show = *(uint32_t *)(p + tag_len_cnt); + if (tag_len_cnt != tag_len_show) { break; } - if ((p + 3) >= (buff + size)) + fit_times++; + if (fit_times >= FIT_TIMES) { + ret = 1; break; } - right = 11 + (htonl(*(size_t *)p) & 0x00ffffff); - p += (right + 4); + p += (tag_len_cnt + 4); } - return ret_flv_each; + return ret; } int is_flv(const char* buff, size_t size) { - int ret_flv = 0; - int ret_flv_each; - const char *p_each = buff; + int ret = 0; + const char *p = buff; - while (p_each < size + buff) + while (p - buff < size)//same as p - buff + 1 <= size//while (p < size + buff) { - p_each = memchr_flv(p_each, size - (p_each - buff)); - if (p_each == NULL) + p = memchr_flv(p, size - (p - buff)); + if (p == NULL) { break; } - else if (p_each + 3 >= buff + size) + if (is_flv_each(p, size - (p - buff)) == 1) { + ret = 1; break; } - else - { - ret_flv_each = is_flv_each(p_each, size - (p_each - buff)); - if (ret_flv_each == 1) - { - ret_flv = 1; - break; - } - p_each++; - } + p++; } - return ret_flv; + return ret; } @@ -249,13 +254,15 @@ int is_mp4_boxname_deep(const char *buff) -int is_mp4_boxname(const char *buff, size_t size) +int is_mp4_boxname(const char *buff);// , size_t size) { int i=0,raw_filter=0; + /* if (size<4) { return 0; } + */ for (i = 0; i < 4; i++) { if (*(buff + i) < '0' || (*(buff + i) > '9'&&*(buff + i) < 'a') || *(buff + i) > 'z') @@ -268,17 +275,18 @@ int is_mp4_boxname(const char *buff, size_t size) break; } } - if(raw_filter!=4) - { - return 0; - } - else + if (raw_filter == 4 || raw_filter == 3)//box type:xmf { - if(1==is_mp4_boxname_deep(buff)) + if (1 == is_mp4_boxname_deep(buff)) { return 1; } } + else + { + if (memcpy()) + return 0; + } return 0; } @@ -310,27 +318,21 @@ struct mp4_box_t #define MIN_MP4_BOX_SIZE (sizeof(struct mp4_box_t)-8) int is_mp4_each(const char* buff, size_t size) { - int ret_mp4_each = 0; - int ret_mp4_boxname; - int sig_mp4_boxtype = 0; - if (is_mp4_boxname_deep(buff) == 1) - { - sig_mp4_boxtype = 1; - } - const char *p = buff; + int ret = 0; int fit_times = 0; - + const char *p = buff; const struct mp4_box_t *box=NULL; - while(p-buff+MIN_MP4_BOX_SIZE<size) + + while (p - buff + MIN_MP4_BOX_SIZE <= size)//while(p-buff+MIN_MP4_BOX_SIZE<size)//at least contain atom_size and name of mp4 box for current p { - box=(const struct mp4_box_t *)p; - if(!is_mp4_boxname(box->name,sizeof(box->name)) + box=(const struct mp4_box_t *)p;//? + if(!is_mp4_boxname(box->name)//?,sizeof(box->name)) { break; } fit_times++; - if(box->atom_size==1) + if(htonl(box->atom_size==1))//?if(box->atom_size == 1) { if(size-(p-buff)>sizeof(struct mp4_box_t)) { @@ -345,15 +347,19 @@ int is_mp4_each(const char* buff, size_t size) { p+=htonl(box->atom_size); } + if (fit_times > FIT_TIMES) + { + ret = 1; + break; + }// } - if (fit_times > FIT_TIMES) - { - return 1; - } - else + + /*else { - return 0; - } + ret = 0; + }// + */ + return ret; } @@ -361,34 +367,28 @@ int is_mp4(const char* buff, size_t size) { int ret_mp4 = 0; int ret_mp4_each; - const char *p_each = buff; + const char *p = buff; - while (p_each < buff + size) + while (p < buff + size) { - p_each = (const char *)memmem_mp4(p_each, size - (p_each - buff)); - if (p_each == NULL) + p = (const char *)memmem_mp4(p, size - (p - buff)); + if (p == NULL) { break; } - else if (p_each + 12 >= buff + size) + if (p - 4 < buff) { - break; - } - else if (p_each - 4 < buff) - { - p_each++; + p++; continue; } - else + + ret_mp4_each = is_mp4_each(p - 4, size - (p - buff) + 4); + if (ret_mp4_each == 1) { - ret_mp4_each = is_mp4_each(p_each, size - (p_each - buff)); - if (ret_mp4_each == 1) - { - ret_mp4 = 1; - break; - } - p_each++; + ret_mp4 = 1; + break; } + p++; } return ret_mp4; } @@ -407,7 +407,7 @@ int AV_container_identify(const char* buff, size_t size) { return AV_CONTAINER_MP4; } - return UNKNOWN; + return AV_CONTAINER_UNKNOWN; } |
