blob: 4ad356119d83f04f79eaeaea4cd9d7682fdaf902 [file] [log] [blame]
/**
* \page dvb_wrapper_test
* \section Introduction
* test code with dvb_wrapper_xxxx APIs.
* It supports:
* \li Record
*
* \section Usage
*
* Help msg will be shown if the test runs without parameters.\n
* There are some general concepts for the parameters:
* \li assign value "1" to the parameter to enable a feature specified
* \li millisecond is used as time unit
* \li no limit to the parameter order
*
* For recording:
* \code
* dvr_wrapper_test.dataout [tsin=n] [dataout=<stdout>]
* \endcode
*
* \section ops Operations in the test:
* \li quit\n
* quit the test
* \endsection
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include "dvr_segment.h"
#include "dvr_wrapper.h"
#include "dvb_utils.h"
#include "segment_dataout.h"
/****************************************************************************
* Macro definitions
***************************************************************************/
#define DMX_DEV_DVR 1
#define REC_EVT(fmt, ...) fprintf(stderr, "recorder:" fmt, ##__VA_ARGS__)
#define INF(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#define ERR(fmt, ...) fprintf(stderr, "error:" fmt, ##__VA_ARGS__)
#define RESULT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
static int ts_src=0;
static FILE *dataout = NULL;
static int flush_size = 10* 188 * 1024;
static DVR_WrapperRecord_t recorder;
static void display_usage(void)
{
INF( "==================\n");
INF( "*quit\n");
INF( "==================\n");
}
int start_test(void)
{
DVR_Bool_t go = DVR_TRUE;
char buf[256];
display_usage();
while (go) {
if (fgets(buf, sizeof(buf), stdin)) {
if (!strncmp(buf, "quit", 4)) {
go = DVR_FALSE;
continue;
}
else if (!strncmp(buf, "recpause", 8)) {
INF("rec paused.\n");
}
else if (!strncmp(buf, "recresume", 9)) {
INF("rec resumed.\n");
}
else {
ERR("Unknown command: %s\n", buf);
display_usage();
}
}
}
if (dataout && dataout != stdout) {
fclose(dataout);
dataout = NULL;
}
return 0;
}
static void log_rec_evt(DVR_WrapperRecordStatus_t *status, void *user)
{
char *state[] = {
/*DVR_RECORD_STATE_OPENED*/ "open", /**< Record state is opened*/
/*DVR_RECORD_STATE_STARTED*/"start", /**< Record state is started*/
/*DVR_RECORD_STATE_STOPPED*/"stop", /**< Record state is stopped*/
/*DVR_RECORD_STATE_CLOSED*/ "close", /**< Record state is closed*/
};
REC_EVT("[%s] state[%s(0x%x)] time/size/pkts[%lu/%llu/%u]\n",
(char *)user,
state[status->state],
status->state,
status->info.time,
status->info.size,
status->info.pkts
);
}
static DVR_Result_t RecEventHandler(DVR_RecordEvent_t event, void *params, void *userdata)
{
if (userdata != NULL)
{
DVR_WrapperRecordStatus_t *status = (DVR_WrapperRecordStatus_t *)params;
switch (event)
{
case DVR_RECORD_EVENT_STATUS:
log_rec_evt(status, userdata);
break;
default:
REC_EVT("Unhandled recording event 0x%x from (%s)\n", event, (char *)userdata);
break;
}
}
return DVR_SUCCESS;
}
static int data_cb(unsigned char *buf, size_t size, void *priv)
{
INF("data(%d) priv(%s): %02x %02x %02x %02x\n", size, (char *)priv, buf[0], buf[1], buf[2], buf[3]);
if (dataout)
fwrite(buf, size, 1, dataout);
return size;
}
static int start_recording()
{
DVR_WrapperRecordOpenParams_t rec_open_params;
DVR_WrapperRecordStartParams_t rec_start_params;
DVR_WrapperPidsInfo_t *pids_info;
char cmd[256];
int error = 0;
sprintf(cmd, "echo ts%d > /sys/class/stb/demux%d_source", ts_src, DMX_DEV_DVR);
//system(cmd);
dvb_set_demux_source(DMX_DEV_DVR, ts_src);
memset(&rec_open_params, 0, sizeof(DVR_WrapperRecordOpenParams_t));
rec_open_params.dmx_dev_id = DMX_DEV_DVR;
rec_open_params.segment_size = 0;/*infinite*/
rec_open_params.max_size = 0;/*infinite*/
rec_open_params.max_time = 0;/*infinite*/
rec_open_params.event_fn = RecEventHandler;
rec_open_params.event_userdata = "rec0";
rec_open_params.flags = DVR_RECORD_FLAG_DATAOUT;
rec_open_params.force_sysclock = DVR_TRUE;
rec_open_params.flush_size = flush_size;
snprintf(rec_open_params.location, DVR_MAX_LOCATION_SIZE, "%s", "dataout");
error = dvr_wrapper_open_record(&recorder, &rec_open_params);
if (error) {
ERR( "recorder open fail = (0x%x)\n", error);
return -1;
}
INF( "Starting %s recording %p [%ld secs/%llu bytes]\n",
"dataout",
recorder,
rec_open_params.max_time,
rec_open_params.max_size);
Segment_DataoutCallback_t dataout = { data_cb, "datacb_priv"};
error = dvr_wrapper_ioctl_record(recorder, SEGMENT_DATAOUT_CMD_SET_CALLBACK, &dataout, sizeof(dataout));
if (error) {
INF("Set dataout callback fail = (%#x)", error);
dvr_wrapper_close_record(recorder);
return -1;
}
memset(&rec_start_params, 0, sizeof(rec_start_params));
pids_info = &rec_start_params.pids_info;
pids_info->nb_pids = 1;
pids_info->pids[0].pid = 0x2000;
pids_info->pids[0].type = DVR_STREAM_TYPE_OTHER << 24;
error = dvr_wrapper_start_record(recorder, &rec_start_params);
if (error)
{
ERR( "recorder start fail = (0x%x)\n", error);
dvr_wrapper_close_record(recorder);
return -1;
}
return 0;
}
static void usage(int argc, char *argv[])
{
INF( "Usage: record : %s [tsin=n] [dataout=<stdout>]\n", argv[0]);
}
static void exit_helper() { if (dataout && dataout != stdout) fclose(dataout); }
void sig_handler(int signo)
{
if (signo == SIGTERM)
exit_helper();
exit(0);
}
int main(int argc, char **argv)
{
int error;
int i;
int helper = 0;
for (i = 1; i < argc; i++) {
if (!strncmp(argv[i], "tsin", 4))
sscanf(argv[i], "tsin=%i", &ts_src);
else if (!strncmp(argv[i], "dataout=stdout", 14))
dataout = stdout;
else if (!strncmp(argv[i], "flush=", 6))
sscanf(argv[i], "flush=%i", &flush_size);
else if (!strncmp(argv[i], "help", 4)) {
usage(argc, argv);
exit(0);
}
}
if (argc == 1) {
usage(argc, argv);
exit(0);
}
if (helper) {
atexit(&exit_helper);
signal(SIGTERM, &sig_handler);
signal(SIGINT, &sig_handler);
}
error = start_recording();
if (error != 0) {
ERR("start_recording failed with return value %d",error);
}
//command loop
start_test();
error = dvr_wrapper_stop_record(recorder);
INF("stop record = (0x%x)\n", error);
error = dvr_wrapper_close_record(recorder);
INF("close record = (0x%x)\n", error);
return 0;
}