【ffmpeg-0.11.1移植到windows】【網路方面遇到的問題】【中文裝置名稱問題】

來源:互聯網
上載者:User

該文章敘述的一些問題,主要偏windows方面,不著重與linux的比較,接續在如何用vs08編譯ffmpeg這件事情之後。內容大多搜集於網上,為轉載。

————————————————————————————————————————————————————

這篇文章列舉了些資料結構與介面的相關:windows下網路編程筆記之linux到windows程式移植

————————————————————————————————————————————————————

1. 小問題,其實也不是網路技術問題了:if ((int)fds[i].fd > n),條件真還是假(int n = -1;)?

看看linux下pollfd結構的定義:

struct pollfd {    int fd;              /* file des to poll */    short events;  /* events to look for */    short revents; /* events that occurred */};

看看windows下pollfd結構的定義:

typedef struct pollfd {    SOCKET  fd;    SHORT   events;    SHORT   revents;} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;

typedef UINT_PTR        SOCKET;

類型不符,導致的隱式轉換,在windows下,題中的條件運算式基本恒為真。

2. WSAStartup函數

int WSAStartup(  WORD wVersionRequested,  LPWSADATA lpWSAData);

3. ffmpeg代碼中getaddrinfo函數的使用

#if defined(_WIN32){int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,  const struct addrinfo *hints,  struct addrinfo **res);char moduleName[36] = {0};int num_chars = 0;wchar_t moduleName_w[36] = {0};snprintf(moduleName, sizeof(moduleName), "ws2_32.dll");///* convert UTF-8 to wide chars */num_chars = MultiByteToWideChar(CP_UTF8, 0, moduleName, -1, NULL, 0);if (num_chars <= 0)return -1;MultiByteToWideChar(CP_UTF8, 0, moduleName, -1, moduleName_w, num_chars);HMODULE ws2mod = GetModuleHandle((const WCHAR *)moduleName_w);win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");if (win_getaddrinfo)return win_getaddrinfo(node, service, hints, res);}#endif

4. 在ioctlsocket設定非阻塞之後,connect 10035(WSAEWOULDBLOCK)錯誤?

可參考:connect 10035錯誤

“non   blocking模式,connect不會等到成功,而是馬上返回。你需要再select()來判斷成功與否。
   for (i = 0; i < TotalSockets; i++)         
            FD_SET(SocketArray[i]->Socket, &ReadSet);
   if ((Total = select(0, &ReadSet, NULL, NULL, NULL)) == SOCKET_ERROR)
      {
         printf("select() returned with error %d\n", WSAGetLastError());
         return;
      }”

“10035不是錯誤。改變為nonblock模式後第一個改變的觀念就是:不能認為凡是遇到SOCKET_ERROR都認為遇到錯誤了。WSAEWOULDBLOCK是一種正常性的錯誤碼,他告訴你現在這個操作無法立即完成,必須等待後續的通知。你可以通過樓上說的select方式去檢查是否連結成功建立”

或看:http://www.verydemo.com/demo_c173_i9565.html

SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);//先建立通訊端if(sock == INVALID_SOCKET){  AfxMessageBox("建立通訊端失敗!");  return 0;}SOCKADDR_IN addrTo;addrTo.sin_family=AF_INET;addrTo.sin_port=htons(4000);addrTo.sin_addr.S_un.S_addr=inet_addr(ip);//--------------------------------------------------------------------------//設定為非阻塞方式串連unsigned long ul = 1;int err;int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);if(ret == SOCKET_ERROR){err = WSAGetLastError();  closesocket(sock);  sock = NULL;  return FALSE;}TIMEVAL timeval;fd_set r;                      FD_ZERO(&r);FD_SET(sock, &r);timeval.tv_sec = 1;   //秒timeval.tv_usec =200;  //毫秒//上面的代碼是要connect在1.2秒之後返回,不管是否已經串連上,這樣就不會阻塞啦,簡單吧connect(sock, (SOCKADDR*)&addrTo, sizeof(SOCKADDR));ret = select(0, 0, &r, 0, &timeval);  if ( ret <= 0 ){  char ch[20] = {0};  sprintf(ch, "和%s連線逾時, 取原參數失敗", ip);  MessageBox(ch, "錯誤", MB_ICONSTOP);  err = WSAGetLastError();  closesocket(sock);  sock = NULL;  return FALSE;}

順便記錄這個問題:How to set a socket connection timeout

是說,有時候connect當目標不能到達,逾時太久。就先設定非阻塞,connect立即返回,然後重新設為阻塞,最後做select看看socket是否準備好。

