static void i80286_data_descriptor_full(i80286_state *cpustate, int reg, UINT16 selector, int cpl, UINT32 trap, UINT16 offset, int size) { if (PM) { UINT16 desc[3]; UINT8 r; UINT32 addr; /* selector format 15..3 number/address in descriptor table 2: 0 global, 1 local descriptor table 1,0: requested privileg level must be higher or same as current privileg level in code selector */ if ((reg != SS) && !IDXTBL(selector)) { cpustate->sregs[reg]=0; cpustate->limit[reg]=0; cpustate->base[reg]=0; cpustate->rights[reg]=0; cpustate->valid[reg]=0; return; } if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw trap; desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (!SEGDESC(r)) throw trap; if (reg == SS) { if (!IDXTBL(selector)) throw trap; if (DPL(r)!=cpl) throw trap; if (RPL(selector)!=cpl) throw trap; if (!RW(r) || CODE(r)) throw trap; if (!PRES(r)) throw TRAP(STACK_FAULT,(IDXTBL(selector)+(trap&1))); } else { if ((DPL(r) < PMAX(cpl,RPL(selector))) && (!CODE(r) || (CODE(r) && !CONF(r)))) throw trap; if (CODE(r) && !READ(r)) throw trap; if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,(IDXTBL(selector)+(trap&1))); } if (offset+size) { if ((CODE(r) || !EXPDOWN(r)) && ((offset+size-1) > LIMIT(desc))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap; if (!CODE(r) && EXPDOWN(r) && ((offset <= LIMIT(desc)) || ((offset+size-1) > 0xffff))) throw (reg==SS)?TRAP(STACK_FAULT,(trap&1)):trap; } SET_ACC(desc); WriteWord(addr+4, desc[2]); cpustate->sregs[reg]=selector; cpustate->limit[reg]=LIMIT(desc); cpustate->base[reg]=BASE(desc); cpustate->rights[reg]=RIGHTS(desc); } else { cpustate->sregs[reg]=selector; cpustate->base[reg]=selector<<4; } cpustate->valid[reg]=1; }
static void PREFIX286(_0fpre)(i8086_state *cpustate) { unsigned next = FETCHOP; UINT16 ModRM, desc[3]; UINT16 tmp, msw, sel; UINT8 r; UINT32 addr; switch (next) { case 0: if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM=FETCHOP; switch (ModRM&0x38) { case 0: /* sldt */ PutRMWord(ModRM, cpustate->ldtr.sel); break; case 8: /* str */ PutRMWord(ModRM, cpustate->tr.sel); break; case 0x10: /* lldt */ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0); sel=GetRMWord(ModRM); if (TBL(sel)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (IDXTBL(sel)) { if (IDX(sel)>=cpustate->gdtr.limit) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); addr = cpustate->gdtr.base + IDX(sel); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel)); } else { desc[0] = 0; desc[1] = 0; desc[2] = 0; } cpustate->ldtr.sel=sel; cpustate->ldtr.limit=LIMIT(desc); cpustate->ldtr.base=BASE(desc); cpustate->ldtr.rights=RIGHTS(desc); break; case 0x18: /* ltr */ if (CPL!=0) throw TRAP(GENERAL_PROTECTION_FAULT,0); sel=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,sel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(sel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(sel)); desc[2] |= 0x200; // mark busy WriteWord(addr+4, desc[2]); cpustate->tr.sel=sel; cpustate->tr.limit=LIMIT(desc); cpustate->tr.base=BASE(desc); cpustate->tr.rights=RIGHTS(desc); break; case 0x20: /* verr */ tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_READ, RIGHTS(desc), 0); cpustate->ZeroVal = cpustate->ZeroVal || (CODE(r) && CONF(r) ? 0 : (DPL(r)<PMAX(RPL(tmp),CPL))); } break; case 0x28: /* verw */ tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); cpustate->ZeroVal = i80286_verify(cpustate, tmp, I80286_WRITE, RIGHTS(desc), 0); cpustate->ZeroVal = cpustate->ZeroVal || (DPL(r)<PMAX(RPL(tmp),CPL)); } break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } break; case 1: /* lgdt, lldt in protected mode privilege level 0 required else common protection failure 0xd */ ModRM = FETCHOP; switch (ModRM&0x38) { case 0: /* sgdt */ PutRMWord(ModRM,cpustate->gdtr.limit); PutRMWordOffset(2,cpustate->gdtr.base&0xffff); PutRMWordOffset(4,0xff00|cpustate->gdtr.base>>16); break; case 8: /* sidt */ PutRMWord(ModRM,cpustate->idtr.limit); PutRMWordOffset(2,cpustate->idtr.base&0xffff); PutRMWordOffset(4,0xff00|cpustate->idtr.base>>16); break; case 0x10: /* lgdt */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->gdtr.limit=GetRMWord(ModRM); cpustate->gdtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16); break; case 0x18: /* lidt */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->idtr.limit=GetRMWord(ModRM); cpustate->idtr.base=GetRMWordOffset(2)|(GetRMByteOffset(4)<<16); break; case 0x20: /* smsw */ PutRMWord(ModRM, cpustate->msw); break; case 0x30: /* lmsw */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); msw = GetRMWord(ModRM); if (!PM&&(msw&1)) cpustate->sregs[CS] = IDX(cpustate->sregs[CS]); // cheat and set cpl to 0 cpustate->msw=(cpustate->msw&1)|msw; break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } break; case 2: /* LAR */ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM = FETCHOP; tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (DPL(r)>=PMAX(RPL(tmp),CPL)) { cpustate->ZeroVal = 0; // rights are expected to be in upper byte RegWord(ModRM) = r << 8; } else cpustate->ZeroVal = 1; } break; case 3: /* LSL */ if (!PM) throw TRAP(ILLEGAL_INSTRUCTION,-1); ModRM = FETCHOP; tmp=GetRMWord(ModRM); if ((addr = i80286_selector_address(cpustate,tmp)) == -1) cpustate->ZeroVal = 1; else { desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (!SEGDESC(r) && (GATE(r) >= CALLGATE)) cpustate->ZeroVal = 1; // not valid for gates else if (DPL(r)>=PMAX(RPL(tmp),CPL)) { cpustate->ZeroVal = 0; RegWord(ModRM) = ReadWord(addr); } else cpustate->ZeroVal = 1; } break; case 5: /* loadall */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->msw = (cpustate->msw&1)|ReadWord(0x806); cpustate->tr.sel = ReadWord(0x816); tmp = ReadWord(0x818); ExpandFlags(tmp); cpustate->flags = tmp; cpustate->flags = CompressFlags(); cpustate->pc = ReadWord(0x81a); cpustate->ldtr.sel = ReadWord(0x81c); cpustate->sregs[DS] = ReadWord(0x81e); cpustate->sregs[SS] = ReadWord(0x820); cpustate->sregs[CS] = ReadWord(0x822); cpustate->sregs[ES] = ReadWord(0x824); cpustate->regs.w[DI] = ReadWord(0x826); cpustate->regs.w[SI] = ReadWord(0x828); cpustate->regs.w[BP] = ReadWord(0x82a); cpustate->regs.w[SP] = ReadWord(0x82c); cpustate->regs.w[BX] = ReadWord(0x82e); cpustate->regs.w[DX] = ReadWord(0x830); cpustate->regs.w[CX] = ReadWord(0x832); cpustate->regs.w[AX] = ReadWord(0x834); // loadall uses base-rights-limit order #define LOADDESC(addr, sreg) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \ cpustate->base[sreg] = BASE(desc); cpustate->rights[sreg] = RIGHTS(desc); \ cpustate->limit[sreg] = LIMIT(desc); } LOADDESC(0x836, ES); LOADDESC(0x83C, CS); LOADDESC(0x842, SS); LOADDESC(0x848, DS); #undef LOADDESC // void cast supresses warning #define LOADDESC(addr, reg, r) { desc[1] = ReadWord(addr); desc[2] = ReadWord(addr+2); desc[0] = ReadWord(addr+4); \ cpustate->reg.base = BASE(desc); (void)(r); cpustate->reg.limit = LIMIT(desc); } LOADDESC(0x84e, gdtr, 1); LOADDESC(0x854, ldtr, cpustate->ldtr.rights = RIGHTS(desc)); LOADDESC(0x85a, idtr, 1); LOADDESC(0x860, tr, cpustate->tr.rights = RIGHTS(desc)); #undef LOADDESC cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK; CHANGE_PC(cpustate->pc); break; case 6: /* clts */ if (PM&&(CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0); cpustate->msw&=~8; break; default: throw TRAP(ILLEGAL_INSTRUCTION,-1); break; } }
static void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT16 offset, int gate) { if (PM) { UINT16 desc[3]; UINT8 r; UINT32 addr; /* selector format 15..3 number/address in descriptor table 2: 0 global, 1 local descriptor table 1,0: requested privileg level must be higher or same as current privileg level in code selector */ if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); desc[0] = ReadWord(addr); desc[1] = ReadWord(addr+2); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r)) { if (!CODE(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (CONF(r)) { if(DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); } else if ((RPL(selector)>CPL) || (DPL(r)!=CPL)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(selector)); // this order is important if (offset > LIMIT(desc)) throw TRAP(GENERAL_PROTECTION_FAULT, 0); SET_ACC(desc); WriteWord(addr+4, desc[2]); cpustate->sregs[CS]=IDXTBL(selector) | CPL; cpustate->limit[CS]=LIMIT(desc); cpustate->base[CS]=BASE(desc); cpustate->rights[CS]=RIGHTS(desc); cpustate->pc=cpustate->base[CS]+offset; } else { // systemdescriptor UINT16 gatedesc[3]={0,0,0}; UINT16 gatesel = GATESEL(desc); if (!gate) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); // tss cs must be segment if (DPL(r) < PMAX(CPL,RPL(selector))) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(selector)); switch (GATE(r)) { case CALLGATE: if ((addr = i80286_selector_address(cpustate,gatesel)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); gatedesc[0] = ReadWord(addr); gatedesc[1] = ReadWord(addr+2); gatedesc[2] = ReadWord(addr+4); r = RIGHTS(gatedesc); if (!CODE(r) || !SEGDESC(r)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); if (DPL(r)>CPL) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT,IDXTBL(gatesel)); if (GATEOFF(desc) > LIMIT(gatedesc)) throw TRAP(GENERAL_PROTECTION_FAULT,0); if (!CONF(r)&&(DPL(r)<CPL)) { // inner call UINT16 tss_ss, tss_sp, oldss, oldsp; UINT32 oldstk; int i; if(gate == JMP) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(gatesel)); // can't jmp to inner tss_ss = ReadWord(cpustate->tr.base+TSS_SS0*2+(DPL(r)*4)); tss_sp = ReadWord(cpustate->tr.base+TSS_SP0*2+(DPL(r)*4)); oldss = cpustate->sregs[SS]; oldsp = cpustate->regs.w[SP]; oldstk = cpustate->base[SS] + oldsp; i80286_data_descriptor_full(cpustate, SS, tss_ss, DPL(r), TRAP(INVALID_TSS,IDXTBL(tss_ss)), tss_sp-8-(GATECNT(desc)*2), 8+(GATECNT(desc)*2)); cpustate->regs.w[SP] = tss_sp; PUSH(oldss); PUSH(oldsp); for (i = GATECNT(desc)-1; i >= 0; i--) PUSH(ReadWord(oldstk+(i*2))); } else i80286_check_permission(cpustate, SS, cpustate->regs.w[SP]-4, 4, I80286_READ); SET_ACC(gatedesc); WriteWord(addr+4, gatedesc[2]); cpustate->sregs[CS]=IDXTBL(gatesel) | DPL(r); cpustate->limit[CS]=LIMIT(gatedesc); cpustate->base[CS]=BASE(gatedesc); cpustate->rights[CS]=RIGHTS(gatedesc); cpustate->pc=(cpustate->base[CS]+GATEOFF(desc))&AMASK; break; case TASKGATE: selector = gatesel; if ((addr = i80286_selector_address(cpustate,selector)) == -1) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); desc[2] = ReadWord(addr+4); r = RIGHTS(desc); if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); case TSSDESCIDLE: i80286_switch_task(cpustate, selector, gate); i80286_load_flags(cpustate, cpustate->flags, CPL); break; default: throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(selector)); } } } else { cpustate->sregs[CS]=selector; cpustate->base[CS]=selector<<4; cpustate->rights[CS]=0x9a; cpustate->limit[CS]=0xffff; cpustate->pc=(cpustate->base[CS]+offset)&AMASK; } }
/* The main () */ int main (int argc, char ** argv, char ** /*envp*/) { GOptionContext *context = NULL; Ekiga::ServiceCorePtr service_core(new Ekiga::ServiceCore); gchar *path = NULL; gchar *url = NULL; int debug_level = 0; /* Globals */ #ifndef WIN32 if (!XInitThreads ()) exit (1); #endif #if !GLIB_CHECK_VERSION(2,36,0) g_type_init (); #endif #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(); #endif /* GTK+ initialization */ gtk_init (&argc, &argv); #ifndef WIN32 signal (SIGPIPE, SIG_IGN); #endif /* Gettext initialization */ path = g_build_filename (DATA_DIR, "locale", NULL); textdomain (GETTEXT_PACKAGE); bindtextdomain (GETTEXT_PACKAGE, path); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); g_free (path); /* Application name */ g_set_application_name (_("Ekiga Softphone")); #ifndef WIN32 setenv ("PULSE_PROP_application.name", _("Ekiga Softphone"), true); #endif /* initialize platform-specific code */ gm_platform_init (); #ifdef WIN32 // plugins (i.e. the audio/video ptlib/opal codecs) are searched in ./plugins chdir (win32_datadir ()); #endif /* Configuration backend initialization */ gm_conf_init (); /* Arguments initialization */ GOptionEntry arguments [] = { { "debug", 'd', 0, G_OPTION_ARG_INT, &debug_level, N_("Prints debug messages in the console (level between 1 and 8)"), NULL }, { "call", 'c', 0, G_OPTION_ARG_STRING, &url, N_("Makes Ekiga call the given URI"), NULL }, { NULL, 0, 0, (GOptionArg)0, NULL, NULL, NULL } }; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, arguments, PACKAGE_NAME); g_option_context_set_help_enabled (context, TRUE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); #ifndef WIN32 char* text_label = g_strdup_printf ("%d", debug_level); setenv ("PTLIB_TRACE_CODECS", text_label, TRUE); g_free (text_label); #else char* text_label = g_strdup_printf ("PTLIB_TRACE_CODECS=%d", debug_level); _putenv (text_label); g_free (text_label); if (debug_level != 0) { std::string desk_path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); if (!desk_path.empty ()) std::freopen((desk_path + "\\ekiga-stderr.txt").c_str (), "w", stderr); } #endif #if PTRACING if (debug_level != 0) PTrace::Initialise (PMAX (PMIN (8, debug_level), 0), NULL, PTrace::Timestamp | PTrace::Thread | PTrace::Blocks | PTrace::DateAndTime); #endif #ifdef HAVE_DBUS if (!ekiga_dbus_claim_ownership ()) { ekiga_dbus_client_show (); if (url != NULL) ekiga_dbus_client_connect (url); exit (0); } #endif /* Ekiga initialisation */ // should come *after* ptrace initialisation, to track codec loading for ex. GnomeMeeting instance; Ekiga::Runtime::init (); engine_init (service_core, argc, argv); PTRACE (1, "Ekiga version " << MAJOR_VERSION << "." << MINOR_VERSION << "." << BUILD_NUMBER); #ifdef EKIGA_REVISION PTRACE (1, "Ekiga git revision: " << EKIGA_REVISION); #endif PTRACE (1, "PTLIB version " << PTLIB_VERSION); PTRACE (1, "OPAL version " << OPAL_VERSION); #if defined HAVE_XV || defined HAVE_DX PTRACE (1, "Accelerated rendering support enabled"); #else PTRACE (1, "Accelerated rendering support disabled"); #endif #ifdef HAVE_DBUS PTRACE (1, "DBUS support enabled"); #else PTRACE (1, "DBUS support disabled"); #endif #ifdef HAVE_GCONF PTRACE (1, "GConf support enabled"); #else PTRACE (1, "GConf support disabled"); #endif boost::shared_ptr<GtkFrontend> gtk_frontend = service_core->get<GtkFrontend>("gtk-frontend"); GtkWidget *main_window = GTK_WIDGET (gtk_frontend->get_main_window ()); const int schema_version = MAJOR_VERSION * 1000 + MINOR_VERSION * 10 + BUILD_NUMBER; int crt_version = gm_conf_get_int (GENERAL_KEY "version"); if (crt_version < schema_version) { gmconf_upgrade_version (); // show the assistant if there is no config file if (crt_version == 0) gtk_widget_show_all (GTK_WIDGET (gtk_frontend->get_assistant_window ())); /* Update the version number */ gm_conf_set_int (GENERAL_KEY "version", schema_version); } /* Show the main window */ gtk_widget_show (main_window); /* Call the given host if needed */ if (url) { boost::shared_ptr<Ekiga::CallCore> call_core = service_core->get<Ekiga::CallCore> ("call-core"); call_core->dial (url); } #ifdef HAVE_DBUS EkigaDBusComponent *dbus_component = ekiga_dbus_component_new (*service_core); #endif // from now on, things should have taken their final place service_core->close (); /* The GTK loop */ gtk_main (); #ifdef HAVE_DBUS g_object_unref (dbus_component); #endif /* Exit Ekiga */ GnomeMeeting::Process ()->Exit (); service_core.reset (); Ekiga::Runtime::quit (); /* Save and shutdown the configuration */ gm_conf_save (); gm_conf_shutdown (); /* deinitialize platform-specific code */ gm_platform_shutdown (); return 0; }
BOOL CMyPhoneEndPoint::OpenVideoChannel(H323Connection & connection, BOOL isEncoding, H323VideoCodec & codec) { PVideoChannel * channel = new PVideoChannel; PVideoDevice * displayDevice = NULL; if (isEncoding) { // Transmitter part if(!autoStartTransmitVideo) return FALSE; codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,15)); codec.SetBackgroundFill(2); int videoOutMaxBitRate = config.GetInteger(VideoOutMaxbandWidthKey, 320); videoOutMaxBitRate = 1024 * PMAX(16, PMIN(10240, videoOutMaxBitRate)); H323Channel * lchannel = codec.GetLogicalChannel(); const H323Capability & capability = lchannel->GetCapability(); PString cname = capability.GetFormatName(); PINDEX suffixPos = cname.Find("H.263"); if(suffixPos == P_MAX_INDEX) suffixPos = cname.Find("H.261"); int videoSize = config.GetInteger(VideoOutSizeConfigKey, 2); int width=352, height=288; suffixPos = P_MAX_INDEX; switch(videoSize) { case 0: //QCIF width = 176; height = 144; break; case 1: //QVGA if(suffixPos == P_MAX_INDEX) { width = 320; height = 240; break; } case 2: //CIF width = 352; height = 288; break; case 3: //VGA if(suffixPos == P_MAX_INDEX) { width = 640; height = 480; break; } case 5: //SVGA if(suffixPos == P_MAX_INDEX) { width = 800; height = 600; break; } case 6: //XVGA if(suffixPos == P_MAX_INDEX) { width = 1024; height = 768; break; } case 4: //4CIF width = 704; height = 576; break; case 7: //HD 720 if(suffixPos == P_MAX_INDEX) { width = 1280; height = 720; break; } case 8: //SXGA if(suffixPos == P_MAX_INDEX) { width = 1280; height = 1024; break; } case 9: //16CIF width = 1408; height = 1152; break; case 10: //UXGA if(suffixPos == P_MAX_INDEX) { width = 1600; height = 1200; break; } case 11: //HD 1080 if(suffixPos == P_MAX_INDEX) { width = 1920; height = 1080; break; } default: break; } PTRACE(1, "Video device videoSize=" << videoSize << " width=" << width << " height=" << height); codec.SetVideoSize(width, height); width = codec.GetWidth(); height = codec.GetHeight(); PTRACE(1, "Accepted video device width=" << width << " height=" << height); int curMBR = codec.GetMaxBitRate(); if(curMBR > videoOutMaxBitRate) codec.SetMaxBitRate(videoOutMaxBitRate); int videoFramesPS = config.GetInteger(VideoFPSKey, 10); codec.SetGeneralCodecOption("Frame Rate",videoFramesPS); //Create grabber. bool NoDevice = false; PString deviceName = config.GetString(VideoDeviceConfigKey, deviceName); if (deviceName.IsEmpty()) { PStringArray devices = PVideoInputDevice::GetDriversDeviceNames(VideoInputDriver); if (!devices.IsEmpty()) deviceName = devices[0]; else NoDevice = true; } PVideoInputDevice * grabber = NULL; if (deviceName.Find("fake") == 0) NoDevice = true; // else if (deviceName.Find("screen") == 0) grabber = PVideoInputDevice::CreateDevice("ScreenVideo"); else grabber = PVideoInputDevice::CreateDeviceByName(deviceName,VideoInputDriver); if (NoDevice || !grabber->Open(deviceName, FALSE) || !grabber->SetFrameSize(width, height) || !grabber->SetColourFormatConverter("YUV420P") || !grabber->SetVFlipState(localFlip)) { if(!NoDevice) { char sSrc[64]; m_dialog->OutputStatusStr((LPCTSTR)LoadStringLang(IDS_ERRVDEVSTR), S_SYSTEM, (const char *) deviceName, itoa(config.GetInteger(VideoSourceConfigKey,0), sSrc, 10)); PTRACE(1, "Failed to open or configure the video device \"" << deviceName << '"'); } if(grabber) delete grabber; grabber = PVideoInputDevice::CreateDevice("FakeVideo"); grabber->SetColourFormat("YUV420P"); grabber->SetVideoFormat(PVideoDevice::PAL); grabber->SetFrameSize(width, height); grabber->SetVFlipState(localFlip); grabber->SetChannel(4); } if(videoFramesPS >0 && videoFramesPS<30) grabber->SetFrameRate(videoFramesPS); grabber->Start(); channel->AttachVideoReader(grabber); /* if (localVideo) { BOOL curVFlip = config.GetBoolean(VideoOutVFlipConfigKey, FALSE); BOOL curHFlip = config.GetBoolean(VideoOutHFlipConfigKey, FALSE); displayDevice = new CVideoOutputDevice(m_dialog, connection.GetLocalPartyName(), curVFlip, curHFlip, TRUE, FALSE); } else */ displayDevice = PVideoOutputDevice::CreateDevice("NULLOutput"); } else { // Receiver part if(!autoStartReceiveVideo) return FALSE; BOOL curVFlip = config.GetBoolean(VideoInVFlipConfigKey, FALSE); BOOL curHFlip = config.GetBoolean(VideoInHFlipConfigKey, FALSE); displayDevice = new CVideoOutputDevice( m_vdlg, (LPCTSTR)m_dialog->FindContactName(connection), curVFlip, curHFlip, FALSE, localVideo); } if(displayDevice) { int width = codec.GetWidth(); int height = codec.GetHeight(); // if( m_dialog->autohideVideoPan && !m_dialog->showVideoPan) // m_dialog->ShowVideoPanels(TRUE); // show Video panel if it's hiden displayDevice->SetColourFormat("RGB32"); displayDevice->SetColourFormatConverter("YUV420P"); displayDevice->SetFrameSize(width, height); //Give the video window refreshing class to the channel. channel->AttachVideoPlayer((PVideoOutputDevice *)displayDevice); } return codec.AttachChannel(channel,TRUE); }
void CMyPhoneEndPoint::LoadCapabilities() { BOOL sizeChange = FALSE; capabilities.RemoveAll(); // Add the codecs we know about AddAllCapabilities(0, 0, "*"); // Удаляю не поддерживаемые видео кодеки из реестра PINDEX videoNum = 0; for (;;) { PString key = psprintf("%u", ++videoNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = videoNum; videoNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(VideoCodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(VideoCodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(VideoCodecsConfigSection, psprintf("%u", j-1)); } } // добавляю новые видео кодеки если их нет в конфигурации for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(VideoCodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } PINDEX audioNum = 0; for (;;) { PString key = psprintf("%u", ++audioNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = audioNum; audioNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(CodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(CodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(CodecsConfigSection, psprintf("%u", j-1)); } } for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(CodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } // Add all the UserInput capabilities AddAllUserInputCapabilities(0, 1); int videoSizeRx = config.GetInteger(VideoInSizeConfigKey, 2); int videoSizeTx = config.GetInteger(VideoOutSizeConfigKey, 2); RemoveCapability(H323Capability::e_ExtendVideo); autoStartTransmitVideo = config.GetBoolean(AutoTransmitVideoConfigKey, TRUE); autoStartReceiveVideo = config.GetBoolean(AutoReceiveVideoConfigKey, TRUE); localVideo = config.GetBoolean(VideoLocalConfigKey, FALSE); localFlip = config.GetBoolean(VideoFlipLocalConfigKey, FALSE); int videoInMaxBitRate = config.GetInteger(VideoInMaxbandWidthKey, 320); videoInMaxBitRate = 1024 * PMAX(16, PMIN(10240, videoInMaxBitRate)); // changing audio codecs PStringArray enabledCodecs; PINDEX codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); enabledCodecs.AppendString(name); } codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; } int tvNum = 0; // if(tvCaps==NULL) this generates error in free tvCaps = (char **)calloc(codecNum+1,sizeof(char *)); // while(tvCaps[tvNum]!=NULL) { free(tvCaps[tvNum]); tvCaps[tvNum]=NULL; tvNum++; } tvNum = 0; codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; // удаление отключенных кодеков PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } // удаление суффикса on из имени кодека suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); // проверка кодека на соответствие размеру принимаемой картинки // (меньше можно, больше нельзя) и удаление из списка локальных кодеков suffixPos = P_MAX_INDEX; switch(videoSizeRx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; case 7: //SXGA suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 8: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) enabledCodecs.AppendString(name); else capabilities.Remove(name); // проверка кодека на соответствие размеру отправляемой картинки // (меньше можно, больше нельзя) и создание списка допустимых кодеков suffixPos = P_MAX_INDEX; switch(videoSizeTx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; case 7: //HD 720 suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 8: //SXGA suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 9: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) // добавляю в список допустимых { const char *p2pstr=name; tvCaps[tvNum]=strdup(p2pstr); tvNum++; } } // Reorder the codecs we have capabilities.Reorder(enabledCodecs); for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { capabilities[i].SetMediaFormatOptionInteger(OpalVideoFormat::MaxBitRateOption, videoInMaxBitRate); if((capabilities[i].GetFormatName().Find("H.264")!=P_MAX_INDEX) || (capabilities[i].GetFormatName().Find("VP8-")==0)) { H323GenericVideoCapability *h264cap = (H323GenericVideoCapability *) &capabilities[i]; h264cap->SetMaxBitRate(videoInMaxBitRate/100); } } } /* PINDEX audioNum = 1; PINDEX videoNum = 1; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { config.SetString(CodecsConfigSection, psprintf("%u", audioNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } else if (capabilities[i].GetMainType() == H323Capability::e_Video) { config.SetString(VideoCodecsConfigSection, psprintf("%u", videoNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } } */ PTRACE(1, "MyPhone\tCapability Table:\n" << setprecision(4) << capabilities); }