SHOW:
|
|
- or go back to the newest paste.
1 | - | diff -r 7be3bddbf7c3 -r 6ec6a070e70e sample.cpp |
1 | + | diff -r 7be3bddbf7c3 -r 43ac6dff58f6 sample.cpp |
2 | --- a/sample.cpp Thu Aug 28 21:23:44 2014 +0900 | |
3 | - | +++ b/sample.cpp Mon Sep 01 17:29:45 2014 +0900 |
3 | + | +++ b/sample.cpp Mon Sep 01 17:46:36 2014 +0900 |
4 | @@ -1,7 +1,7 @@ | |
5 | /* | |
6 | -$ g++ -O2 -Wall -rdynamic -o sample sample.cpp -ldl | |
7 | +$ g++ -O2 -Wall -rdynamic -o sample sample.cpp -ldl -larib25 | |
8 | */ | |
9 | -#define FILE_OFFSET_BITS 64 | |
10 | +#define _FILE_OFFSET_BITS 64 | |
11 | #include <unistd.h> | |
12 | #include <stdio.h> | |
13 | #include <stdlib.h> | |
14 | @@ -15,6 +15,123 @@ | |
15 | #include "typedef.h" | |
16 | #include "IBonDriver2.h" | |
17 | ||
18 | +#include <getopt.h> | |
19 | +#include "arib25/arib_std_b25.h" | |
20 | + | |
21 | +class B25Decorder { | |
22 | + ARIB_STD_B25 *b25; | |
23 | + B_CAS_CARD *bcas; | |
24 | + bool valid; | |
25 | + ARIB_STD_B25_BUFFER sbuf; | |
26 | + ARIB_STD_B25_BUFFER dbuf; | |
27 | + | |
28 | +public: | |
29 | + B25Decorder() : b25(0), bcas(0), valid(false) {} | |
30 | + ~B25Decorder() { release(); } | |
31 | + | |
32 | + int init(bool strip, bool emm, int round = 4) | |
33 | + { | |
34 | + int code = -1; | |
35 | + if (valid) | |
36 | + release(); | |
37 | + | |
38 | + if (!(bcas = create_b_cas_card())) | |
39 | + goto err; | |
40 | + | |
41 | + if (!(b25 = create_arib_std_b25())) | |
42 | + goto err; | |
43 | + | |
44 | + if ((code = bcas->init(bcas)) < 0) | |
45 | + goto err; | |
46 | + | |
47 | + if ((code = b25->set_b_cas_card(b25, bcas)) < 0) | |
48 | + goto err; | |
49 | + | |
50 | + b25->set_strip(b25, strip); | |
51 | + b25->set_emm_proc(b25, emm); | |
52 | + b25->set_multi2_round(b25, round); | |
53 | + | |
54 | + valid = true; | |
55 | + | |
56 | + err: | |
57 | + if (code < 0) | |
58 | + release(); | |
59 | + return code; | |
60 | + } | |
61 | + | |
62 | + void release() | |
63 | + { | |
64 | + if (b25) | |
65 | + b25->release(b25); | |
66 | + | |
67 | + if (bcas) | |
68 | + bcas->release(bcas); | |
69 | + | |
70 | + b25 = 0; | |
71 | + bcas = 0; | |
72 | + valid = false; | |
73 | + } | |
74 | + | |
75 | + ssize_t write(int fd, void *buf, size_t count) | |
76 | + { | |
77 | + if (!valid) | |
78 | + return ::write(fd, buf, count); | |
79 | + | |
80 | + sbuf.data = static_cast<uint8_t*>(buf); | |
81 | + sbuf.size = count; | |
82 | + | |
83 | + int code; | |
84 | + if ((code = b25->put(b25, &sbuf)) < 0) | |
85 | + return code; | |
86 | + | |
87 | + if ((code = b25->get(b25, &dbuf)) < 0) | |
88 | + return code; | |
89 | + | |
90 | + if (dbuf.size > 0) | |
91 | + { | |
92 | + ssize_t len; | |
93 | + if ((len = write_full(fd, dbuf.data, dbuf.size)) < 0) | |
94 | + return len; | |
95 | + } | |
96 | + return count; | |
97 | + } | |
98 | + | |
99 | + static ssize_t write_full(int fd, const void *buf, size_t count) | |
100 | + { | |
101 | + size_t size_remain = count; | |
102 | + size_t offset = 0; | |
103 | + | |
104 | + while (size_remain > 0) { | |
105 | + ssize_t wc = ::write(fd, static_cast<const char*>(buf) + offset, size_remain); | |
106 | + if (wc < 0) { | |
107 | + perror("write"); | |
108 | - | + break; |
108 | + | + return wc; |
109 | + } | |
110 | + size_remain -= wc; | |
111 | + offset += wc; | |
112 | + } | |
113 | + return count - size_remain; | |
114 | + } | |
115 | + | |
116 | + int flush(int fd) | |
117 | + { | |
118 | + int code; | |
119 | + if (!valid) | |
120 | + return 0; | |
121 | + | |
122 | + if ((code = b25->flush(b25)) < 0) | |
123 | + return code; | |
124 | + | |
125 | + if ((code = b25->get(b25, &dbuf)) < 0) | |
126 | + return code; | |
127 | + | |
128 | + if (dbuf.size > 0) | |
129 | + return write_full(fd, dbuf.data, dbuf.size); | |
130 | + | |
131 | + return 0; | |
132 | + } | |
133 | +}; | |
134 | + | |
135 | static volatile BOOL bStop = FALSE; | |
136 | static void handler(int sig) | |
137 | { | |
138 | @@ -23,13 +140,17 @@ | |
139 | ||
140 | void usage(char *p) | |
141 | { | |
142 | - fprintf(stderr, "usage: %s [-b bondriver] [-s space_no] [-c channel_no] ( [-t sec] [-o filename] )\n", p); | |
143 | + fprintf(stderr, "usage: %s [--b25 [--round N] [--strip] [--EMM]] [-b bondriver] [-s space_no] [-c channel_no] ( [-t sec] [-o filename] )\n", p); | |
144 | exit(0); | |
145 | } | |
146 | ||
147 | int main(int argc, char *argv[]) | |
148 | { | |
149 | int opt, bfind, sfind, cfind, ofind, wfd; | |
150 | + int b25 = false; | |
151 | + int strip = false; | |
152 | + int emm = false; | |
153 | + int round = 4; | |
154 | char *bon, *output; | |
155 | DWORD sec, dwSpace, dwChannel; | |
156 | ||
157 | @@ -38,10 +159,24 @@ | |
158 | bon = output = NULL; | |
159 | bfind = sfind = cfind = ofind = 0; | |
160 | dwSpace = dwChannel = 0; | |
161 | - while ((opt = getopt(argc, argv, "b:s:c:t:o:")) != -1) | |
162 | + | |
163 | + static const struct option options[] = { | |
164 | + {"b25", no_argument, &b25, 1}, | |
165 | + {"strip", no_argument, &strip, 1}, | |
166 | + {"EMM", no_argument, &emm, 1}, | |
167 | + {"round", required_argument, NULL, 'r'}, | |
168 | + {0} | |
169 | + }; | |
170 | + | |
171 | + while ((opt = getopt_long(argc, argv, "b:s:c:t:o:", options, NULL)) != -1) | |
172 | { | |
173 | switch (opt) | |
174 | { | |
175 | + case 0: // long options | |
176 | + break; | |
177 | + case 'r': // multi2 round | |
178 | + round = strtoul(optarg, NULL, 10); | |
179 | + break; | |
180 | case 'b': // BonDriver指定 | |
181 | bon = optarg; | |
182 | bfind = 1; | |
183 | @@ -150,6 +285,12 @@ | |
184 | timespec ts; | |
185 | ts.tv_sec = 0; | |
186 | ts.tv_nsec = 10 * 1000 * 1000; // 10ms | |
187 | + B25Decorder b25dec; | |
188 | + if (b25) | |
189 | + { | |
190 | + if (b25dec.init(strip, emm, round) < 0) | |
191 | + goto err; | |
192 | + } | |
193 | while (!bStop) | |
194 | { | |
195 | // TSストリーム取得 | |
196 | @@ -158,18 +299,8 @@ | |
197 | { | |
198 | // この時点でpBufに長さdwSize分のTSストリームを取得した状態なので、それを書き出し | |
199 | // (もしバッファリングやデスクランブルやTS分離処理を入れるならこの辺で) | |
200 | - int len, left = (int)dwSize; | |
201 | - do | |
202 | - { | |
203 | - len = write(wfd, pBuf, left); | |
204 | - if (len < 0) | |
205 | - { | |
206 | - perror("write"); | |
207 | - goto err; | |
208 | - } | |
209 | - left -= len; | |
210 | - pBuf += len; | |
211 | - } while (left > 0); | |
212 | + if (b25dec.write(wfd, pBuf, dwSize) < 0) | |
213 | + goto err; | |
214 | } | |
215 | // 取得待ちTSデータが無ければ適当な時間待つ | |
216 | if (dwRemain == 0) | |
217 | @@ -180,29 +311,14 @@ | |
218 | pIBon->CloseTuner(); | |
219 | ||
220 | // BonDriver内のバッファに残っている分があれば一応回収 | |
221 | - while (1) | |
222 | + if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0)) | |
223 | { | |
224 | - dwSize = dwRemain = 0; | |
225 | - if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0)) | |
226 | - { | |
227 | - int len, left = (int)dwSize; | |
228 | - do | |
229 | - { | |
230 | - len = write(wfd, pBuf, left); | |
231 | - if (len < 0) | |
232 | - { | |
233 | - perror("write"); | |
234 | - goto err; | |
235 | - } | |
236 | - left -= len; | |
237 | - pBuf += len; | |
238 | - } while (left > 0); | |
239 | - } | |
240 | - if (dwRemain == 0) | |
241 | - break; | |
242 | + if (b25dec.write(wfd, pBuf, dwSize) < 0) | |
243 | + goto err; | |
244 | } | |
245 | ||
246 | err: | |
247 | + b25dec.flush(wfd); | |
248 | close(wfd); | |
249 | // インスタンス解放 & モジュールリリース | |
250 | pIBon->Release(); |