Merge branch 'nto-signal-stats'
[dvblast.git] / asi-deltacast.c
blob7ba43ed6d8a5d939c9373f097b1da2aaa3c53091
1 /*****************************************************************************
2 * asi-deltacast.c: support for Deltacast ASI cards
3 *****************************************************************************
4 * Copyright (C) 2004, 2009, 2015 VideoLAN
6 * Authors: Simon Lockhart <simon@slimey.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22 #include "config.h"
24 #ifdef HAVE_ASI_DELTACAST_SUPPORT
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <sys/uio.h>
36 #include <sys/poll.h>
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <errno.h>
43 #include <ev.h>
45 #include <bitstream/common.h>
47 #include <StreamMaster.h>
48 // #include <DeltacastErrors.h>
50 #include "asi-deltacast.h"
52 #include "dvblast.h"
54 /*****************************************************************************
55 * Local declarations
56 *****************************************************************************/
57 #define ASI_DELTACAST_PERIOD 1000 /* ms */
58 #define ASI_DELTACAST_LOCK_TIMEOUT 5000000 /* 5 s */
60 static HANDLE h_board, h_channel;
61 static struct ev_timer asi_watcher, mute_watcher;
62 static bool b_sync = false;
64 static UCHAR *p_asibuf = NULL;
65 static ULONG i_asibuf_len;
67 /*****************************************************************************
68 * asi_deltacast_Open
69 *****************************************************************************/
70 void asi_deltacast_Open( void )
72 ASICHANNELCONFIG RXConfig;
73 ULONG ApiVersion, DrvVersion, NbBoards;
74 ASIBOARDINFOEX BoardInfoEx;
75 BOOL res;
77 /* Get API information */
78 res = Asi_GetApiInfo(&ApiVersion,&DrvVersion,&NbBoards);
79 if (!res)
81 msg_Err( NULL, "couldn't get Deltacast API Info: 0x%08lX",
82 (unsigned long) Dc_GetLastError(NULL) );
83 exit(EXIT_FAILURE);
86 msg_Dbg( NULL, "Deltacast StreamMaster DLL v%d.%d",
87 (int)ApiVersion>>16,
88 (int)ApiVersion&0xFFFF);
89 msg_Dbg( NULL, "Deltacast Driver v%d.%d.%d",
90 (DrvVersion >> 24) & 0xFF,
91 (DrvVersion >> 16) & 0xFF,
92 (DrvVersion >> 8) & 0xFF);
93 msg_Dbg( NULL, "Deltacast Board Count: %d", NbBoards);
95 /* Get the board information */
96 res = Asi_GetBoardInfoEx((int)(i_asi_adapter / 100), &BoardInfoEx);
97 if (!res)
99 msg_Err( NULL, "couldn't get Deltacast board Info: 0x%08lX",
100 (unsigned long) Dc_GetLastError(NULL) );
101 exit(EXIT_FAILURE);
104 msg_Dbg( NULL, "Deltacast Board FPGA v%08lX",
105 (unsigned long)BoardInfoEx.BaseInformation.FPGAVersion);
106 msg_Dbg( NULL, "Deltacast Board PLD v%08lX",
107 (unsigned long)BoardInfoEx.BaseInformation.PLDVersion);
108 msg_Dbg( NULL, "Deltacast Board PLX v%08lX",
109 (unsigned long)BoardInfoEx.BaseInformation.PLXRevision);
110 msg_Dbg( NULL, "Deltacast Board Serial %08X%08X",
111 (ULONG)(BoardInfoEx.BaseInformation.SerialNb>>32),
112 (ULONG)(BoardInfoEx.BaseInformation.SerialNb&0xFFFFFFFF));
113 msg_Dbg( NULL, "Deltacast Board Input Count: %d", BoardInfoEx.NbRxChannels_i);
114 msg_Dbg( NULL, "Deltacast Board Output Count: %d", BoardInfoEx.NbTxChannels_i);
116 /* Open the board */
117 h_board = Asi_SetupBoard((int)(i_asi_adapter / 100));
118 if (h_board == NULL)
120 msg_Err( NULL, "couldn't setup deltacast board %d: 0x%08lX",
121 (int)(i_asi_adapter / 100), (unsigned long) Dc_GetLastError(NULL) );
122 exit(EXIT_FAILURE);
125 /* Open the channel on the board */
126 memset(&RXConfig,0,sizeof(ASICHANNELCONFIG));
127 RXConfig.DriverBufferSize = 188 * 2400; /* Use a driver buffer size of 2400 packets */
128 RXConfig.BoardBufferSize = 1048576; /* Use 1MB of onboard buffer */
129 RXConfig.TSPacketType = ASI_PKT_188; /* Use 188-bytes TS packets */
130 RXConfig.NbPIDFilter = 0; /* No PID filtering */
131 RXConfig.pPIDFilterTable = NULL; /* No PID filtering */
132 RXConfig.BitrateIntPeriod = ASI_INTPER_100; /* Integrate over 100 msec */
133 RXConfig.AllowedBRDeviation= 10000000; /* Allow 10Mbps of deviation */
134 RXConfig.RXTimeStamp = FALSE; /* No timestamping */
136 /* Try to open RX0 channel on the board 0 */
137 h_channel = Asi_OpenChannel(h_board, ASI_CHN_RX0 + (i_asi_adapter % 100), &RXConfig);
138 if (h_channel == NULL)
140 msg_Err( NULL, "couldn't setup deltacast channel %d: 0x%08lX",
141 (i_asi_adapter % 100), (unsigned long) Dc_GetLastError(NULL) );
142 exit(EXIT_FAILURE);
145 ev_timer_init(&asi_watcher, asi_deltacast_Read,
146 ASI_DELTACAST_PERIOD / 1000000.,
147 ASI_DELTACAST_PERIOD / 1000000.);
148 ev_timer_start(event_loop, &asi_watcher);
150 ev_timer_init(&mute_watcher, asi_deltacast_MuteCb,
151 ASI_DELTACAST_LOCK_TIMEOUT / 1000000.,
152 ASI_DELTACAST_LOCK_TIMEOUT / 1000000.);
155 /*****************************************************************************
156 * ASI deltacast events
157 *****************************************************************************/
158 static void asi_deltacast_Read(struct ev_loop *loop, struct ev_io *w, int revents)
160 BOOL res;
161 block_t *p_ts, **pp_current = &p_ts;
162 int i;
163 ULONG Err;
165 res = Asi_GetInputBuffer(h_channel, &p_asibuf, &i_asibuf_len,
166 ASI_DELTACAST_PERIOD);
167 if (!res)
169 Err = Dc_GetLastError(NULL) & ~DC_ERRORCODE_MASK;
171 if (Err != DCERR_TIMEOUT)
173 msg_Warn( NULL, "asi_deltacast_Read(): GetInputBuffer failed: 0x%08X!", Err);
175 return;
178 if ( !b_sync )
180 msg_Info( NULL, "frontend has acquired lock" );
181 switch (i_print_type) {
182 case PRINT_XML:
183 fprintf(print_fh, "<STATUS type=\"lock\" status=\"1\"/>\n");
184 break;
185 case PRINT_TEXT:
186 fprintf(print_fh, "lock status: 1\n");
187 break;
188 default:
189 break;
192 b_sync = true;
195 ev_timer_again(loop, &mute_watcher);
197 for (i = 0; i < i_asibuf_len / TS_SIZE; i++)
199 *pp_current = block_New();
200 memcpy((*pp_current)->p_ts, p_asibuf + (i * TS_SIZE), TS_SIZE);
201 pp_current = &(*pp_current)->p_next;
205 res = Asi_ReleaseInputBuffer(h_channel);
207 // msg_Warn( NULL, "asi_deltacast_Read(): returning %d blocks", i_asibuf_len / TS_SIZE );
209 demux_Run( p_ts );
212 static void asi_deltacast_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents)
214 msg_Warn( NULL, "frontend has lost lock" );
215 ev_timer_stop(loop, w);
217 switch (i_print_type) {
218 case PRINT_XML:
219 fprintf(print_fh, "<STATUS type=\"lock\" status=\"0\"/>\n");
220 break;
221 case PRINT_TEXT:
222 fprintf(print_fh, "lock status: 0\n" );
223 break;
224 default:
225 break;
229 /*****************************************************************************
230 * asi_deltacast_SetFilter
231 *****************************************************************************/
232 int asi_deltacast_SetFilter( uint16_t i_pid )
234 /* TODO: Support PID filtering */
235 msg_Warn( NULL, "asi_deltacast_SetFilter(%d) not yet implemented", i_pid );
236 return -1;
239 /*****************************************************************************
240 * asi_deltacast_UnsetFilter: normally never called
241 *****************************************************************************/
242 void asi_deltacast_UnsetFilter( int i_fd, uint16_t i_pid )
244 /* TODO: Support PID filtering */
245 msg_Warn( NULL, "asi_deltacast_UnsetFilter() not yet implemented" );
248 /*****************************************************************************
249 * asi_deltacast_Reset
250 *****************************************************************************/
251 void asi_deltacast_Reset( void )
253 /* Called when retune required, so nothing required */
254 msg_Warn( NULL, "asi_deltacast_Reset() do nothing" );
257 #endif