summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tv/CTvRecord.cpp (plain)
blob: 564f4f38217e5603de49ce39d8bf0c55dd59cefd
1#include <string.h>
2#include <fcntl.h>
3#include <sys/ioctl.h>
4#include <am_debug.h>
5#include <am_dmx.h>
6#include <am_av.h>
7
8#include <am_misc.h>
9
10#include <am_fend.h>
11#include <am_dvr.h>
12#include <errno.h>
13#include "CTvProgram.h"
14#include "../tvconfig/tvconfig.h"
15#include "CTvRecord.h"
16
17#ifdef LOG_TAG
18#undef LOG_TAG
19#endif
20#define LOG_TAG "CTvRecord"
21
22#define FEND_DEV_NO 0
23#define DVR_DEV_NO 0
24#define DVR_BUF_SIZE 1024*1024
25#define DVR_DEV_COUNT (2)
26
27typedef struct {
28 int id;
29 char file_name[256];
30 pthread_t thread;
31 int running;
32 int fd;
33} DVRData;
34
35static DVRData data_threads[DVR_DEV_COUNT];
36int pvr_init = 0;
37CTvRecord::CTvRecord()
38{
39 AM_DVR_OpenPara_t dpara;
40 memset(&dpara, 0, sizeof(dpara));
41 AM_DVR_Open(DVR_DEV_NO, &dpara);
42 data_threads[DVR_DEV_NO].id = 0;
43 data_threads[DVR_DEV_NO].fd = -1;
44 data_threads[DVR_DEV_NO].running = 0;
45
46 AM_DVR_SetSource(DVR_DEV_NO, AM_DVR_SRC_ASYNC_FIFO0);
47 AM_DVR_SetBufferSize(DVR_DEV_NO, DVR_BUF_SIZE);
48
49 memset(filename, 0, sizeof(filename));
50 progid = 0xFFFF;
51 vpid = 0x1fff;
52 apid = 0x1fff;
53}
54CTvRecord::~CTvRecord()
55{
56 AM_DVR_Close(DVR_DEV_NO);
57
58}
59void CTvRecord::dvr_init(void)
60{
61 AM_DVR_OpenPara_t para;
62 char buf[32];
63
64 if (pvr_init)
65 return;
66
67 memset(&para, 0, sizeof(para));
68 LOGD("%s,%d", "TV", __LINE__);
69
70 AM_DVR_Open(DVR_DEV_NO, &para);
71 AM_DVR_SetSource(DVR_DEV_NO, AM_DVR_SRC_ASYNC_FIFO0);
72 AM_DVR_SetBufferSize(DVR_DEV_NO, DVR_BUF_SIZE);
73
74 snprintf(buf, sizeof(buf), "%d", (512 * 1024));
75 AM_FileEcho("/sys/class/dmx/asyncfifo_len", buf);
76
77 pvr_init = 1;
78}
79
80char *CTvRecord::GetRecordFileName()
81{
82 return filename;
83}
84void CTvRecord::SetRecordFileName(char *name)
85{
86 strcpy(filename, name);
87}
88void CTvRecord::SetCurRecProgramId(int id)
89{
90 progid = id;
91}
92
93int CTvRecord::dvr_data_write(int fd, uint8_t *buf, int size)
94{
95 int ret;
96 int left = size;
97 uint8_t *p = buf;
98 LOGD("%s,%d", "TV", __LINE__);
99
100 while (left > 0) {
101 ret = write(fd, p, left);
102 if (ret == -1) {
103 if (errno != EINTR) {
104 LOGD("Write DVR data failed: %s", strerror(errno));
105 break;
106 }
107 ret = 0;
108 }
109
110 left -= ret;
111 p += ret;
112 }
113
114 return (size - left);
115}
116void *CTvRecord::dvr_data_thread(void *arg)
117{
118 DVRData *dd = (DVRData *)arg;
119 int cnt;
120 uint8_t buf[256 * 1024];
121
122 LOGD("Data thread for DVR%d start ,record file will save to '%s'", dd->id, dd->file_name);
123 LOGD("%s,%d", "TV", __LINE__);
124
125 while (dd->running) {
126 cnt = AM_DVR_Read(dd->id, buf, sizeof(buf), 1000);
127 if (cnt <= 0) {
128 LOGD("No data available from DVR%d", dd->id);
129 usleep(200 * 1000);
130 continue;
131 }
132 //AM_DEBUG(1, "read from DVR%d return %d bytes", dd->id, cnt);
133 if (dd->fd != -1) {
134 dvr_data_write(dd->fd, buf, cnt);
135 }
136 }
137
138 if (dd->fd != -1) {
139 close(dd->fd);
140 dd->fd = -1;
141 }
142 LOGD("Data thread for DVR%d now exit", dd->id);
143
144 return NULL;
145}
146
147void CTvRecord::start_data_thread(int dev_no)
148{
149 DVRData *dd = &data_threads[dev_no];
150
151 if (dd->running)
152 return;
153 LOGD("%s,%d,dev=%d", "TV", __LINE__, dev_no);
154 dd->fd = open(dd->file_name, O_TRUNC | O_WRONLY | O_CREAT, 0666);
155 if (dd->fd == -1) {
156 LOGD("Cannot open record file '%s' for DVR%d, %s", dd->file_name, dd->id, strerror(errno));
157 return;
158 }
159 dd->running = 1;
160 pthread_create(&dd->thread, NULL, dvr_data_thread, dd);
161}
162void CTvRecord::get_cur_program_pid(int progId)
163{
164 CTvProgram prog;
165 int aindex;
166 CTvProgram::Audio *pA;
167 CTvProgram::Video *pV;
168 int ret = CTvProgram::selectByID(progId, prog);
169 if (ret != 0) return;
170
171 LOGD("%s,%d", "TV", __LINE__);
172 pV = prog.getVideo();
173 if (pV != NULL) {
174 setvpid(pV->getPID());
175 }
176
177 aindex = prog.getCurrAudioTrackIndex();
178 if (-1 == aindex) { //db is default
179 aindex = prog.getCurrentAudio(String8("eng"));
180 if (aindex >= 0) {
181 prog.setCurrAudioTrackIndex(progId, aindex);
182 }
183 }
184
185 if (aindex >= 0) {
186 pA = prog.getAudio(aindex);
187 if (pA != NULL) {
188 setapid(pA->getPID());
189 }
190 }
191
192}
193int CTvRecord::start_dvr()
194{
195 AM_DVR_StartRecPara_t spara;
196 int pid_cnt;
197 int pids[2];
198
199 /**½ö²âÊÔ×î¶à8¸öPID*/
200 get_cur_program_pid(progid);
201 pids[0] = getvpid();
202 pids[1] = getapid();
203
204 strcpy(data_threads[DVR_DEV_NO].file_name, GetRecordFileName());
205 LOGD("%s,%d", "TV", __LINE__);
206 //sprintf(data_threads[DVR_DEV_NO].file_name,"%s","/storage/external_storage/sda4/testdvr.ts");
207 spara.pid_count = 2;
208 memcpy(&spara.pids, pids, sizeof(pids));
209
210 if (AM_DVR_StartRecord(DVR_DEV_NO, &spara) == AM_SUCCESS) {
211 start_data_thread(DVR_DEV_NO);
212 }
213
214 return 0;
215}
216void CTvRecord::stop_data_thread(int dev_no)
217{
218 DVRData *dd = &data_threads[dev_no];
219 LOGD("%s,%d", "TV", __LINE__);
220
221 if (! dd->running)
222 return;
223 dd->running = 0;
224 pthread_join(dd->thread, NULL);
225 LOGD("Data thread for DVR%d has exit", dd->id);
226}
227
228
229void CTvRecord::StartRecord(int id)
230{
231 AM_DVR_OpenPara_t dpara;
232 fe_status_t status;
233 char buf[32];
234
235 AM_FEND_GetStatus(FEND_DEV_NO, &status);
236
237 if (status & FE_HAS_LOCK) {
238 LOGD("locked\n");
239 } else {
240 LOGD("unlocked\n");
241 return ;
242 }
243 SetCurRecProgramId(id);
244 start_dvr();
245
246 return;
247}
248void CTvRecord::StopRecord()
249{
250 int i = 0;
251 LOGD("stop record for %d", DVR_DEV_NO);
252 AM_DVR_StopRecord(DVR_DEV_NO);
253
254 //for (i=0; i< DVR_DEV_COUNT; i++)
255 {
256 if (data_threads[DVR_DEV_NO].running)
257 stop_data_thread(DVR_DEV_NO);
258 //LOGD("Closing DMX%d...", i);
259 }
260
261
262}
263void CTvRecord::SetRecCurTsOrCurProgram(int sel)
264{
265 int i = 0;
266 char buf[50];
267 memset(buf, 0, sizeof(buf));
268 for (; i < 3; i++) {
269 snprintf(buf, sizeof(buf), "/sys/class/stb/dvr%d_mode", i);
270 if (sel)
271 AM_FileEcho(buf, "ts");
272 else
273 AM_FileEcho(buf, "pid");
274 }
275}
276
277