2baaf4d44696b0a33863f24e7e4fdd8b0f6ef366
[vuplus_transtreamproxy] / src / main.cpp
1 /*
2  * main.cpp
3  *
4  *  Created on: 2013. 9. 12.
5  *      Author: kos
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <poll.h>
12 #include <stdlib.h>
13 #include <sys/ioctl.h>
14
15 #include <vector>
16 #include <string>
17 #include <iterator>
18 #include <fstream>
19
20 #include "ePreDefine.h"
21 #include "eURIDecoder.h"
22 #include "eFilePumpThread.h"
23 #include "eNetworkPumpThread.h"
24
25 #ifdef DEBUG_LOG
26 FILE* fpLog = fopen("/tmp/filestreamproxy.log", "w");
27 //#undef LOG
28 //#define LOG(X,...) { do{}while(0); }
29 #endif
30
31 using namespace std;
32 //-------------------------------------------------------------------------------
33
34 int gDeviceFd = 0;
35
36 char* ReadRequest(char* aRequest)
37 {
38         return fgets(aRequest, MAX_LINE_LENGTH-1, stdin);
39 }
40 //-------------------------------------------------------------------------------
41
42 namespace eParser {
43         int gVideoPid = 0, gAudioPid = 0;
44         std::vector<string> Split(std::string aBuffer, char aDelimiter);
45         void FileName(char* aRequest, char* aHttp, std::string& aOutData);
46         bool MetaData(std::string aMediaFileName);
47 };
48 using namespace eParser;
49 //-------------------------------------------------------------------------------
50
51 /* GET /file?file=/home/kos/work/workspace/filestreamproxy/data/20131023%200630%20-%20FASHION%20TV%20-%20instant%20record.ts HTTP/1.0 */
52 int main(int argc, char** argv)
53 {
54         char request[MAX_LINE_LENGTH] = {0};
55
56         if (!ReadRequest(request)) {
57                 RETURN_ERR_400();
58         }
59 #ifdef DEBUG_LOG
60         LOG("%s", request);
61 #endif
62
63         if (strncmp(request, "GET /", 5)) {
64                 RETURN_ERR_400();
65         }
66
67         char* http = strchr(request + 5, ' ');
68         if (!http || strncmp(http, " HTTP/1.", 7)) {
69                 RETURN_ERR_400("Not support request (%s).", http);
70         }
71
72         std::string srcfilename = "";
73         eParser::FileName(request, http, srcfilename);
74
75         bool isSuccessMeta = eParser::MetaData(srcfilename);
76
77 #ifdef DEBUG_LOG
78         LOG("meta parsing result : %d, video : %d, audio : %d", isSuccessMeta, eParser::gVideoPid, eParser::gAudioPid);
79 #endif
80
81         gDeviceFd = open("/dev/bcm_enc0", O_RDWR);
82         if(gDeviceFd < 0 ) {
83                 close(gDeviceFd);
84                 RETURN_ERR_502("Fail to opne device.");
85         }
86
87         if(isSuccessMeta) {
88                 if(ioctl(gDeviceFd, 1, eParser::gVideoPid)) {
89                         RETURN_ERR_502("Fail to set video pid");
90                 }
91                 if(ioctl(gDeviceFd, 2, eParser::gAudioPid)) {
92                         RETURN_ERR_502("Fail to set audio pid");
93                 }
94         }
95
96         eFilePumpThread filepump(gDeviceFd, srcfilename);
97         filepump.Start();
98
99         sleep(1);
100
101         if(ioctl(gDeviceFd, 100, 0)) {
102                 RETURN_ERR_502("Fail to start transcoding.");
103         }
104         eNetworkPumpThread networkpump(gDeviceFd);
105         networkpump.Start();
106
107         networkpump.Join();
108         filepump.Stop();
109         filepump.Join();
110
111         close(gDeviceFd);
112
113 #ifdef DEBUG_LOG
114         fclose(fpLog);
115 #endif
116         return 0;
117 }
118 //-------------------------------------------------------------------------------
119
120 std::vector<string> eParser::Split(std::string aBuffer, char aDelimiter)
121 {
122         int b = 0, i = 0, l = aBuffer.length();
123         std::vector<string> t;
124
125         while (i++ < l) {
126                 if (aBuffer[i] == aDelimiter) {
127                         t.push_back(aBuffer.substr(b, i-b));
128                         b = i + 1;
129                         continue;
130                 }
131                 if (i == (l - 1)) {
132                         t.push_back(aBuffer.substr(b, l));
133                 }
134         }
135         return t;
136 }
137 //-------------------------------------------------------------------------------
138
139 void eParser::FileName(char* aRequest, char* aHttp, std::string& aOutData)
140 {
141         char tmp[256] = {0};
142         char* file = aRequest + 5;
143         if (strncmp(file, "file?file=", strlen("file?file="))) {
144                 return;
145         }
146         strncpy(tmp, file+10, aHttp-file-10);
147         aOutData = eURIDecoder().Decode(tmp);
148 }
149 //-------------------------------------------------------------------------------
150
151 /* f:40,c:00007b,c:01008f,c:03007b */
152 bool eParser::MetaData(std::string aMediaFileName)
153 {
154         std::string metafilename = aMediaFileName;
155         metafilename += ".meta";
156
157         std::ifstream ifs(metafilename.c_str());
158
159         if (!ifs.is_open()) {
160 #ifdef DEBUG_LOG
161                 LOG("metadata is not exists..");
162 #endif
163                 return false;
164         }
165
166         size_t rc = 0, i = 0;
167         char buffer[1024] = {0};
168         while (!ifs.eof()) {
169                 ifs.getline(buffer, 1024);
170                 if (i++ == 7) {
171 #ifdef DEBUG_LOG
172                                 LOG("%d [%s]", i, buffer);
173 #endif
174                         std::vector<string> tokens = eParser::Split(buffer, ',');
175                         if(tokens.size() < 3) {
176 #ifdef DEBUG_LOG
177                                 LOG("pid count size error : %d", tokens.size());
178 #endif
179                                 return false;
180                         }
181
182                         for (int ii = 0; ii < tokens.size(); ++ii) {
183                                 std::string token = tokens[ii];
184 #ifdef DEBUG_LOG
185                                 LOG("token : %d [%s]", ii, token.c_str());
186 #endif
187                                 switch(ii) {
188                                         case(1):
189                                                 gVideoPid = strtol(token.substr(4,8).c_str(), NULL, 16);
190 #ifdef DEBUG_LOG
191                                                 LOG("video pid : %d", gVideoPid);
192 #endif
193                                                 break;
194                                         case(2):
195                                                 gAudioPid = strtol(token.substr(4,8).c_str(), NULL, 16);
196 #ifdef DEBUG_LOG
197
198                                                 LOG("audio pid : %d", gAudioPid);
199 #endif
200                                                 break;
201                                 }
202                         }
203                         break;
204                 }
205         }
206         ifs.close();
207         return true;
208 }
209 //-------------------------------------------------------------------------------
210
211