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