5. 在ffmpeg的dshow中,去枚舉裝置名稱,與上層傳下來的裝置名稱匹配。

如:漢字的unicode編碼,常用漢字的UTF-8編碼,漢字GBK編碼錶。上層擷取的是GBK碼,下面卻用UTF-8去匹配,所以總是失敗。

引自 文字編碼 ASCII 漢字GB2312 UTF-8解析

“ASCII,美國資訊交換標準代碼(America standard code of Information Interchange),用一個位元組的7位,美國專用。歐洲也要編碼,於是位元組的8位全用上,有了IBM/ISO Latin-1。然後是第三世界國家,中國,韓國等,於是就必須得擴充了,我們中文輻射區的文字表示甚是複雜,於是兩個位元組的UNICODE出世。但是在幾種編碼的相容問題出現了,怎樣讓中文的一個檔案能在美國讀出來呢?一種權衡方案出台--UTF系列。UTF,Universal
Transformation Format,通用轉換格式。UTF-8是一種非定長的字元表示方式,具體實現可以參見相關資料。”

引自 漢字怎樣轉換成ascii碼

“ascii碼是根據http編碼得出的,首先要知道這個字的http編碼,先進入百度貼吧,把你想查看的字輸入,點擊搜尋,比如說我輸入“牛”,因為地址太長了,再點一下左上方百度貼吧旁的“牛吧”,就會出現比較短的地址,這個地址是 http://tieba.baidu.com/f?kw=%C5%A3 kw=後面的%C5%A3就是http編碼,把%去掉,變成C5A3,使用系統內建的計算機把他變為10進位(開始——所有程式——附件——計算機),查看——科學型,先選擇十六進位,再輸入C5A3,然後選擇十進位,上面的數字就會變成50595,也就說alt+50595能打出“牛””

下面貼兩段代碼,gbk與utf-8的轉換,調用了windows下的介面,代碼醜陋與否無所謂了。

//using cchar *gbk_to_utf8_c(const char *src_gbk, void *(* local_malloc)(size_t), void (* local_free)(void *)){int n;char *dst_utf8 = NULL;wchar_t *tmp = NULL;if (!src_gbk || !local_malloc || !local_free){return NULL;}n = MultiByteToWideChar(CP_ACP, 0, src_gbk, -1, NULL, 0);tmp = (wchar_t *)local_malloc(n*2+2);memset(tmp, 0, n * 2 + 2);MultiByteToWideChar(CP_ACP, 0, src_gbk, -1, tmp, n);n = WideCharToMultiByte(CP_UTF8, 0, tmp, -1, NULL, 0, NULL, NULL);dst_utf8 = (char *)local_malloc(n+1);memset(dst_utf8, 0, n + 1);WideCharToMultiByte(CP_UTF8, 0, tmp, -1, dst_utf8, n, NULL, NULL);local_free((void *)tmp);return dst_utf8;}char *utf8_to_gbk_c(const char *src_utf8, void *(* local_malloc)(size_t), void (* local_free)(void *)){int n = MultiByteToWideChar(CP_UTF8, 0, src_utf8, -1, NULL, 0);wchar_t *tmp = (wchar_t *)local_malloc(n*2+2);char *dst_gbk = NULL;memset(tmp, 0, n * 2 + 2);MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)src_utf8, -1, (LPWSTR)tmp, n);n = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)tmp, -1, NULL, 0, NULL, NULL);dst_gbk = (char *)local_malloc(n+1);memset(dst_gbk, 0, n + 1);WideCharToMultiByte(CP_ACP,0, (LPCWSTR)tmp, -1, dst_gbk, n, NULL, NULL);local_free((void *)tmp);return dst_gbk;}

還可以參考:UTF-8, Unicode, GB2312格式串轉換之C語言版

除了編碼問題,在dshow介面調用的時候,(對於一些硬體裝置名稱,xp win7下不同,win7下通常會有首碼,這樣使裝置名稱很長),裝置易記名稱擷取不完整,而用dsound介面擷取又是沒有問題的。下面是dshow調用的部分介面:

*.讀取裝置名稱的屬性step1:  Call IMoniker::BindToStorage to get a pointer to the IPropertyBag interface.        IPropertyBag *pPropBag;        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag)); step2:   Call IPropertyBag::Read to read the property.        VARIANT var;        VariantInit(&var);        // Get description or friendly name.        hr = pPropBag->Read(L"Description", &var, 0);

沒轍,在這裡做名字匹配的時候,只好通過,兩個字串是否包含的關係,去做比較。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.