source: tools/xupnpd/mpls.cpp @ 41905

Last change on this file since 41905 was 34374, checked in by Stephan, 9 years ago

add xupnpd

File size: 3.2 KB
Line 
1#include "mpls.h"
2
3namespace mpls
4{
5    inline u_int32_t get_ui32(unsigned char* p)
6    {
7        u_int32_t rc=((u_int32_t)p[0])<<24;
8        rc+=((u_int32_t)p[1])<<16;
9        rc+=((u_int32_t)p[2])<<8;
10        rc+=p[3];
11
12        return rc;
13    }
14
15    inline u_int16_t get_ui16(unsigned char* p)
16    {
17        u_int32_t rc=((u_int32_t)p[0])<<8;
18        rc+=p[1];
19
20        return rc;
21    }
22}
23
24
25
26int mpls::parse(const char* filename,std::list<int>& playlist,std::map<int,std::string>& datetime,int verb)
27{
28    FILE* fp=fopen(filename,"rb");
29
30    if(!fp)
31        return -1;
32
33    struct stat st;
34
35    if(fstat(fileno(fp),&st)==-1)
36    {
37        fclose(fp);
38        return -1;
39    }
40
41    unsigned int len=st.st_size;
42
43    std::auto_ptr<unsigned char> p(new unsigned char[len]);
44
45    unsigned char* ptr=p.get();
46
47    if(!ptr)
48    {
49        fclose(fp);
50        return -1;
51    }
52
53    if(fread(ptr,1,len,fp)!=len)
54    {
55        fclose(fp);
56        return -1;
57    }
58
59    fclose(fp);
60
61    if(memcmp(ptr,"MPLS0",5))
62        return -1;
63
64    std::vector<int> chapters;
65    chapters.reserve(512);
66
67    u_int32_t playlist_offset=get_ui32(ptr+8);
68    u_int32_t playlist_mark_offset=get_ui32(ptr+12);
69    u_int32_t playlist_ext_offset=get_ui32(ptr+16);
70
71    if(playlist_offset>len || playlist_mark_offset>len || playlist_ext_offset>len)
72        return -1;
73
74    if(verb)
75        fprintf(stderr,"=== clips from playlist %s ===\n",filename);
76
77    if(playlist_offset)
78    {
79        unsigned char* p=ptr+playlist_offset;
80
81        u_int32_t l=get_ui32(p);
82        p+=4;
83
84        unsigned char* p2=p+l;
85
86        p+=2;                                   // reserved
87
88        u_int16_t n=get_ui16(p);
89        p+=4;
90
91        for(u_int16_t i=0;i<n;i++)
92        {
93            if(p>p2)
94                return -1;
95
96            u_int16_t item_len=get_ui16(p);
97            p+=2;
98
99            int clip=0;
100
101            for(int j=0;j<5;j++)
102            clip=clip*10+(p[j]-48);
103
104            chapters.push_back(clip);
105            playlist.push_back(clip);
106
107            p+=item_len;
108        }
109    }
110
111    if(playlist_mark_offset)
112    {
113        // skip section
114    }
115
116    if(playlist_ext_offset)
117    {
118        unsigned char* p=ptr+playlist_ext_offset;
119
120        u_int32_t l=get_ui32(p);
121        p+=4;
122
123        unsigned char* p2=p+l;
124
125        if(p+4<=p2 && !memcmp(p+20,"PLEX",4))
126        {
127            p+=348;
128
129            if(p+2<=p2)
130            {
131                u_int16_t n=get_ui16(p);
132                p+=2;
133
134                for(u_int16_t i=0;i<n;i++)
135                {
136                    if(p+66>p2)
137                        break;
138
139                    // CA or DA
140                    if((p[44] == 'C' || p[44] == 'D') && p[45] == 'A')
141                    {
142                        char tmp[64];
143
144                        sprintf(tmp,"20%.2x-%.2x-%.2x %.2x:%.2x:%.2x",p[12],p[13],p[14],p[15],p[16],p[17]);
145
146                        datetime[chapters[i]]=tmp;
147
148                        if(verb)
149                            fprintf(stderr,"* %.5i: %s\n",chapters[i],tmp);
150                    }
151
152                    p+=66;
153                }
154            }
155        }
156
157    }else
158    {
159        if(verb)
160            for(int i=0;i<chapters.size();i++)
161                fprintf(stderr,"* %.5i\n",chapters[i]);
162    }
163
164    return 0;
165}
Note: See TracBrowser for help on using the repository browser.