Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 113 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
113
Dung lượng
2,2 MB
Nội dung
BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI PHẠM QUANG TRIỆU NGHIÊN CỨU CÁC GIẢI PHÁP MIDDLEWARE TRONG HỆ THỐNG TRUYỀN HÌNH SỐ Chuyên ngành : Kỹ Thuật Điện Tử - Viễn Thông LUẬN VĂN THẠC SĨ KHOA HỌC KỸ THUẬT ĐIỆN TỬ - VIỄN THÔNG NGƯỜI HƯỚNG DẪN KHOA HỌC : TS.PHẠM NGỌC NAM Hà Nội – 2010 LỜI CAM ĐOAN Tôi xin cam đoan luận văn công trình nghiên cứu riêng tôi, không chép luận văn khác Các nội dung nghiên cứu kết luận văn trung thực Các tài liệu tham khảo liệt kê trích dẫn đầy đủ, rõ ràng theo danh mục tài liệu tham khảo luận văn Nếu sai, xin chịu trách nhiệm Tác giả luận văn Phạm Quang Triệu i MỤC LỤC LỜI CAM ĐOAN i DANH MỤC CÁC KÝ HIỆU VÀ CÁC CHỮ VIẾT TẮT iv DANH MỤC CÁC BẢNG vi DANH MỤC CÁC HÌNH VẼ vii PHẦN MỞ ĐẦU ix Chương 1: Tổng quan hệ thống truyền hình số 1.1 Sự chuyển đổi công nghệ sang truyền hình số 1.1.1 Một số vấn đề biến đổi tín hiệu truyền hình 1.1.1.1 Lựa chọn độ phân giải cho hình ảnh số 1.1.1.2 Lựa chọn tần số lấy mẫu 1.1.1.3 Lựa chọn cấu trúc mẫu 1.1.1.4 Lựa chọn tín hiệu số hóa 1.1.2 Quá trình chuyển đổi công nghệ tương tự-số 1.2 Khái quát truyền hình số 1.2.1 Đặc điểm phát thanh, truyền hình số 1.2.2 Sơ đồ khối tổng quát hệ thống phát thanh, truyền hình số 1.2.3 Thu, phát truyền dẫn tín hiệu truyền hình số 1.2.3.1 Truyễn dẫn tín hiệu truyền hình số 1.2.3.2 Thu tín hiệu truyền hình số 11 1.3 Một số tiêu chuẩn truyền hình số giới 18 1.3.1 Chuẩn ATSC 18 1.3.1.1 Đặc điểm chung 18 1.3.1.2 Phương pháp điều chế VSB tiêu chuẩn ATSC 19 1.3.2 Chuẩn DVB 22 1.3.2.1 Đặc điểm chung 22 1.3.2.2 Phương pháp điều chế COFDM tiêu chuẩn DVB 23 Chương 2: Phương pháp đóng gói truyền tải tín hiệu Video-Audio theo tiêu chuẩn MPEG-2 26 2.1 Hệ thống truyền tín hiệu MPEG-2 26 2.2 Dòng liệu đóng gói, dòng chương trình dòng truyền tải 28 2.2.1 Dòng liệu đóng gói (Packetized Elementary Stream-PES) 28 2.2.2 Dòng chương trình (Program Stream-PS) dòng truyền tải (Transport Stream-TS) 29 2.3 Dòng truyền tải MPEG-2 32 2.3.1 Tính linh hoạt dòng truyền tải 33 2.3.2 Khả liên vận hành dòng truyền tải 34 ii 2.3.3 Sự phân loại dòng truyền tải 35 2.3.4 Thông tin đặc tả chương trình PSI (Program Specific Information) 36 2.4 Định thời đồng sử dụng dòng truyền tải MPEG-2 39 Chương 3: Giải pháp Middleware cho hệ thống truyền hình số 43 3.1 Khái niệm Middleware 43 3.2 Giải pháp Middleware cho hệ thống truyền hình số 44 3.2.1 MHEG-5 45 3.2.1.1 Kiến trúc MHEG-5 45 3.2.1.2 MHEG-5 mở rộng 49 3.2.2 MHP 51 3.2.2.1 Tổng quan hệ thống MHP 52 3.2.2.2 Kiến trúc phần mềm MHP 53 3.2.2.3 Các Java Xlet 56 3.2.2.4 Các ứng dụng MHP 57 Chương 4: Mô hệ thống middleware để dò kênh hiển thị lịch chương trình cho DVB-T 60 4.1 Phân tích yêu cầu hệ thống 60 4.1.1 Khối thông tin dịch vụ (SI) 61 4.1.2 Khối hiển thị lịch phát sóng chương trình (EPG) 62 4.1.3 Khối điều khiển dò kênh (Tuning Control) 62 4.1.4 Khối tổng hợp trung chuyển thông tin (Table Server) 63 4.1.5 Khối quản lý danh sách chương trình (Service List Management) 63 4.2 Thiết kế hệ thống 63 4.2.1 Lớp ứng dụng 65 4.2.1.1 Khối thông tin dịch vụ SI 65 4.2.1.2 Khối hiển thị lịch phát sóng EPG 69 4.2.2 Lớp trung gian Middleware 73 4.3 Kết mô hệ thống 80 KẾT LUẬN 84 TÀI LIỆU THAM KHẢO 85 PHỤ LỤC 87 iii DANH MỤC CÁC KÝ HIỆU VÀ CÁC CHỮ VIẾT TẮT Ký hiệu Cách viết đầy đủ AM Application Module API Application Ý nghĩa Khối ứng dụng Programing Giao diện chương trình ứng dụng Interface COFDM Code Orthogonal Frequency Ghép kênh theo tần số mã trực giao Division Multiplexing DD_SF Device Driver_Section Filter Bộ lọc thông tin lớp điều khiển phần cứng DD_TN Device Driver_Tuner Bộ dò kênh lớp điều khiển phần cứng DTV Digital Television Truyền hình kỹ thuật số DVB Digital Video Broadcasting Chuẩn phát sóng truyền hình số DVB-T Digitao Video Broadcasting – Chuẩn phát sóng truyền hình số EPG Terrestrial mặt đất Electronic Program Guide Lịch phát sóng chương trình truyền hình kỹ thuật số ES Elementary Stream Luồng liệu sở ETSI European Viện chuẩn hóa viễn thông Châu Telecommunications Âu Standards Institute FFT Fast Fourier Transform Biến đổi Fourier nhanh FM Frequency Modulation Điều tần HDTV High-Definition Television Truyền hình độ nét cao IEC International Electrotechnical Ủy ban kỹ thuật Điện Quốc tế Commission IF Intermediate Frequency Trung tần iv Ký hiệu MPTS Cách viết đầy đủ Multi Program Ý nghĩa Transport Dòng truyền tải đa chương trình Stream PCR Presentation Clock Reference Tham chiếu đồng hồ trình chiếu PES Packetized Elementary Stream Luồng sở đóng gói PID Packet Identifier Mã nhận dạng gói PS Program Stream Dòng chương trình PSI Program Specific Information Thông tin mô tả chương trình PSK Phase-Shift Key Khóa dịch pha RAM Random Access Memory Bộ nhớ truy nhập ngẫu nhiên RF Radio Frequency Tần số sóng vô tuyến SDL Simple DirectMedia Layer Thư viện lập trình giao diện SDTV Standard-Definition Truyền hình độ nét chuẩn Television SI Service Information Thông tin dịc vụ STB Set-Top-Box Bộ giải mã tín hiệu truyền hình số TS Transport Stream Dòng truyền tải TSP Transport Stream Packet Gói liệu dòng truyền tải VLSI Very Large Scale Integration Vi mạch tích hợp mật độ cao VOD Video On Demand Truyền hình theo yêu cầu v DANH MỤC CÁC BẢNG Bảng 1.1: Tần số lấy mẫu tín hiệu Video Bảng 1.2: Tỉ lệ lấy mẫu tín hiệu chói tín hiệu màu Bảng 1.3: Hiệu suất nén tiêu chuẩn DVB 25 Bảng 2.1: Các giá trị số PID 31 vi DANH MỤC CÁC HÌNH VẼ Hình 1.1: Vị trí điểm lấy mẫu theo hai tiêu chuẩn 4:2:2 4:2:0 Hình 1.2: Cấu trúc lấy mẫu quincux mành Hình 1.3: Cấu trúc lấy mẫu quincux dòng Hình 1.4: Quá trình chuyển đổi công nghệ từ truyền hình tương tự sang truyền hình số Hình 1.5: Sơ đồ khối hệ thống truyền hình số Hình 1.6: Sơ đồ khối hộp STB 12 Hình 1.7: Sơ đồ khối phần phát hệ thống DSS 15 Hình 1.8: Sơ đồ khối máy thu (phần xử lý tín hiệu) 16 Hình 1.9: Khung liệu VSB 20 Hình 1.10: Sơ đồ khối máy phát VSB 21 Hình 1.11: Sơ đồ khối máy thu VSB 22 Hình 1.12: Các dạng thức truyền dẫn DVB điển hình 23 Hình 2.1: Cấu trúc gói liệu 26 Hình 2.2: Hệ thống truyền tải MPEG-2 27 Hình 2.3: Cấu trúc gói PES 28 Hình 2.4: Định dạng dòng chương trình dòng truyền tải từ dòng đóng gói PES 29 Hình 2.5: Cấu trúc gói truyền tải (Transport stream packet _TS) tiêu chuẩn MPEG-2 30 Hình 2.6: Định dạng dòng truyền tải MPEG-2 32 Hình 2.7: Dòng truyền tải đa chương trình 36 Hình 2.8: Mối quan hệ bảng PSI 38 Hình 2.9: Thông tin đồng hồ hệ thống PCR 40 Hình 2.10: Cú pháp dòng bít MPEG-2 41 Hình 2.11: Sự đồng hoá thu phát 42 Hình 3.1: Minh họa kiến trúc ứng dụng khởi tạo MHEG-5 điển hình 47 Hình 3.2: Kiến trúc phần mềm MHEG-5 điển hình 49 Hình 3.3: Kiến trúc phần mềm MHEG-6 điển hình 50 Hình 3.4: Kiến trúc chung hệ thống phần cứng STB có hỗ trợ MHP 52 Hình 3.5: Các thành phần phần mềm điển hình cho STB có hỗ trợ MHP 53 Hình 3.6: Sơ đồ mô tả vòng đời Xlet 57 Hình 3.7: Các dịch vụ MHP 58 Hình 4.1: Sơ đồ tổng quan hệ thống 61 Hình 4.2: Sơ đồ tổng quan hệ thống Global DTV Middleware 64 Hình 4.3: Quá trình xử lý yêu cầu dò kênh tự động 66 Hình 4.4: Quá trình xử lý yêu cầu dò kênh tay 67 Hình 4.5: Sơ đồ thể trình xử lý khối EPG 70 vii Hình 4.6: Sơ đồ xử lý yêu cầu dò kênh tự động khối Tuning Control 74 Hình 4.7: Sơ đồ xử lý yêu cầu dò kênh tay khối Tuning Control 75 Hình 4.8: Hệ thống chế độ xem TV thông thường 81 Hình 4.9: Màn hình người dùng chọn chức SI 81 Hình 4.10: Quá trình dò kênh tự động 82 Hình 4.11: Nhập tần số để dò kênh tay 82 Hình 4.12: Quá trình dò kênh tay 83 Hình 4.13: Khối EPG hiển thị lịch phát sóng chương trình 83 viii PHẦN MỞ ĐẦU Hệ thống truyền hình số ngày phổ biến việc nghiên cứu giải pháp để nâng cao chất lượng dịch vụ cần thiết Đặc biệt thời đại công nghệ phát triển với tốc độ cao nay, đồng thời đời sống người dân ngày nâng lên nhu cầu thưởng thức chương trình truyền hình ngày phong phú Nội dung truyền hình đơn truyền thống chưa đủ sức đáp ứng nhu cầu người xem Vì ứng dụng truyền hình đời phát triển vô mạnh mẽ mua sắm trực tuyến, gửi mail, bầu chọn trực tuyến, trò chơi điện tử, xem video theo yêu cầu, thông tin thời tiết, tỷ giá,… Để đáp ứng nhu cầu phát triển đó, đầu thu kỹ thuật số không đơn giản giải mã hiển thị nội dung video, audio Thêm vào đó, đầu thu phải đảm bảo cung cấp chương trình ứng dụng hay có khả giải mã chạy ứng dụng phát sóng chương trình truyền hình Trong phát triển công nghệ làm tảng phần cứng nâng cấp thay đổi Để tránh ảnh hưởng tới chương trình ứng dụng lớp trên, lớp phần mềm trung gian kết nối yêu cầu, theo lớp ứng dụng tách khỏi liên kết với lớp phần cứng bên phát triển độc lập Lớp phần mềm trung gian giải pháp Middleware cho hệ thống truyền hình số Sự đời giải pháp Middleware không giúp chương trình ứng dụng phát triển độc lập với thay đổi lớp phần cứng bên mà cung cấp khả xử lý tốt cho đầu thu kỹ thuật số, thúc đẩy chương trình ứng dụng phát triển phong phú mạnh mẽ, đáp ứng nhu cầu người dùng Trong luận văn em xin trình bày trình nghiên cứu hệ thống truyền hình số, giải pháp Middleware từ mô giải pháp Middeware cho hệ thống truyền hình số mặt đất DVB-T Luận văn trình bày chia làm bốn chương: ¾ Chương 1: Tổng quan hệ thống truyền hình số ¾ Chương 2: Phương pháp đóng gói truyền tải tín hiệu Video-Audio theo tiêu chuẩn MPEG-2 ix printf("%s %d\n","Original Network ID",msg.usONID); printf("%s %d\n","Transport Stream ID",msg.usTSID); printf("%s %d\n","Service ID",msg.usSVID); printf("%s %s\n","Service Name",msg.aoSvcName); printf("\n"); } else printf("\nTuning .\n\n"); } void *AL_SI_Run(void* data) { Data_to_si *inputdata; int freq; inputdata = (Data_to_si*)data; freq = inputdata->freq; ER bool_t uint8_t err; bRun = TRUE; oStatus; MSG_TC tyRecvMsg; uint16_t usChannel_num = 0; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); AL_SI_SendMsgInit(freq); //send Req if (freq == 0) { while(bRun) { err = AL_AM_ReceiveTCResMsg(&tyRecvMsg); if(err != E_OK) { AL_AM_Print("AL_SI_Run: Can not receive Res Msg from TC\n"); AL_SI_Exit(); break; } if (tyRecvMsg.tyMsgHeader.usMsgType == MSG_TYPE_TC_SetupAutoScanStartRes) oStatus = tyRecvMsg.tyMsg.tyTcSetupAutoScanStartRes.oStatus; else continue; switch(oStatus) { case MW_TC_AM_RES_PROGRESS: if(tyRecvMsg.tyMsg.tyTcSetupAutoScanStartRes.usONID+tyRecvMsg.tyMsg.tyTcSetupAutoScanStartRes.usTSID == 0){ if(tyRecvMsg.tyMsg.tyTcSetupAutoScanStartRes.ulFreq usONID + pSlmInfo->usTSID + pSlmInfo->usSvcID + pSlmInfo->usNWID) == 0){ return E_FATAL; } } //if this lcn is stored in slm -> get schedule of this service pData = (EPG_sche_info_t*) malloc (sizeof(EPG_sche_info_t)); if(pData == NULL) { printf("Out of memory in AL_AM_EPG_DataGet function\n"); return E_NOMEM; } pData->lcn = pSlmInfo->usLCN; pData->channel_name = (char*) malloc ((ServiceName_len+1)*sizeof(char)); strcpy(pData->channel_name,(char*)pSlmInfo->poSvcName); pData->channel_name[ServiceName_len] = '\0'; pData->event_num = 0; pData->event_info = NULL; //only get schedule of service stored in slm 90 err = SLM_API_get_current_channel(&cur_chanel); //printf("Current Channel = %d\n",cur_chanel); //sleep(3); pCurChanelSlmInfo = (SLM_sv_info_t*)malloc(sizeof(SLM_sv_info_t)); err = SLM_API_get_sv(cur_chanel, pCurChanelSlmInfo); if(pCurChanelSlmInfo->usTSID == pSlmInfo->usTSID) { otype = TS_ACTUAL; //printf("TS_ACTUAL\n"); ustable_id_first = TABLE_ID_EIT_A_START; ustable_id_last = TABLE_ID_EIT_A_STOP; } else { otype = TS_OTHER; //printf("TS_OTHER\n"); ustable_id_first = TABLE_ID_EIT_O_START; ustable_id_last = TABLE_ID_EIT_O_STOP; } for(i=ustable_id_first; iolast_table_id) break; //AL_AM_TC_Send_SvcEventInfoStartReq(pSlmInfo->usONID, pSlmInfo->usTSID, pSlmInfo->usSvcID, i, osection_no); err = TS_API_EitDataGet(pSlmInfo->usONID, pSlmInfo->usTSID, i, pSlmInfo->usSvcID, otype, &pTempEitSche); if(err == E_OK){ olast_table_id = pTempEitSche->oLastTableID; pTempEitInfo = pTempEitSche->ptyEit_info; //printf("pTempEitInfo->oEvent_num = %d\n",pTempEitInfo->oEvent_num); for(j=0; j oEvent_num; j++) //all events in a section of a table id { if((pTempEitInfo->ptyEvent_info->ptyDesc_info == NULL)||(pTempEitInfo>ptyEvent_info->oDesc_num==0)) { (pTempEitInfo->ptyEvent_info)++; continue; } for(des_cnt=0; des_cntptyEvent_info->oDesc_num; des_cnt++){ if(pTempEitInfo->ptyEvent_info->ptyDesc_info->otag != EIT_SHORT_DES_TAG){ pTempEitInfo->ptyEvent_info->ptyDesc_info++; continue; } //40 bits of Start time includes 16 bits of date and 24 bits of time in MJD standard ullOriginTime = (pTempEitInfo->ptyEvent_info->ullStartTime)&0xFFFFFF; //24 bits of Start Time in BCD format ullOriginDate = ((pTempEitInfo->ptyEvent_info>ullStartTime)>>24)&0xFFFF;//16 bits of Start Date in MJD standard if(ullOriginDate != MJD_in){ pTempEitInfo->ptyEvent_info->ptyDesc_info++; continue; } event_num ++; if (event_num == 1) pEventList = (EPG_event_info_t*) malloc(sizeof(EPG_event_info_t)); else pEventList = (EPG_event_info_t*) realloc(pEventList, event_num * sizeof(EPG_event_info_t)); ptempEVENT = pEventList + event_num - 1; //Call api to decode descriptor in this pointer: (pTempEitInfo->ptyEvent_info>ptyDesc_info->podata) err = TS_API_DescShortEventDataGet(pTempEitInfo->ptyEvent_info>ptyDesc_info->olength, pTempEitInfo->ptyEvent_info->ptyDesc_info->podata, &pTempEitShortDes); if (err == E_OK) { 91 ptempEVENT->event_name_num = 0; memcpy(ptempEVENT->event_name,(char*)pTempEitShortDes>poEventName_char,pTempEitShortDes->oEventName_len); ptempEVENT->event_name[pTempEitShortDes->oEventName_len] = '\0'; TS_API_DescShortEventDataFree(pTempEitShortDes); } else{ strcpy(ptempEVENT->event_name,""); } pTempEitInfo->ptyEvent_info->ptyDesc_info->olength = 0; //To find Y, M, D from MJD Y = (int)((ullOriginDate - 15078.2) / 365.25); M = (int)((ullOriginDate - 14956.1 - (int)(Y*365.25))/30.6001); D = ullOriginDate - 14956 - (int)(Y * 365.25) - (int)(M * 30.6001); if ((M==14)||(M==15)) K = 1; else K = 0; Y = Y + K + 1900; M = M - - (K * 12); (ptempEVENT->start_date).yy = (uint16_t)Y; (ptempEVENT->start_date).mm = (uint8_t)M; (ptempEVENT->start_date).dd = (uint8_t)D; (ptempEVENT->start_time).ss = (uint8_t)(((ullOriginTime&0xF0)>>4)*10 + (ullOriginTime&0x0F)); ullOriginTime = (ullOriginTime)>>8; (ptempEVENT->start_time).mm = (uint8_t)(((ullOriginTime&0xF0)>>4)*10 + (ullOriginTime&0x0F)); ullOriginTime = (ullOriginTime)>>8; (ptempEVENT->start_time).hh = (uint8_t)(((ullOriginTime&0xF0)>>4)*10 + (ullOriginTime&0x0F)); ullOriginTime = (ullOriginTime)>>8; ulOriginDuration = pTempEitInfo->ptyEvent_info->ulDuration; //24 bits of Duration in BCD format (ptempEVENT->duration).ss = (uint8_t)(((ulOriginDuration&0xF0)>>4)*10 + (ulOriginDuration&0x0F)); ulOriginDuration = (ulOriginDuration)>>8; (ptempEVENT->duration).mm = (uint8_t)(((ulOriginDuration&0xF0)>>4)*10 + (ulOriginDuration&0x0F)); ulOriginDuration = (ulOriginDuration)>>8; (ptempEVENT->duration).hh = (uint8_t)(((ulOriginDuration&0xF0)>>4)*10 + (ulOriginDuration&0x0F)); pTempEitInfo->ptyEvent_info->ptyDesc_info++; }//end of loop des_cnt (pTempEitInfo->ptyEvent_info)++; }//end of event loop } //TS_API_EitDataFree(pTempEitSche); //printf("event_num of table %x = %d\n",i, event_num); } /* end of for table loop*/ //printf("event_num of all table of service_id %d = %d\n",pSlmInfo->usSvcID, event_num); //AL_AM_TC_Send_SvcEventInfoStopReq(pSlmInfo->usONID, pSlmInfo->usTSID, pSlmInfo->usSvcID, ustable_id_first, 0); //printf("Sent stop req\n"); if (event_num > 0) { pData->event_num = event_num; pData->event_info = pEventList; } *ppData = pData; if(pSlmInfo != NULL) free(pSlmInfo); return E_OK; } /************************************************************************ 92 Send messages to TC to request Delete all table in SDT & EIT tables - Input: lcn: Logical Chanel - Output: ppData: broadcast schedule information corresponding to lcn input ************************************************************************/ ER AL_AM_EPG_DeleteTable(uint16_t usLcn) { int err; //uint8_t osection_no = 0; //first section number uint8_t otype ; //is TS_ACTUAL or TS_OTHER uint16_t cur_chanel; SLM_sv_info_t* pSlmInfo = NULL; SLM_sv_info_t* pCurChanelSlmInfo = NULL; uint16_t ustable_id_first; uint16_t ustable_id_last; //Get service information from service list pSlmInfo = (SLM_sv_info_t*)malloc(sizeof(SLM_sv_info_t)); err = SLM_API_get_sv(usLcn, pSlmInfo); //If lcn input is wrong or user did not store in slm if(err == E_INVAL){ printf(" Logical Number Input is not valid\n"); return E_INVAL; } else{ if((pSlmInfo->usONID + pSlmInfo->usTSID + pSlmInfo->usSvcID + pSlmInfo->usNWID) == 0){ return E_FATAL; } } //only get schedule of service stored in slm err = SLM_API_get_current_channel(&cur_chanel); //printf("Current Channel = %d\n",cur_chanel); //sleep(3); pCurChanelSlmInfo = (SLM_sv_info_t*)malloc(sizeof(SLM_sv_info_t)); err = SLM_API_get_sv(cur_chanel, pCurChanelSlmInfo); if(pCurChanelSlmInfo->usTSID == pSlmInfo->usTSID) { otype = TS_ACTUAL; //printf("TS_ACTUAL\n"); ustable_id_first = TABLE_ID_EIT_A_START; ustable_id_last = TABLE_ID_EIT_A_STOP; } else { otype = TS_OTHER; //printf("TS_OTHER\n"); ustable_id_first = TABLE_ID_EIT_O_START; ustable_id_last = TABLE_ID_EIT_O_STOP; } //printf("ustable_id_first = %x\n",ustable_id_first); AL_AM_TC_Send_SvcEventInfoStopReq(pSlmInfo->usONID, pSlmInfo->usTSID, pSlmInfo->usSvcID, ustable_id_first, 0); if(pSlmInfo != NULL) free(pSlmInfo); return E_OK; } /************************************************************************ Send messages to TC to request all table in SDT & EIT tables - Input: lcn: Logical Chanel - Output: ppData: broadcast schedule information corresponding to lcn input ************************************************************************/ ER AL_AM_EPG_ReqTable(uint16_t usLcn) { int err; 93 //uint8_t osection_no = 0; //first section number uint8_t otype ; //is TS_ACTUAL or TS_OTHER uint16_t cur_chanel; SLM_sv_info_t* pSlmInfo = NULL; SLM_sv_info_t* pCurChanelSlmInfo = NULL; uint16_t ustable_id_first; uint16_t ustable_id_last; //Get service information from service list pSlmInfo = (SLM_sv_info_t*)malloc(sizeof(SLM_sv_info_t)); err = SLM_API_get_sv(usLcn, pSlmInfo); //If lcn input is wrong or user did not store in slm if(err == E_INVAL){ printf(" Logical Number Input is not valid\n"); return E_INVAL; } else{ if((pSlmInfo->usONID + pSlmInfo->usTSID + pSlmInfo->usSvcID + pSlmInfo->usNWID) == 0){ return E_FATAL; } } //only get schedule of service stored in slm err = SLM_API_get_current_channel(&cur_chanel); //printf("Current Channel = %d\n",cur_chanel); //sleep(3); pCurChanelSlmInfo = (SLM_sv_info_t*)malloc(sizeof(SLM_sv_info_t)); err = SLM_API_get_sv(cur_chanel, pCurChanelSlmInfo); if(pCurChanelSlmInfo->usTSID == pSlmInfo->usTSID) { otype = TS_ACTUAL; //printf("TS_ACTUAL\n"); ustable_id_first = TABLE_ID_EIT_A_START; ustable_id_last = TABLE_ID_EIT_A_STOP; } else { otype = TS_OTHER; //printf("TS_OTHER\n"); ustable_id_first = TABLE_ID_EIT_O_START; ustable_id_last = TABLE_ID_EIT_O_STOP; } //printf("ustable_id_first = %x\n",ustable_id_first); AL_AM_TC_Send_SvcEventInfoStartReq(pSlmInfo->usONID, pSlmInfo->usTSID, pSlmInfo->usSvcID, ustable_id_first, 0); if(pSlmInfo != NULL) free(pSlmInfo); return E_OK; } /********************************************************************* *Display schedule of one service - Input: pData: a pointer of EPG_sche_info_t struct ( schedule information) - Output: *********************************************************************/ ER AL_AM_EPG_DataDisplay(EPG_sche_info_t* pData, int timeout, int last_epg_next_screen_index) { int i = 0; int j = 0; int k = 0; int name_len_view = 49; char s1[EVENT_NAME_LEN_MAX],s2[EVENT_NAME_LEN_MAX]; int event_index=0; int page_num=0; /* printf("In display epg_next_screen_index = %d\n",epg_next_screen_index); printf("In display last_epg_next_screen_index = %d\n",last_epg_next_screen_index); 94 */ if(epg_next_screen_index < 0) epg_next_screen_index = last_epg_next_screen_index; event_index = epg_next_screen_index*FRAME_EVENT_NUM; if(pData == NULL){ printf("You have input NULL pointer to AL_AM_EPG_DataDisplay() function\n"); return E_INVAL; } printf("%c[1;%dm",27,Blue); if(pData->event_num>0){ if((pData->event_num%FRAME_EVENT_NUM) != 0) page_num = (pData>event_num/FRAME_EVENT_NUM)+1; else page_num = (pData->event_num/FRAME_EVENT_NUM); printf("Page: %d/%d\n",epg_next_screen_index+1,page_num); } else printf("Page: 1/1\n"); printf(" \n"); printf("|EvNo|LgCN| Channel name | Date | Event name |StartTime|Duration|\n"); printf("+ + + + + -+ -+ +\n"); printf("%c[1;%dm",27,Normal); //printf("pData->event_num = %d\n",pData->event_num); if(pData->event_num>0){ EPG_event_info_t *tmp; tmp = pData->event_info; tmp += event_index; //for(i=0;ievent_num; i++){ printf("%c[1;%dm",27,Blue); for(i=event_index;ievent_num) { epg_next_screen_index = -1; tmp = pData->event_info; break; } if(ievent_num-1)&&(i == event_index+FRAME_EVENT_NUM-1)){ epg_next_screen_index = -1; tmp = pData->event_info; } printf("+ + + + + -+ -+ -+\n"); // printf("|%4d", i+1); printf("|%4d", pData->lcn); printf("|%18s", pData->channel_name); if(tmp[i] != NULL){ printf("|%2d/%2d/%4d", (tmp->start_date).dd, (tmp->start_date).mm, (tmp- >start_date).yy); if(strlen(tmp->event_name)event_name); } else{ strcpy(s2,tmp->event_name); while(strlen(s2)>name_len_view){ memcpy(s1,s2,name_len_view); s1[name_len_view] = '\0'; if(s2[name_len_view] != ' '){ k = 0; while(s1[name_len_view-(k+1)] != ' ') k++; s1[name_len_view-(k+1)]= '\0'; } printf("|%49s| | |\n",s1); for(j = name_len_view-k;jname_len_view) printf("| | |"); } printf("| | | |%49s",s2); } 95 printf("|%2d:%2d:%2d ", (tmp->start_time).hh, (tmp->start_time).mm, (tmp>start_time).ss); // printf("|%2d:%2d:%2d|\n", (tmp->duration).hh, (tmp->duration).mm, (tmp->duration).ss); } printf("+ + + + + -+ -+ +\n"); tmp++; } printf("%c[1;%dm",27,Normal); if((i == pData->event_num)&&(timeout < DECODE_TIMEOUT)){ printf("%c[1;%dmUpdating Data %c[1;%dm\n",27,Blue,27,Normal); epg_next_screen_index = -1; } printf("\n********************************************************************************************* ******\n"); } else{ epg_next_screen_index = -1; if(timeout < DECODE_TIMEOUT){ printf("%c[1;%dmReceiving Data %c[1;%dm\n",27,Blue,27,Normal); } else{ printf("%c[1;%dm",27,Blue); printf("+ + + + + -+ -+ -+\n"); printf("|%4d", 0); printf("|%4d", pData->lcn); printf("|%18s", pData->channel_name); printf("|%10s",""); printf("|%49s","No broadcast schedule information"); printf("|%9s",""); printf("|%8s|\n",""); printf("+ + + + + -+ -+ -+\n"); printf("%c[1;%dm",27,Normal); } } return E_OK; } /********************************************************************* Free schedule of one service - Input: pData: a pointer of EPG_sche_info_t struct ( schedule information) - Output: *********************************************************************/ ER AL_AM_EPG_DataFree(EPG_sche_info_t* pData) { if(pData == NULL) return E_OK; free(pData->event_info); pData->event_num = 0; free(pData->channel_name); free(pData); return E_OK; } /********************************************************************* Start EPG module - Input: - Output: *********************************************************************/ void *AL_AM_EPG_Start(void *data) { ER err; int last_epg_screen_refresh_index = 0; int decode_time = 0; int last_event_num = 0; last_epg_next_screen_index=0; decode_timeout=0; 96 /* printf("chosen service = %d\n",((Data_to_epg*)data)->lcn); printf("MJD_TDT = %x\n",((Data_to_epg*)data)->MJD_TDT); printf("offset_day = %d\n",((Data_to_epg*)data)->offset_day); */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); if(epg_next_screen_index == -3){ AL_AM_EPG_DeleteTable(((Data_to_epg*)data)->lcn); return NULL; } if(((Data_to_epg*)data)->offset_day >= 0){ //Send message to TC to request tables AL_AM_EPG_ReqTable(((Data_to_epg*)data)->lcn); //sleep(1); err = AL_AM_EPG_DataGet(((Data_to_epg*)data)->lcn, ((Data_to_epg*)data)->MJD_TDT + ((Data_to_epg*)data)->offset_day, &pSchedule1service); if(err == E_OK) { if(pSchedule1service != NULL){ if(pSchedule1service->event_num > last_event_num){ last_event_num = pSchedule1service->event_num; } } AL_AM_EPG_DataDisplay(pSchedule1service,decode_timeout,last_epg_next_screen_index); if(epg_next_screen_index>0) last_epg_next_screen_index = epg_next_screen_index; last_epg_screen_refresh_index = epg_screen_refresh_index; while(1){ if(epg_next_screen_index == -3){ AL_AM_EPG_DeleteTable(((Data_to_epg*)data)->lcn); break; } if(epg_screen_refresh_index != last_epg_screen_refresh_index){ last_epg_screen_refresh_index = epg_screen_refresh_index; //printf("When moving arrow is pressed\n"); AL_AM_EPG_DataDisplay(pSchedule1service,decode_timeout,last_epg_next_screen_index); } if((epg_next_screen_index != last_epg_next_screen_index)&&(epg_next_screen_index>=0)){ last_epg_next_screen_index = epg_next_screen_index; AL_AM_EPG_DataDisplay(pSchedule1service,decode_timeout,last_epg_next_screen_index); } else{ //printf("No change in EPG screen\n"); usleep(10000);//sleep 0.01 second decode_time++; } if(decode_time == 100){ /*delay 1second*/ decode_time = 0; decode_timeout++; AL_AM_EPG_DataFree(pSchedule1service); err = AL_AM_EPG_DataGet(((Data_to_epg*)data)->lcn, ((Data_to_epg*)data)>MJD_TDT + ((Data_to_epg*)data)->offset_day, &pSchedule1service); if(pSchedule1service != NULL){ if((pSchedule1service->event_num > last_event_num)||(decode_timeout == DECODE_TIMEOUT)){ last_event_num = pSchedule1service->event_num; if(epg_next_screen_index == -1){ epg_next_screen_index = last_epg_next_screen_index; system("clear"); printf("When Time out or udate\n"); AL_AM_EPG_DataDisplay(pSchedule1service,decode_timeout,last_epg_next_screen_index); } } } } } 97 AL_AM_EPG_DataFree(pSchedule1service); } } else{ printf("\n"); printf("%c[1;%dm",27,Blue); printf(" \n"); printf("|EvNo|LgCN| Channel name | Date | Event name |StartTime|Duration|\n"); printf("+ + + + + -+ -+ +\n"); printf("+ + + + + -+ -+ +\n"); printf("|%4d", 0); printf("|%4d", ((Data_to_epg*)data)->lcn); printf("|%18s", ""); printf("|%10s",""); printf("|%49s","No broadcast schedule information"); printf("|%9s",""); printf("|%8s|\n",""); printf("+ + + + + -+ -+ +\n"); printf("%c[1;%dm",27,Normal); } return NULL; } Tệp mw_tc_comm.c thực tạo truyền tin giao tiếp khối Tuning Control khối khác #include /* * File name mw_tc_comm.c * * Revision history * date Revised by: * 2010.08.25 Q.Trieu */ Reasons New #include #include #include #include "mp_pf.h" #include "mw_tc_sock.h" #include "mw_tc_comm.h" #include "mw_tc_msg.h" // -// Function name MW_TC_COMM_SetHeader // Argument MSG_TC *tyMsg // uint16_t usLength // // Return value void // -void MW_TC_COMM_SetHeader(MSG_TC *tyMsg, uint16_t usMsgType, uint16_t usLength) { tyMsg->tyMsgHeader.oSender = MODULE_TC; tyMsg->tyMsgHeader.oReceiver = MODULE_AM; tyMsg->tyMsgHeader.usMsgType = usMsgType; tyMsg->tyMsgHeader.usLength = usLength; } /********************************************************************* * Function name MW_TC_COMM_Send_SetupAutoScanStartRes * Argument uint16_t usprogno, uint32_t ulfreq, uint16_t usONID, uint16_t usTSID, uint16_t usSVID, uint16_t ussn_len, 98 uint8_t uint8_t osname, ostatus, * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SetupAutoScanStartRes(uint16_t usProgNo, uint32_t ulFreq, uint16_t usONID, uint16_t usTSID, uint16_t usSVID, uint16_t usSvcName_len, uint8_t* poSvcName, uint8_t oStatus) { MSG_TC tySendMsg; MSG_TC_SetupAutoScanStartRes *ptyRes = &tySendMsg.tyMsg.tyTcSetupAutoScanStartRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SetupAutoScanStartRes, sizeof(*ptyRes)); ptyRes->usProgNo= usProgNo; ptyRes->ulFreq = ulFreq; ptyRes->usONID = usONID; ptyRes->usTSID = usTSID; ptyRes->usSVID = usSVID; ptyRes->usSvcName_len = usSvcName_len; strcpy((char*)ptyRes->aoSvcName, (char*)poSvcName); ptyRes->oStatus = oStatus; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SetupAutoScanStopRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SetupAutoScanStopRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SetupAutoScanStopRes *ptyRes = &tySendMsg.tyMsg.tyTcSetupAutoScanStopRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SetupAutoScanStopRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SetupAutoScanStoreRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SetupAutoScanStoreRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SetupAutoScanStoreRes *ptyRes = &tySendMsg.tyMsg.tyTcSetupAutoScanStoreRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SetupAutoScanStoreRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SetupManualScanStartRes * Argument uint32_t ulfreq, uint16_t usONID, uint16_t usTSID, uint16_t usSVID, uint16_t ussn_len, uint8_t osname, uint8_t ostatus, * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SetupManualScanStartRes(uint32_t ulFreq, uint16_t usONID, uint16_t usTSID, uint16_t usSVID, uint16_t usSvcName_len, uint8_t* poSvcName, uint8_t oStatus) { MSG_TC tySendMsg; MSG_TC_SetupManualScanStartRes *ptyRes = &tySendMsg.tyMsg.tyTcSetupManualScanStartRes; 99 MW_TC_COMM_SetHeader( &tySendMsg, MSG_TYPE_TC_SetupManualScanStartRes, sizeof(*ptyRes)); ptyRes->ulFreq = ulFreq; ptyRes->usONID = usONID; ptyRes->usTSID = usTSID; ptyRes->usSVID = usSVID; ptyRes->usSvcName_len = usSvcName_len; strcpy((char*)ptyRes->aoSvcName, (char*) poSvcName); ptyRes->oStatus = oStatus; return (MW_TC_SOCK_SendAmResMsg(&tySendMsg)); } /********************************************************************* * Function name MW_TC_COMM_Send_SetupManualScanStoreRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SetupManualScanStoreRes(int8_t oResult) { MSG_TC MSG_TC_SetupManualScanStoreRes tySendMsg; *ptyRes = &tySendMsg.tyMsg.tyTcSetupManualScanStoreRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SetupManualScanStoreRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcChannelUpRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcChannelUpRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcChannelUpRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcChannelUpRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcChannelUpRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcChannelDownRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcChannelDownRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcChannelDownRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcChannelDownRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcChannelDownRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcChannelSetRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcChannelSetRes(int8_t oResult) { 100 MSG_TC MSG_TC_SvcChannelSetRes tySendMsg; *ptyRes = &tySendMsg.tyMsg.tyTcSvcChannelSetRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcChannelSetRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcNetworkInfoStartRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcNetworkInfoStartRes(int8_t oResult) { MSG_TC MSG_TC_SvcNetworkInfoStartRes tySendMsg; *ptyRes = &tySendMsg.tyMsg.tyTcSvcNetworkInfoStartRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcNetworkInfoStartRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcNetworkInfoStopRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcNetworkInfoStopRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcNetworkInfoStopRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcNetworkInfoStopRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcNetworkInfoStopRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_TimeDateInfoStartRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_TimeDateInfoStartRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_TimeDateInfoStartRes *ptyRes = &tySendMsg.tyMsg.tyTcTimeDateInfoStartRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_TimeDateInfoStartRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_TimeDateInfoStopRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_TimeDateInfoStopRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_TimeDateInfoStopRes *ptyRes = &tySendMsg.tyMsg.tyTcTimeDateInfoStopRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_TimeDateInfoStopRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } 101 /********************************************************************* * Function name MW_TC_COMM_Send_SvcServiceInfoStartRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcServiceInfoStartRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcServiceInfoStartRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcServiceInfoStartRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcServiceInfoStartRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcServiceInfoStopRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcServiceInfoStopRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcServiceInfoStopRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcServiceInfoStopRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcServiceInfoStopRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcEventInfoStartRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcEventInfoStartRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcEventInfoStartRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcEventInfoStartRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcEventInfoStartRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } /********************************************************************* * Function name MW_TC_COMM_Send_SvcEventInfoStopRes * Argument uint8_t oResult * Return value int32_t ********************************************************************/ int32_t MW_TC_COMM_Send_SvcEventInfoStopRes(int8_t oResult) { MSG_TC tySendMsg; MSG_TC_SvcEventInfoStopRes *ptyRes = &tySendMsg.tyMsg.tyTcSvcEventInfoStopRes; MW_TC_COMM_SetHeader(&tySendMsg, MSG_TYPE_TC_SvcEventInfoStopRes, sizeof(*ptyRes)); ptyRes->oResult = oResult; return ( MW_TC_SOCK_SendAmResMsg(&tySendMsg) ); } 102 ... dụng dòng truyền tải MPEG-2 39 Chương 3: Giải pháp Middleware cho hệ thống truyền hình số 43 3.1 Khái niệm Middleware 43 3.2 Giải pháp Middleware cho hệ thống truyền hình số 44... MPEG-2 ix ¾ Chương 3: Giải pháp Middleware cho hệ thống truyền hình số ¾ Chương 4: Mô hệ thống middleware để dò kênh hiển thị lịch chương trình cho hệ thống truyền hình số DVB-T Với bốn chương,... chuyển đổi số - tương tự Hình 1.5: Sơ đồ khối hệ thống truyền hình số 1.2.3 Thu, phát truyền dẫn tín hiệu truyền hình số 1.2.3.1 Truyễn dẫn tín hiệu truyền hình số Việc sử dụng kỹ thuật số để truyền