#ifdef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE #endif /*************************************************************************** * Copyright (c) 2014 Amlogic, Inc. All rights reserved. * * This source code is subject to the terms and conditions defined in the * file 'LICENSE' which is part of this source code package. * * Description: */ /**\file * \brief 节目管理 * * \author Gong Ke * \date 2010-10-25: create the document ***************************************************************************/ #define AM_DEBUG_LEVEL 5 #include #include #include #include "dtv.h" #include #include #include #include #include /**************************************************************************** * Macro definitions ***************************************************************************/ /*节目存储文件名*/ #define PROGRAM_FILE "prog.dat" /**************************************************************************** * Global data ***************************************************************************/ struct dvb_frontend_parameters ts_param; DTV_Program_t programs[DTV_PROG_COUNT]; int program_count; int curr_program; const fe_type_t fe_type = FE_QAM; static int curr_read_prog; static struct dvb_frontend_parameters last_ts_param; static void test_print_all_programs() { int i; printf("frequency %d:\n", ts_param.frequency); for (i=0; itses == NULL || result->tses->pmts == NULL) return ; /*清除原来节目*/ program_count = 0; curr_program = -1; /*存储频点信息*/ ts_param = result->tses->fend_para; AM_SI_LIST_BEGIN(result->tses->pmts, pmt) /*添加节目*/ if (program_count >= DTV_PROG_COUNT) { AM_DEBUG(1, "Too many programs!"); return; } prog = &programs[program_count]; prog->chan_num = program_count + 1; prog->video_pid = prog->audio_pid = 0x1fff; sprintf(prog->name, "电视节目%03d", prog->chan_num); /*检查ES流*/ AM_SI_LIST_BEGIN(pmt->p_first_es, es) /*video pid*/ if ((es->i_type == 0x1 || es->i_type == 0x2) && prog->video_pid == 0x1fff) prog->video_pid = (es->i_pid >= 0x1fff) ? 0x1fff : es->i_pid; /*audio pid*/ if ((es->i_type == 0x3 || es->i_type == 0x4) && prog->audio_pid == 0x1fff) prog->audio_pid = (es->i_pid >= 0x1fff) ? 0x1fff : es->i_pid; AM_SI_LIST_END() /*SDT*/ AM_SI_LIST_BEGIN(result->tses->sdts, sdt) AM_SI_LIST_BEGIN(result->tses->sdts->p_first_service, srv) if (srv->i_service_id == pmt->i_program_number) { AM_SI_LIST_BEGIN(srv->p_first_descriptor, descr) if (descr->p_decoded && descr->i_tag == AM_SI_DESCR_SERVICE) { dvbpsi_service_dr_t *psd = (dvbpsi_service_dr_t*)descr->p_decoded; /*取节目名称*/ if (psd->i_service_name_length > 0) { convertcode((char*)psd->i_service_name, psd->i_service_name_length,\ prog->name, sizeof(prog->name)); } /*跳出多层循环*/ goto SDT_END; } AM_SI_LIST_END() } AM_SI_LIST_END() AM_SI_LIST_END() SDT_END: /*不存储音视频PID都无效的节目*/ if ((prog->video_pid != 0x1fff) || (prog->audio_pid != 0x1fff)) program_count++; AM_SI_LIST_END() if (program_count > 0) curr_program = 0; AM_DEBUG(1, "Total searched %d programs, storing programs to file...", program_count); store_program_to_file(); AM_DEBUG(1, "Done"); test_print_all_programs(); } /**************************************************************************** * API functions ***************************************************************************/ int dtv_program_init(void) { /*初始化节目数据*/ program_count = 0; curr_program = -1; AM_DEBUG(1, "Loading programs from file..."); /*从文件中加载节目信息*/ load_program_from_file(); memset(&last_ts_param, 0, sizeof(last_ts_param)); if (program_count > 0) curr_program = 0; test_print_all_programs(); return 0; } int dtv_program_quit(void) { return 0; } /**\brief 取得指定频道号的节目信息*/ int dtv_program_get_info_by_chan_num(int chan_num, DTV_Program_t *info) { int i; assert(info); for (i=0; i= program_count) return -1; *info = programs[curr_program]; return 0; } /**\brief 播放当前节目*/ int dtv_program_play(void) { DTV_Program_t info; /*获取当前播放节目信息*/ if (dtv_program_get_curr_info(&info) < 0) { AM_DEBUG(1, "Cannot get curr program, cannot play"); return -1; } /*前端参数发生变化,需要重新锁定频点*/ //if (memcmp(&ts_param, &last_ts_param, sizeof(ts_param))) { fe_status_t status; AM_DEBUG(1, "FEnd param changed, try lock new param(%u)...",ts_param.frequency); AM_FEND_Lock(DTV_FEND_DEV_NO, &ts_param, &status); AM_DEBUG(1, "FEnd %s", (status & FE_HAS_LOCK) ? "Locked" : "Unlocked"); last_ts_param = ts_param; } AM_AV_StopTS(DTV_AV_DEV_NO); if (AM_AV_StartTS(0, info.video_pid, 0x1fff, 0, 0) != AM_SUCCESS) { AM_DEBUG(1, "AM_AV_StartTS Err!"); return -1; } return 0; } int dtv_program_play_by_channel_no(int channel_no) { DTV_Program_t info; /*获取当前播放节目信息*/ if (dtv_program_get_info_by_chan_num(channel_no,&info) < 0) { AM_DEBUG(1, "Cannot get curr program, cannot play"); return -1; } /*前端参数发生变化,需要重新锁定频点*/ //if (memcmp(&ts_param, &last_ts_param, sizeof(ts_param))) { fe_status_t status; AM_DEBUG(1, "FEnd param changed, try lock new param(%u)...",ts_param.frequency); AM_FEND_Lock(DTV_FEND_DEV_NO, &ts_param, &status); AM_DEBUG(1, "FEnd %s", (status & FE_HAS_LOCK) ? "Locked" : "Unlocked"); last_ts_param = ts_param; } AM_AV_StopTS(DTV_AV_DEV_NO); if (AM_AV_StartTS(0, info.video_pid, 0x1fff, 0, 0) != AM_SUCCESS) { AM_DEBUG(1, "AM_AV_StartTS Err!"); return -1; } curr_program = channel_no-1; return 0; } /**\brief 停止播放当前节目*/ int dtv_program_stop(void) { return AM_AV_StopTS(0); } /**\brief 播放下一个频道*/ int dtv_program_channel_up(void) { if (program_count <= 0) { curr_program = -1; return -1; } /*设置下一个节目为当前播放节目*/ curr_program++; if (curr_program < 0 || curr_program >= program_count) curr_program = 0; /*播放*/ return dtv_program_play(); } /**\brief 播放上一个频道*/ int dtv_program_channel_down(void) { if (program_count <= 0) { curr_program = -1; return -1; } /*设置上一个节目为当前播放节目*/ curr_program--; if (curr_program < 0 || curr_program >= program_count) curr_program = program_count - 1; /*播放*/ return dtv_program_play(); }