summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaoqing MA <[email protected]>2018-07-20 17:26:34 +0800
committerXiaoqing MA <[email protected]>2018-07-20 17:26:34 +0800
commit621174db070d060b0996eef3593c5944322c82b3 (patch)
tree1ae64aec20626cb0037502fb10fb1e41752b127e
parentaade0897112e0a25c0b3a8e96af3490ba256b6ed (diff)
1.按照mp4修改思路修改ts与flv-待继续修改
-rw-r--r--inc/av_format_identify.h1
-rw-r--r--src/av_format_identify.c308
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;
}