討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 網路投保旅行平安險 討論區最近新進100則主題
[ 回上頁 ] [ 討論區發言規則 ]
directShow 如何為transform filter 多一個input pin
更改我的閱讀文章字型大小
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/3 上午 11:48:58

請問一下 我目前寫好了一個transform filter(是繼承 CTransformFilter)

可是我又想要多一個input pin 來抓取另一個影片上的資料

在我寫好的transform filter 內的 transform function 作一些剪接拼貼的處理

請問我該怎樣直接新增一個 input pin 呢

我找到的資料都是說要從CBaseFilter 改寫

請問有沒有相關的資料或是 sample code 可以參考看看呢

謝謝回答
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/2/7 下午 09:50:48
兩個以上 Input Pin 的sample 比較少看到, 你可找看看有沒有Muxer的code 可以參考...一個 Input Pin, 多個 Output pin則是可以參考 InfiniteTee 這個 Sample.
你如果要寫非一進一出的filter. 的確是要由 CBaseFilter 下去寫...要從 Transform filter 去改會變得很麻煩..
基本原則是寫一個 filter 繼承自 CBaseFilter...然後這個 Filter 堶戚n有一或多個 member 是繼承自 CBaseInputPin. 依據你的需求來訂的..然後再一個或多個member 是繼承 CBaseOuputPin...
以最常見的的 2 進 1出來說...就是有兩個繼承 CBaseInputPin 的 member 和 一個繼承 CBaseOutPin 的 member...
因為多 Pin 的 filter 依需求, 寫法變化還蠻大的...你可以大概說一下你想做什麼事...這樣比較容易決定要怎麼實作...


作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/9 下午 09:35:32
謝謝你的回覆

我目前的計畫是接兩個input

一個是avi 檔 一個是 web cam

在transform filter中 web cam 部分會作人臉偵測 再把它剪下來 放在影片中

這是我目前的計畫

我現在最大的問題是找不到 繼承cBaseFilter 適當sample code可以改

因為我不知道 transform(input , output) 這 function 怎麼改

因為我預期在裡面作影像處理合併的動作

我找的sample 都是 run, stop, pause
(問個笨問題 這三個function 為何在cTransformFilter 內都沒看到阿 CBaseFilter 才有)

再度謝謝你的回答
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為最佳解答 2010/2/10 上午 04:13:59
其實 CTransform filter 就是一個使用 CBaseFilter 的範例了...只是他還做了很多事..
一般來說, 除非我們有要依目前 streamming 狀態 allocate resource, 或是要檢查 streamming 狀態時, 才會去覆寫 run/stop/pause function..

CTransform filter 把大部分的 media type 的檢查, 選擇和allocate之類的工作都包裝好了...所以你大部分的工作都會在 CTransformFilter::Transform 這個 function 內完成..

依你的情形, 你要做的事是寫一個filter class 繼承 CBaseFilter, 然後寫兩個 video InputPin class 繼承 CBaseInputPin, 一個 OutputPin 繼承CBaseOutputPin. 而這三個 Pin 都是 filter class 的 memory variable.

在 filter class 中, 你要實作
1. CBaseFilter::GetPin
    - 你要依據傳進來的 Index, 決定要將那個 pin 的pointer 傳出去, index 你可以自己決定...index 由 0 開始, 通常是先排 input pin , 再排 output pin.
    - 以你的情況來說, 0: 回傳第一個 video input pin, 1:回傳第二個 video input pin, 2:回傳 output pin
2. CBaseFilter::GetPinCount
    - 回傳 3
3. 一個 receive function, 角色如同你在 Transform filter 堛 Transform function, 所有的Input Pin要將他們收到的media sample 傳到這個 function, 你會在這個 function 內處理大部分的事情...可能還會需要 allocate 自己的 media sample. (如果在 Pin 埵 allocate 自己的 media sample 的話, 這部就可以省了. ), 這個function最後需要將處理好的media sample 送到 output pin 去.

在 input pin 中, 你要實作
1. CBasePin::CheckMediaType
   - 檢查傳進來的 media type 你有沒有 support.
   - 依你 support 的程度, 但至少要是 MEDIATYPE_Video 不然你之後會很難處理.
2. CBasePin::GetMediaType
   - 依據 index 回傳你可以 support 的 media type. (通常這個回傳值只作參考用而已..但儘量填對以後麻煩比較少)
   - 你應該回傳 video 相關的 media type.
3. CBaseInputPin::Receive
   - 你會在這個 function 收到 media sample, 可以依據你的需要做一些前置處理, 然後將media sample 送到 filter 的 receive function 和其他的 pin 的media sample 一起做一些事.
4. CBaseInputPin::BeginFlush/CBaseInputPin::EndFlush
  - 上游的 filter 告訴你他要清 buffer 了, 你要還沒做完的事趕快做完...如果沒什麼事的話, 這兩個function可以不做事..

至於 output pin 要實作的是
CBaseOutputPin::DecideBufferSize...
這你可以參考Ball 這個sample, 堶惘 output pin 有實作這個 function...

你可以先試著寫寫看, 有問題再來研究研究吧.
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/10 上午 04:16:17
sorry, 上面的 memory variable, 應該是member variable.
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/10 上午 09:58:50
真的很感謝你的回覆

因為我對於繼承不同的filter後 又該實作哪些function

這問題一直很困惑 不知道該去哪找資料

謝謝你的回覆

不過我現在在研究 ffmpeg decoder Orz.....

可能要過年後 才會再來研究這個 two input pin filter

另外想請教 因為我是dshow 新手
 
請問有沒有幫助寫 dshow code 的工具阿

因為有很多地方 實作函式 要背

有沒有精靈可以幫忙完成這些工作呢

像是DirectShow Wizard
http://marcefertech.wordpress.com/2007/04/19/directshow-wizard/

可是我的環境是 vs 9 我試的結果是沒有用

再次謝謝你的回覆

感恩
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/2/12 上午 08:56:17
不好意思, 我寫 filter 大多是從頭關始手工的...並沒有用 Wizard, 所以Wizard 的資訊我就不清楚了..
不過如果是要寫繼承 CBaseFilter 的class 的話, 我通常 source filter 會參考 ball, transform 會參考 InfTee, render 會參考 dump.
和 device capture 或是 transcoding 有關的我會參考 AMCap.., 再來就是參考我手上現有的...so..

順道一提... 如果你是要把 ffmpeg 用在商業用途的話, 要注意 royalty 的問題...如果是純研究就沒差了..此外 ffmpeg 也可以包在 filter 堶接 DShow 的程式用...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/22 上午 10:04:36
謝謝你的回覆

因為之前在過年 所以才拖到現在回復

我現在的想法就是想把 ffmpeg 包成 filter
(一個open source 的h264 decode filter)
(因為 ffdshow 的pin 跟我現有的encoder 不能相接 所以只好自己作一個來包)

就像是
http://blog.csdn.net/hnhyhongmingjiang/archive/2008/09/15/2931938.aspx

不過她是 flv 我的目標是 h.264

目前code 改好了

可是在VMR裡秀出來的結果是綠色一片

不知道您有沒有相似的經驗可以分享

謝謝你 新年快樂
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/22 下午 02:34:27
太好了 我可以播 副黨名為 .264 的檔案了

可是fps = 2

這個.... 應該有辦法解決吧

因為 kmplayer 也是用 ffmpeg 播影片

我再繼續研究 如果前輩你有任何情報線索

還請你分享一下

謝謝你
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/2/24 下午 01:12:00
之前我是在使用 ffmpeg + libx264 來測試 h264 encoding 的功能, 並沒有測試他 decode h264 的能力..
我在做 encoding 時, 壓的圖是 320*240, 吃的 CPU 大約是和 VC-1 吃的 resource 差不多..core 2 dual 3G 大約要吃50~70%左右.
基本上, decode應該有機會用到硬體的解壓縮, 所以有機會比較快, 啟用硬體加速的功能印象中是 compile 的選項, 你要自己打開後, compile 後的lib才會去啟用硬體加速..
基本上, 用CPU去decode H264 HD的圖...一秒兩張可能還算是蠻正常的結果. software 端能做的大概就是啟用硬體加速, 利用指令集幫忙做向量運算(ffmpeg應該有 compile選項可以開)..再來就是減少memory copy 的次數...減少memory copy data 的次數算是比較容易improve的, 而且improve的程度也算可觀(少一次 copy 有可能CPU少1~3%)..

順便提一下, 以後你看到綠色畫面, 大概都可以直接猜是沒有資料送進renderer堶..因為大部分的renderer 綠色是底色, 會出現底色十之八九都是沒資料進去造成的.

再來還是提醒一下, 就算是要open source...你最好還是不要提供 binary 的檔案給人家...binary 的檔案會有 royalty 的問題...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/24 下午 02:31:55
真的很感謝你的回覆
給我很大的幫助

所以我現在的下一步就是去找如何開啟 ffmpeg 的硬體加速的選項囉

另外謝謝您的提醒
我會注意的

再次謝謝你
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/24 下午 05:20:33
我剛剛看 ffmpeg 的教學範例

發現在程式理 直接開檔 解碼(h264) 再用SDL 播出 速度非常快

而且範例code 都跟我包在 filter 內的一樣 (他應該也沒有用到硬體加速吧)

我想說 會不會是因為是包在direct show 內 而我少做了什麼事

所以才會慢的呢??

謝謝回復
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/24 下午 05:40:53
我剛剛看 ffmpeg 的教學範例

發現在程式理 直接開檔 解碼(h264) 再用SDL 播出 速度非常快

而且範例code 都跟我包在 filter 內的一樣 (他應該也沒有用到硬體加速吧)

會不會是因為是包在direct show 內 而我少做了什麼事

我猜想 請你看看這樣對不對

會不會是 上流的filter 一次傳一個packet 過來 而不是傳一個frame

所以每次在做這些 packet 的decoder後再組合 會花比較多時間

才會慢的呢??

謝謝回復
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/24 下午 05:41:06
我剛剛看 ffmpeg 的教學範例

發現在程式理 直接開檔 解碼(h264) 再用SDL 播出 速度非常快

而且範例code 都跟我包在 filter 內的一樣 (他應該也沒有用到硬體加速吧)

會不會是因為是包在direct show 內 而我少做了什麼事

我猜想 請你看看這樣對不對

會不會是 上流的filter 一次傳一個packet 過來 而不是傳一個frame

所以每次在做這些 packet 的decoder後再組合 會花比較多時間

才會慢的呢??

謝謝回復
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/2/24 下午 07:16:37
不知你使用的是同一份 ffmpeg 的 library嗎? 因為不同的 compile 選項, compile 出來的performance 是差很多的.
我覺得你可以先把每個工作拆開來, 分斷來看看到底是 decode 慢(decode完的資料不要用直接丟掉, log 起來就好.)或是 rendering 慢, 如果是 decode 慢的話, 就是從ffmpeg library 查看看...或是看看是不是有多餘的 memory copy或是在decode進render之間多做了一些事或是你多了一些不必要的 sleep. (檢查 CPU 的使用量, 如果沒到100的話就有 tuning的空間..)
.
如果是 rendering (試一下丟固定資料, 不要用 deocde 的)慢的話...可能就要想想要怎麼用了...目前暫時沒有什麼 idea...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/26 下午 01:57:11
不好意思又來請教

我後來發現 在我作的decoder filter 後面加上一個 color convert filter 速度就變很快了

可是現在還有個小問題想請教一下

就是我show 出來的的影片有部分會有格子狀 有些又是正常的

http://ppt.cc/(S;Z

想請問說這表示解碼錯誤嗎??

可是我用相同的選項來解同一個檔案

不透過 dshow 就OK

請問我該怎麼解決了

謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/2/26 下午 04:52:24
我剛剛把兩份code 合在一起做個比較

列出其中的差異

1. (直接用 ffmpeg 程式跑)
    //先開檔
    //讀frame
    av_read_frame(pFormatCtx, &packet);
    // Decode video frame
    int bytesDecoded = avcodec_decode_video(pCodecCtx, pFrame, &got_picture, packet.data, packet.size);
    ==> 速度正常 影像正常
 
2. (將 ffmpeg 包成filter)
    if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
     pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
    int bytesDecoded = avcodec_decode_video(pCodecCtx, pFrame, &got_picture, (uint8_t *) input, inLen);
    ==> 速度飛快 影像有格子 ( http://ppt.cc/(S;Z )

而且每次在解碼時 inLen 都是固定的值 262144, 而 packet.size 會跳動100~30000

不過兩者的累加是相同的 (是 1280*720 的.264 檔案)

我下一步該怎麼解決 速度飛快 影像有格子 的問題呢

謝謝回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/4 下午 09:12:27
我建議你可以看一下
 bytesDecoded 這個值...
我猜這個值必須要和你的Media sample堛 actual data length 相同,
你可以利用 IMediaSample::SetActualDataLength來設定media sample的actual data length.


作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/4 下午 09:26:34
這堶惘陷ㄗ駣fmpeg packet 的PTS..
http://dranger.com/ffmpeg/tutorial05.html

你要對每個frame設定對的 time stamp..不然的話就有可能出現畫面快轉的情形..(因為沒有 time stamp, renderer 就會播的ASAP..)
如果你暫時不知怎麼設定的話. 幾個測試可以幫你..
1. 可以把每個 frame都設定成 sync point. (IMediaSample::SetSyncPoint) 這樣會強迫 DShow 的renderer 一定要把畫面畫出來...如果確定畫面是OK的話, 再調整PTS讓畫面正常播..(但是若硬體太強的話畫面一樣是快轉, 但是不會掉 frame.)
2. 你也可以先自己做假的PTS來測試. i.e. 自己為每個frame 填PTS...第一個填0~ 33 ms, 第二個 34 ~ 66ms, 第三個 67~100 ms..,etc. 等看起來差不多正常後再和你ffmpeg decode出來的PTS做比較, 這個會比較知道該怎麼填...

你可以看一下你的 code 堶惘釣S有設定 PTS..
你可以利用
IMediaSample::SetTime
來設定 PTS
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/4 下午 09:57:02
不好意思, 剛剛前面的說明, 方向有點弄錯了..

int avcodec_decode_video(AVCodecContext *avctx,
     AVFrame *picture,
     int *got_picture_ptr,
     uint8_t *buf,
     int buf_size);
這個function..
最後的這個參數..buf_size, 應該是要由你指定才對..
他的值是media sample堛...
IMediaSample::GetActualDataLength.


buf 要填的是..IMediaSample::GetPointer 抓到的那個pointer..
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/5 上午 09:23:09

謝謝你的回覆

切割的部分我完成了 我用的方法跟你提示的差不多

只是我不知道 OutputPin -> Deliver 可以直接送資料出去

我現在的確畫面會快轉
(ps 我現在播影片才會變快 接網路stream 速度正常 )
(是因為 網路stream PTS 可以忽略嗎 ?? )

因為我同一次切割的 frame PTS 都設一樣的

我會再研究如何設定正確的 frame

接下來我的下一步就是用相同的方法作一個 h264 encoder filter

希望到時候能再請教你問題 (當然是希望不要遇到問題 XD)

謝謝你的回覆

作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/5 下午 10:07:41
你播放的速度應該是不會和你用 network 或是 local 有關..
但是我不知道你是用什麼方式在網路 streaming 的, 所以沒辦法確定,
因為進網路可能有muxing...在muxing時...是有機會打time stamp的..一般如果不包成 straming 的format, 應該是沒辦法
在網路上做 streaming 才對..

如果你在streaming時不會快轉, 你也可以在網路另一端把資料抓下來看看是不是有time stamp在堶..
你可以用 wireshark 或是 httpwatch 把資料抓起來看看和你送出去的資料有什麼不一樣..

另外, 如果你用的bitrate 很高的話, 播的慢也有可能是網路頻寬造成的...

>
>謝謝你的回覆
>
>切割的部分我完成了 我用的方法跟你提示的差不多
>
>只是我不知道 OutputPin -> Deliver 可以直接送資料出去
>
>我現在的確畫面會快轉
>(ps 我現在播影片才會變快 接網路stream 速度正常 )
>(是因為 網路stream PTS 可以忽略嗎 ?? )
>
>因為我同一次切割的 frame PTS 都設一樣的
>
>我會再研究如何設定正確的 frame
>
>接下來我的下一步就是用相同的方法作一個 h264 encoder filter
>
>希望到時候能再請教你問題 (當然是希望不要遇到問題 XD)
>
>謝謝你的回覆
>
>
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/10 下午 08:40:54

又遇到問題了 Orz

請問如果我在 DecideBufferSize 內 所用的 m_inputPin 變數裡面很多都是 ???

所以我無法藉由m_inputPin -> CurrentMediaType得到影像寬高

因為 connect 不起來

所以也不能從第一筆資料來parse h264 的header

請問我還有哪些方法可以取得影像的寬高呢

謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/11 下午 06:04:25

請問你之前 研究 ffmpeg 時 可以 encode h264 吧

還是說要另外裝 libx264?? 這個動作要在 linux 才能做嗎

有沒有已經有 libx264 的 ffmpeg SDK 呢??(我是用 3.2 版)

因為我現在用另外的 libx264 產生的 .264 黨

不能用我用ffmpeg 作的 264 decoder 讀

錯誤好像是 ffmpeg 的參數設錯

不知道您有相關的資訊嗎

謝謝您的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/11 下午 07:42:49
我之前壓 h264 是自己 compile ffmpeg +libx264 的. compile可以在 windows 下進行, 但是要做很多前置作業..
當時東抄西抄找了很多網站, 後來發現官網上的一個連結
http://ffmpeg.arrozcru.org/wiki/index.php?title=Main_Page
這堶措 windows 下 compile ffmpeg 有詳細的介紹, 那堶惟M libx264 有關的資料在
http://ffmpeg.arrozcru.org/wiki/index.php?title=X264
此外, ffmpeg 對 h264 encode 的支援是在 compile time 就已經決定了...如果當時 compile 的人沒打選項打開, compile 出來的ffmpeg 就沒有encode h264 的能力...so...你應該是自己 compile 一份自己的 ffmpeg 才是...
以下是我之前用的 compile 選項...你可以參考看看.. 我compile的是 一份支援 h264 + aac 的ffmpeg...

exe:
make distclean;
./configure --enable-memalign-hack --extra-cflags="-fno-common" --enable-libx264 --enable-gpl --enable-libfaac --enable-nonfree;
make;
make install;


dll:
make distclean;
./configure --enable-memalign-hack --extra-cflags="-fno-common" --enable-libx264 --enable-gpl --enable-libfaac --enable-nonfree --enable-shared --disable-static;
make;
make install;

>
>請問你之前 研究 ffmpeg 時 可以 encode h264 吧
>
>還是說要另外裝 libx264?? 這個動作要在 linux 才能做嗎
>
>有沒有已經有 libx264 的 ffmpeg SDK 呢??(我是用 3.2 版)
>
>因為我現在用另外的 libx264 產生的 .264 黨
>
>不能用我用ffmpeg 作的 264 decoder 讀
>
>錯誤好像是 ffmpeg 的參數設錯
>
>不知道您有相關的資訊嗎
>
>謝謝您的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/3/11 下午 07:59:40
影像的寬高通常正確的大小都是要開始 streamming 時才會知道的...在 connection 這個 state, 只要確保allocate 出來的 memory 之後夠用就行了.(夠用的話, 之後進行dynamic format change 會比較簡單, 不然要重新設定 allocator, 蠻麻煩的)
所以在decide buffer size 階段, 你可以自己定一個足夠的大小就可以了. 這個 function 在directshow堶悸漕丹潀麻I怪怪的...
因為這堥M定的值, 之後有可能會改變.

你在
receive 到 media sample 之後, 你要檢查堶悸榦edia type, 就定義來說, 一般應該是 NULL, 如果streaming 的format有變的話, 就必須拿這個最新的 media type 參考堶悸熙]定來重新設定自己的程式, 不過好玩的是...不知為什麼...通常第一個 media sample 的media type 都不會是 NULL...所以通常正確的影像格式都必須參考這個media type.

此外, 你在decide buffer size 時, 因為input pin 還沒 connect, 所以你才會看不到東西...通常要 complete connect 之後, pin 的資料才能參考.

>
>又遇到問題了 Orz
>
>請問如果我在 DecideBufferSize 內 所用的 m_inputPin 變數裡面很多都是 ???
>
>所以我無法藉由m_inputPin -> CurrentMediaType得到影像寬高
>
>因為 connect 不起來
>
>所以也不能從第一筆資料來parse h264 的header
>
>請問我還有哪些方法可以取得影像的寬高呢
>
>謝謝你的回覆
>
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/11 下午 08:15:32
補充一下,
在basepin 堛榦ember
m_mt
堶推雩茼酗妨e在check media後的結果, 你可以拿這個值來參考要怎麼設buffer 的大小...
不過就如我上面提的, 通常真正的media type都是存在第一個sample堛.
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/11 下午 10:31:40
sorry 我的問題問錯了

當我 filter的output pin 要跟別的filter 相連時

他會呼叫 GetMediaType 並在裡面設定output 影像寬高

我就是卡在這邊 照理說應該可以藉由 m_input 這變數得到這些資訊才對

Receive 不是要在Run的時候才會跑到嗎??

可以先取得第一筆 sample 來作 paser 嗎??

另外問一下 如果我作一個h264 encode filter

那他的GetMediaType function 內要怎麼設定 因為我不知道他的 pixel format, chnnle number .... 等

先前我作 decoder 是轉為 RGB32 所以這些資訊我都知道

請問轉 YV12 這些資訊我該參考哪些資料

謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/12 上午 12:46:28
ffmpeg 堶惘 sample 是用PIX_FMT_YUV420P來進行壓縮的(sample.c), 所以我是根據sample強制把 RGB 24 轉成encoder support 的format. (轉換方式就在 sample 堶)
所以 get media type 我的 code 就只有回傳我只支援 RGB 24而已... 這樣上游的 filter 會想辦法轉成我要的格式再送下來

HRESULT CVideoInputPin::CheckMediaType(const CMediaType *mtIn)
{
HRESULT hr = E_INVALIDARG;
CheckPointer(mtIn, E_POINTER);

if(MEDIATYPE_Video != (*mtIn->Type())) return E_INVALIDARG;

if( MEDIASUBTYPE_RGB24 == (*mtIn->Subtype()) )
   {
if(1 != mtIn->bFixedSizeSamples) return E_INVALIDARG;
hr = S_OK;
   }
    return hr;
}

至於 Image format 的資訊, 大概就是去查 image processing的書了..
MSDN上有簡短的介紹, 你可以在這查到
http://msdn.microsoft.com/en-us/library/dd391027(VS.85).aspx

至於第一個sample的確是要streaming之後才會收得到..
這時必須依據當時media sample的media type值, 來決定要不要進行 dynamic format change.
你可以參考下面的資料..
http://msdn.microsoft.com/en-us/library/dd388731(VS.85).aspx
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/12 上午 11:12:03
不好意思 我覺得您好像有點誤會我的意思了

你文章內的 CVideoInputPin::CheckMediaType

我在HRESULT CMyH264Encoder::CheckInputType(const CMediaType *mtIn) 做了 內容大致一樣 (我想應該功能是一樣的)

這是我的 graph
source filter --> encoder --> decoder --> color convert --> render filter

我想我現在的問題是在 encoder --> decoder 之間的箭頭上

卡在 HRESULT CMyH264Encoder::GetMediaType(int iPosition, CMediaType *pMediaType)

不知為何她的 iPosition 會回傳1 我個人猜測是 對output type 沒有指定好 所以不能connect

不知道您先前的 encoder filter 這一個部份是怎麼做的

謝謝您的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/12 上午 11:37:31
我解決 connect 的問題了

原來是我 HRESULT CMyH264Encoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)

這裡沒有改為 MEDIASUBTYPE_H264

謝謝你的回覆

作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/12 下午 04:27:25
又遇到小問題了

我目前的做好的 h264 encode filer 他的 in/out pin media type 分別是 MEDIASUBTYPE_YUY2 / MEDIASUBTYPE_H264
buffer size 設定 w*h*1.5

然後我把進來的 buffer 作編碼的動作
avpicture_fill((AVPicture *)pFrame, input, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
int bytesDecoded = avcodec_encode_video(pCodecCtx, out , inLen , pFrame);

可是結果圖是 http://ppt.cc/8Pu2

我猜想是 pixel format & buffer size 不對的問題

不知道您先前有遇到類似的問題嗎

謝謝您的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/3/12 下午 07:01:54
YUV 420P 和 YUY2 要做convert,
你可以參考
http://msdn.microsoft.com/en-us/library/dd206750(VS.85).aspx
堶惘酗雯苳@些轉換的公式...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/12 下午 09:07:09

有一個小地方 在上文中沒有向您問清楚

這是我的 graph
upstream filter --> decoder fliter--> color convert --> render filter

decoder filter 在 HRESULT CMyH264Decoder::GetMediaType(int iPosition, CMediaType *pMediaType)

要設定 output pin 的 media pin 時 無法取得 m_input 的資訊

因此我無法藉由m_inputPin -> CurrentMediaType得到影像寬高
(應該是 upstream filter 沒寫好 因為我用別的upstream filter 裡面的m_input 都有寬 高資訊 )

所以照您先前說的 DecideBufferSize 我目前是先寫死 只要大一點(w*h*4)

之後的dynamic format change 會比較簡單, 不用allocator

在 transfrom 收到第一個sample時 再來 parse h264 的header
(有簡單網頁說明第幾個 byte 是 w or h嗎 我找到的都是很長的pdf orz)

再來更改裡面BufferSize 不知道我的理解有錯嗎
(or 看 m_inputPin ->m_mt 裡面有沒有 w or h 資訊)

http://msdn.microsoft.com/en-us/library/dd388731(VS.85).aspx

謝謝您的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為最佳解答 2010/3/13 上午 05:32:50
如果你是想知道 encoded data 在 decode 完之後是什麼格式, 大小的話...
在 ffmpeg 堛 avcodec_decode_video function
decode 完後, AVCodecContext 的內容會被修改, 你可以去查堶悸滬, 然後填給下游的 filter...不用自己去 parse h264 的 header.
通知下游最簡單的方法, 就是你在產生第一個 sample 的時候, 把 format 填到 sample 的 media type 堶, 這樣下游的 filter,
在收到第一個 sample 之後, 就會根據新的資訊來設定了...但是第二個以後的 sample , media type 要記得填成NULL...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/16 下午 05:51:25
不好意思 又來請教了

我現在已經得要影像正確的寬高資訊

請問我要如何去更改他的 mediatype 呢??

我用我的方法改了以後 變成這樣
http://ppt.cc/y8KB

我一開始在 HRESULT CMyH264Decoder::GetMediaType(int iPosition, CMediaType *pMediaType)

先設他的寬高 是1280*720

後來得到正確的寬高後 640*480

以下是我更改 mediatype 的code

CMediaType pMediaType = m_pOutput->CurrentMediaType();
ULONG t = pMediaType.lSampleSize;
pMediaType.SetFormatType(&FORMAT_VideoInfo);
pMediaType.SetType(& MEDIATYPE_Video) ;
pMediaType.SetSubtype(& MEDIASUBTYPE_RGB32) ;

////修改format///////
VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.AllocFormatBuffer(sizeof(VIDEOINFO));
ZeroMemory(pvi, sizeof(VIDEOINFO));
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 32;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = w;
pvi->bmiHeader.biHeight = h;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->AvgTimePerFrame = 30;
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
pvi->rcTarget.right = pvi->rcSource.right = w;
pvi->rcTarget.bottom = pvi->rcSource.bottom = h;

pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
pMediaType.SetSampleSize(w*h*4);
pMediaType.ReallocFormatBuffer(w*h*4);
ULONG t1 = pMediaType.lSampleSize;
m_pOutput->SetMediaType(&pMediaType);

請問是不是我哪裡疏忽了

謝謝你的回覆

作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/16 下午 05:51:32
不好意思 又來請教了

我現在已經得要影像正確的寬高資訊

請問我要如何去更改他的 mediatype 呢??

我用我的方法改了以後 變成這樣
http://ppt.cc/y8KB

我一開始在 HRESULT CMyH264Decoder::GetMediaType(int iPosition, CMediaType *pMediaType)

先設他的寬高 是1280*720

後來得到正確的寬高後 640*480

以下是我更改 mediatype 的code

CMediaType pMediaType = m_pOutput->CurrentMediaType();
ULONG t = pMediaType.lSampleSize;
pMediaType.SetFormatType(&FORMAT_VideoInfo);
pMediaType.SetType(& MEDIATYPE_Video) ;
pMediaType.SetSubtype(& MEDIASUBTYPE_RGB32) ;

////修改format///////
VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.AllocFormatBuffer(sizeof(VIDEOINFO));
ZeroMemory(pvi, sizeof(VIDEOINFO));
pvi->bmiHeader.biCompression = BI_RGB;
pvi->bmiHeader.biBitCount = 32;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = w;
pvi->bmiHeader.biHeight = h;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->AvgTimePerFrame = 30;
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
pvi->rcTarget.right = pvi->rcSource.right = w;
pvi->rcTarget.bottom = pvi->rcSource.bottom = h;

pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
pMediaType.SetSampleSize(w*h*4);
pMediaType.ReallocFormatBuffer(w*h*4);
ULONG t1 = pMediaType.lSampleSize;
m_pOutput->SetMediaType(&pMediaType);

請問是不是我哪裡疏忽了

謝謝你的回覆

作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/17 下午 10:44:23
你這圖的結果看起來有點像是下游的filter不支援dynamic format change, 所以你format change 沒成功..
你可以在set media type 之前呼叫input pin的CheckMediaType 或是QueryAccept 看看是成功還是失敗..
如果下游的filter 不支援dynamic format change的話, 大概就只能自己轉了. 通常比較常用的方法是後面接一個專門負責做format change的filter. 這個filter專門負責格式和大小的轉換, 但這個filter 得自己寫...
通常color space的轉換有機會可以用系統內建的, 而resize大概都得自己來..因此有一個投機的做法就是把output size直接設定成video的大小(當然前題是已知video的大小就是了). 這樣就有機會省到一些功...
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/17 下午 10:49:37
這個現像還有一個可能是 stride 的設定有問題...
你可以參考
http://msdn.microsoft.com/en-us/library/dd318229(VS.85).aspx
最下面有提到這個問題的介紹...
不過我個人是覺得上面的情況的機率比較大就是了..
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/17 下午 11:49:52
剛剛測試發現

我做完這一步後
m_pOutput->SetMediaType(&pMediaType);
馬上
m_pOutput->GetMediaType(&pMediaType);
發現
pMediaType.lSampleSize; 還是沒變 還是舊的size

我下流的filter 是 color convert filter 所以有可能是他不支援 dynamic format change 囉

那我 dynamic format change m_pOutput->SetMediaType(&pMediaType);
的做法沒錯了
因為我記得我有成功過 可是改一改後就不行了 Orz
謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/18 上午 08:29:09
通常 trigger dynamic format change 的方式有固定的 calling sequence...你直接設定不一定能成功...可能會被擋掉...
trigger 的方法你可以參考一下MSDN堛漱漁e. (前面我有放連結了)
通常常用的方法. 大概就是 check media type. query accept 或是在 sample 中放 media type...你可以先試看看這幾個 function然後檢查一下回傳值. 有時回傳值可以知道為什麼不成功..
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/18 下午 04:05:37
我參考網頁
IPin* pDownIn;
HRESULT hr = m_pOutput->ConnectedTo(&pDownIn);
hr = pDownIn->QueryAccept(&pMediaType);
是m_falut 看起來是 Color convert filter 不支援 dynamic format change 囉

那請問我可不可以先disconnect 在connect
讓filter 再跑一次 GetMediaType 呢??

IPin* pDownIn;
HRESULT hr = m_pOutput->ConnectedTo(&pDownIn);
REFERENCE_TIME a;
this->m_pClock->GetTime(&a);
hr = this->Stop();
hr = m_pOutput->Disconnect();
hr = m_pOutput->BreakConnect();
hr = m_pOutput->SetMediaType(&pMediaType);
hr = m_pOutput->ReceiveConnection(pDownIn,&pMediaType);
hr = this->Run(a);
這是我的想法 可是結果卻是灰色一片 沒有反應

請問這個想法不對嗎 還是我疏忽了嗎

謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/18 下午 07:02:29
你參考一下IFilterGraph::Disconnect..
http://msdn.microsoft.com/en-us/library/dd390018(VS.85).aspx
斷pin要兩邊一起斷才可以..不然沒用.

你想要用斷 PIN 的方法來重建的話..會麻煩些...你參考一下..
http://msdn.microsoft.com/en-us/library/dd388737(VS.85).aspx
這堶惘陷ㄗ鴢蝏糬垂..

不是很確定...但是我印象中, color space coverter應該有能力處理run time 的 resolution change才對..
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/18 下午 08:04:35
我也有是過兩邊一起 disconnect

可是再重連的時候
hr = m_pOutput->ReceiveConnection(pDownIn,&pMediaType);

還是灰色一片

真的很感謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/19 下午 05:16:43
CMediaType cmt;
GetMediaType(0,&cmt);
if (S_OK == m_pOutput->GetConnected()->QueryAccept(&cmt)) // 有支援 dnamic format change
{
m_pGraph->Reconnect(m_pOutput);
}
else
{
HRESULT hr = S_OK;
REFERENCE_TIME a;
this->m_pClock->GetTime(&a);

IPin *pDownIn = m_pOutput->GetConnected();
//pDownIn->AddRef(); // or it will go away in Disconnect

IBaseFilter *DownFilter=NULL;
GetNextFilter(this,PINDIR_OUTPUT,&temp);
DownFilter->Stop();
CBaseFilter::Stop();
m_State = State_Stopped;
this->StopStreaming();
this->EndOfStream();

/*IGraphBuilder *pFG;
IMediaControl *pMediaControl;
hr = m_pGraph->QueryInterface( IID_IGraphBuilder, (void **)&pFG);
hrcheck(hr,_T("m_pGraph->QueryInterface( IID_IGraphBuilder, (void **)&pFG);;"));
hr = pFG->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
hrcheck(hr,_T("pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);"));
hr = pMediaControl->Pause();
hrcheck(hr,_T("pMediaControl->Stop();"));*/
hr =this->ReconnectPin(pDownIn,&cmt);
hrcheck(hr,_T("m_pGraph->ReconnectPin(m_pOutput);"));

/*if(m_pOutput->IsStopped() )
{
hr = m_pGraph->Disconnect(pDownIn);
hrcheck(hr,_T(" pDownIn->Disconnect();"));
hr = m_pGraph->Disconnect(m_pOutput);
hrcheck(hr,_T("m_pGraph->Disconnect(m_pOutput);"));
}

IGraphBuilder *pFG;
hr = m_pGraph->QueryInterface( IID_IGraphBuilder, (void **)&pFG);
if (hr == NOERROR)
{
hr = pFG->Connect(m_pOutput, pDownIn);
hrcheck(hr,_T("pFG->Connect(m_pOutput, pDownIn);"));
pFG->Release();
}*/
/*hr = pMediaControl->Run();
hrcheck(hr,_T("pMediaControl->Run();"));
pFG->Release();*/
pDownIn->Release();
this->Run(a);
DownFilter->Run(a);
DownFilter->Release();
this->StartStreaming();
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/19 下午 05:22:00

請問我的 run / stop 方法對嗎 每次都只能跑一個sample 就停住了

而我reconnect 的方法對嗎

每次都卡在 tranfrm.cpp 內的 hr = m_pOutput->m_pInputPin->Receive(pOutSample);

     CMediaType cmt;
     GetMediaType(0,&cmt);
if (S_OK == m_pOutput->GetConnected()->QueryAccept(&cmt)) // 有支援 dnamic format change
{
m_pGraph->Reconnect(m_pOutput);
}
else
{
HRESULT hr = S_OK;
REFERENCE_TIME a;
this->m_pClock->GetTime(&a);
   IPin *pDownIn = m_pOutput->GetConnected();
pDownIn->AddRef(); // or it will go away in Disconnect

   IBaseFilter *DownFilter=NULL;
GetNextFilter(this,PINDIR_OUTPUT,&temp);
DownFilter->Stop();
CBaseFilter::Stop();
m_State = State_Stopped;

hr =this->ReconnectPin(pDownIn,&cmt);
pDownIn->Release();
this->Run(a);
DownFilter->Run(a);
DownFilter->Release();
}

謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/3/21 上午 05:29:15
你不能自己在跑的過程中在自己的filter中去改別的 filter 的狀態...你再參考一下這一頁的說明吧..
http://msdn.microsoft.com/en-us/library/dd388737(VS.85).aspx

我有遇過不少 filter 你想在 running 的過程中偷改狀態的都有 side effect..(剛跑不覺得, 後來就會出現..有些甚至會當掉)


不過, 其實我到現在還沒有遇過需要用到 dynamic reconnect 的 case 過(真的需要reconnect...就在建 graph 時動手腳...圖建到一半..run 圖, stop, 再接著建圖..不過這種通常是在 graph 堶惘酗H有bug解不掉才會這樣做...), 正常來說, 微軟的filter應該是都有支援dynamic format change的...目前我遇過沒支援 dynamic format change的 filter都是 3rd party的...除非你下游的 filter 是 3rd party的..不然我覺得你應該試著讓 dynamic format change成功會比較簡單...
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/21 上午 05:45:28
補充一下...
通常我在產生新的 format 時, 我都是拿現有的 format 然後只修改我要變的部分來用, 不會建一個全新的出來用..
像如果只有 resolution 變的話, 我就只會把 resolution 相關的改掉而已...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/22 下午 03:55:19
我把問題做個整理
web cam-> decoder (H264->RGB32) ->color space convert ->VMR

由於畫面會閃爍(沒有破圖) 所以我加入了一個 color space convert filter
又因 m_pinput 沒有提供寬高資訊 所以我要在filter 中去parser header info 再修改resolution
但是根據網頁
m_pOutput->GetConnected()->QueryAccept(&pMediaType) return error
所以我猜想是 CSC 不支援 dynamic format change

而我修改resolution的code 為
CMediaType pMediaType = m_pOutput->CurrentMediaType();
////修改format///////
VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.ReallocFormatBuffer(sizeof(VIDEOINFO));
pvi->bmiHeader.biWidth = w;
pvi->bmiHeader.biHeight = h;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
SetRect(&pvi->rcSource, 0, 0, w, h);
SetRect(&pvi->rcTarget, 0, 0, w, h);
pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
m_pOutput->SetMediaType(&pMediaType);
我用 m_pOutput->CurrentMediaType(); 來看 寬高是正確的size
我用 m_pOutput->GetMediaType(); 來看 寬高是原先的size

我猜想說是不是要重新 new 一個 IMediaSample 因為IMediaSample *pDest的大小也是原先size
謝謝你的回覆 現在只差這個小地方了

其實我有做 property page 可以讓user 輸入寬高
但這畢竟是逃避問題的方法 想把這個小地方解決
謝謝你的幫忙
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/22 下午 09:37:00
不知你有試過在 media sample 堜 media type 的方法嗎? 在 media sample 堜 media type 也是 trigger dynamic format change 的方法之一....你可以試看看..
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/22 下午 09:53:44
你是指 IMediaSample *pDest
pDest->SetMediaType(&pMediaType) ; 嗎

這個我有試過 不過結果畫面都是黑的

他就不會再回來 Transform()這個函式了

謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/23 下午 04:17:46
請問 我現在似乎是卡在 buffer size 這個地方

如果我參考網頁作法QueryAccept (Downstream)
http://msdn.microsoft.com/en-us/library/dd377488(VS.85).aspx

這個意思是指說 我要自己繼承寫一個 output pin 嗎??

因為在filter 中不能使用output pin 內的 IMemAllocator變數

這樣看起來困難重重的樣子 Orz
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/25 下午 12:39:48
通常不管成不成功, 都應該是要回來的..
你會沒回來表示你的media type 的設定有問題, 你可以從這著手去查看看..(ex..你可以先做一下目前會work的media type..., size大小是不用變的..然後往下送, 基本上應該要正常才是..)

>你是指 IMediaSample *pDest
>pDest->SetMediaType(&pMediaType) ; 嗎
>
>這個我有試過 不過結果畫面都是黑的
>
>他就不會再回來 Transform()這個函式了
>
>謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/3/25 下午 10:28:03

如果media type 都不改變的話

data flow 都是正常的

謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/2 下午 05:33:18

我現在已經可以把 color space convert filter 取代掉了 直接接 VMR
可是還是有問題

我的code 是
     if(m_pOutput && m_pOutput->IsConnected())
    {
     if (S_OK == m_pOutput->GetConnected()->QueryAccept(&NewMediaType))
{
m_pGraph->Reconnect(m_pOutput);
}
    }

現在卡在 m_pGraph->Reconnect
錯誤訊息是 "因為篩選器狀態不正確,所以無法執行作業。"

是要我先stop 在 run 嗎?? 可是我stop 後就run 不起來了

謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/2 下午 06:17:05
你的動作是 dynamic reconnect. 我很少遇到filter 有支援 dynamic reconnect的. 你遇到的錯誤就是指他不支援在 running 時做reconnect.

我建議你還是利用在media sample堻] media type的方式來 trigger dynamic format change..
目前我遇到支援 dynamic format change 的filter都會支援這個方式...你可以先試看看..

>
>我現在已經可以把 color space convert filter 取代掉了 直接接 VMR
>可是還是有問題
>
>我的code 是
> if(m_pOutput && m_pOutput->IsConnected())
> {
> if (S_OK == m_pOutput->GetConnected()->QueryAccept(&NewMediaType))
> {
> m_pGraph->Reconnect(m_pOutput);
> }
> }
>
>現在卡在 m_pGraph->Reconnect
>錯誤訊息是 '因為篩選器狀態不正確,所以無法執行作業。'
>
>是要我先stop 在 run 嗎?? 可是我stop 後就run 不起來了
>
>謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/2 下午 09:57:18

>你的動作是 dynamic reconnect. 我很少遇到filter 有支援 dynamic reconnect的. 你遇到的錯誤就是指他不支援在 running 時做reconnect.
>
>我建議你還是利用在media sample堻] media type的方式來 trigger dynamic format change..
>目前我遇到支援 dynamic format change 的filter都會支援這個方式...你可以先試看看..

你的意思是指
IMediaSample *pDest
pDest->SetMediaType(&pMediaType) ;



我參考過網頁作法
QueryAccept (Downstream)
http://msdn.microsoft.com/en-us/library/dd377488(VS.85).aspx
請問網頁的意思是指說 我要自己繼承寫一個 output pin 嗎??
因為在filter 中不能使用output pin 內的 IMemAllocator變數
所以要自己寫一個嗎

請問是指哪一種呢??
或是還有其他的 trigger dynamic format change 方法呢
謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/4 上午 12:52:27
因為 filter 是你自己寫的, 所以你的 filter 中, 應該至少會有一個 function 會遇到 media sample. (就是他的 參數堶惘陰a media sample的), 這個function 通常就是你在填media sample資料的地方...你設定 media type 就可以在這個function內著手...
設定的 media type, 你可以把在pin中的m_mt這個member(CBasePin的Protected Member Variables)拿來改一下然後設定下去..在IPin 這個interface堣]有
IPin::ConnectionMediaType, 這個也能抓到 media type...但是要記得的是...設定media type 的事只能做一次, 第二次以後media type就要設定成 NULL...不然後面的filter可能會遇到一些問題..

基本上你設定的方式沒錯, 但是重點是要對真正會送下去的media sample做設定就可以了..

也因為filter是你自己的, 所以你一定拿得到 自己output pin的pointer...你可以查一下你的class的member..堶捧|有一個member variable 是記你的output pin的 pointer, 只要能拿到這個pointer就好了...至於output pin要不要自己寫應該是沒什麼差才對...

作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/6 下午 03:24:19

不好意思又來請教了

請問在用 ffmpeg encoder 時

有沒有參數可以調整他的壓縮率呢??

我改了很多 AVCodecContext 內的參數 (bit_rate , sample_rate) 都沒有效果

請問你有改過壓縮率嗎

謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/6 下午 04:30:11
我在
HRESULT CMyH264Decoder::Transform(IMediaSample *pIn, IMediaSample *pOut) 內
設定新的 media type

     CMediaType pMediaType = m_pOutput->CurrentMediaType(); //回傳 m_mt
     ////修改format///////
     VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.Format();
    
     pvi->bmiHeader.biWidth = m_Fwidth;
     pvi->bmiHeader.biHeight = m_Fheight;
     pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
     SetRect(&pvi->rcSource, 0, 0, m_Fwidth, m_Fheight);
     SetRect(&pvi->rcTarget, 0, 0, m_Fwidth, m_Fheight);

     pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
     hr = m_pOutput->SetMediaType(&pMediaType);
     hr = pDest->SetMediaType(&pMediaType);

這樣還是不行 Orz
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/6 下午 05:16:50
補充一下

我都是看 pDest->GetSize();

來判斷有沒有成功

他的回傳值都是之前的 old_w*old_h*4

謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/6 下午 07:02:59
你這 sample 我沒看到你填資料的code..不知道你是不是漏了什麼東西.
不過, 你的media type要對 pOut 做設定...不是對 m_pOutput做設定.
你設定完後, media type應該是要在你下一個media sample送下去時, 檢查一下看看有沒有變..
下游的 filter 是在收到media sample之後才會進行dynamic format change. 所以變動要下一次才會知道.


>我在
>HRESULT CMyH264Decoder::Transform(IMediaSample *pIn, IMediaSample *pOut) 內
>設定新的 media type
>
> CMediaType pMediaType = m_pOutput->CurrentMediaType(); //回傳 m_mt
> ////修改format///////
> VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.Format();
>
> pvi->bmiHeader.biWidth = m_Fwidth;
> pvi->bmiHeader.biHeight = m_Fheight;
> pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
> SetRect(&pvi->rcSource, 0, 0, m_Fwidth, m_Fheight);
> SetRect(&pvi->rcTarget, 0, 0, m_Fwidth, m_Fheight);
>
> pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
> hr = m_pOutput->SetMediaType(&pMediaType);
> hr = pDest->SetMediaType(&pMediaType);
>
>這樣還是不行 Orz
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/4/6 下午 07:23:35
ffmpeg 調壓縮率的功能以前我試也是有問題...
他的建議是調video 的quality...
你可以參考一下.
http://rob.opendot.cl/index.php/useful-stuff/ffmpeg-x264-encoding-guide/

x264 – Rate Control Choices
這一段的內容...
ffmpeg堶惘章奰釭熙]定可以改...


>
>不好意思又來請教了
>
>請問在用 ffmpeg encoder 時
>
>有沒有參數可以調整他的壓縮率呢??
>
>我改了很多 AVCodecContext 內的參數 (bit_rate , sample_rate) 都沒有效果
>
>請問你有改過壓縮率嗎
>
>謝謝你的回覆
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/8 上午 10:21:55
不好意思 因 code 貼不完整讓你誤會了
請你在撥空看一下

HRESULT CMyH264Decoder::Transform(IMediaSample *pSource, IMediaSample *pDest)
{
    // Copy the sample data
    BYTE *pSourceBuffer, *pDestBuffer;
    long lSourceSize = pSource->GetActualDataLength();
    long lDestSize = 1280*720*4; //這裡每次都是舊的 buffer size 所以我就先寫死 新的大小
    ASSERT(lDestSize >= lSourceSize);
    if(lSourceSize <= 0)
     return S_OK;

    pSource->GetPointer(&pSourceBuffer);
    pDest->GetPointer(&pDestBuffer);

    // Copy the media type
    AM_MEDIA_TYPE *pMediaType;
    pSource->GetMediaType(&pMediaType);
    pDest->SetMediaType(pMediaType);
    DeleteMediaType(pMediaType);
  
    // Copy the sample times
    REFERENCE_TIME TimeStart, TimeEnd;
    if (NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
    {
     pDest->SetTime(&TimeStart, &TimeEnd);
    }

    pDest->SetSyncPoint(pSource->IsSyncPoint() == S_OK); // Copy the Sync point property
    pDest->SetPreroll(pSource->IsPreroll() == S_OK); // Copy the preroll property
    pDest->SetDiscontinuity(pSource->IsDiscontinuity() == S_OK); // Copy the discontinuity property

    int got_picture = 0;
    int decodedsized = 0;
    while( (lSourceSize-decodedsized) > 0) //表示有解碼資料 且還有input資料還沒解碼完
     {
     // 將會 decoder 兩次
     int ret = m_H264Decoder.ffmpegDecode(pSourceBuffer+decodedsized, lSourceSize-decodedsized, pDestBuffer,got_picture);
     if(ret < 0)
     {
break;
     }
     if( !m_isReconnect) //沒有重連過
     {
     if(m_H264Decoder.ffmpegSize(&m_Fwidth,&m_Fheight)) //size 有變動
     {
m_isReconnect = true;
decodedsized = 0;

     CMediaType pMediaType = m_pOutput->CurrentMediaType();
     ////修改format///////
     VIDEOINFO *pvi = (VIDEOINFO *) pMediaType.Format();
     pvi->bmiHeader.biWidth = m_Fwidth;
     pvi->bmiHeader.biHeight = m_Fheight;
     pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
     //SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered
     //SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle

pMediaType.SetSampleSize(pvi->bmiHeader.biSizeImage);
HRESULT hr = S_OK;
hr = m_pOutput->SetMediaType(&pMediaType);
hr = pDest->SetMediaType(&pMediaType); // 這裡就是您說要改的地方
     pDest->SetActualDataLength(pvi->bmiHeader.biSizeImage);
     }
     }//end if ( !m_isReconnect)
     else if(m_isReconnect ) //檔案 or 重連過 !m_H264DecoderParams.isStream ||
     {
if(got_picture) //
{
pDest->SetActualDataLength(lDestSize);
}
else
{
pDest->SetActualDataLength(0);
}
     decodedsized+=ret;
     dxprintf("Decoder source size %d decoded data size %d",lSourceSize,ret);
     } //end else if ( m_isReconnect)
     }//end while
    return NOERROR;
}
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/8 上午 10:38:04
我參考了一些網路資料及其您提供的網頁
我猜想應該是透過
qmin、qmax、crf
這三個變數來調整壓縮率
可是不論我怎麼更改這三個的值
對於畫面的畫值都沒有任何影響
請問這三個變數該如何設定呢??

謝謝
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/8 上午 11:07:19
我把code 放在

http://codepaste.net/etmdzi

方便你閱讀

謝謝你的幫忙
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人tocute520註記此篇回應為很有道理 2010/4/10 上午 01:47:33
我沒辦法直接 trace code..所以只能先根據我觀察到的地方, 建議你先修改一下.
1. 你現在是所有的情況都會回 S_OK...你要先把 code 改成只有當資料已經收齊一張 frame 後, 一次填到當次的 media sample. 然後在第一個完成的 sample 才做 set media type 的動作. 你丟不完整的 frame 到下游去, 通常會有問題.
2. 沒完成的 frame, 先把資料用 temp buffer存起來. 然後回傳 S_FALSE. 一直到整張 frame 的資料齊了, 再從buffer中 copy 資料出來, 做 step 1的事.
3. 檢查一下你設定的 media type值是不是都符合你的預期...順便做一個測試, 一樣設 media type, 但是資料都不動, 看看會怎麼...

你先試看看有什麼變化吧...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/14 上午 10:05:47

>我沒辦法直接 trace code..所以只能先根據我觀察到的地方, 建議你先修改一下.
>1. 你現在是所有的情況都會回 S_OK...你要先把 code 改成只有當資料已經收齊一張 frame 後, 一次填到當次的 media sample. 然後在第一個完成的 sample 才做 set media type 的動作. 你丟不完整的 frame 到下游去, 通常會有問題.
>2. 沒完成的 frame, 先把資料用 temp buffer存起來. 然後回傳 S_FALSE. 一直到整張 frame 的資料齊了, 再從buffer中 copy 資料出來, 做 step 1的事.

我有截圖 save 看過了 我確定每次往下傳送的都是完整的 frame

>3. 檢查一下你設定的 media type值是不是都符合你的預期...順便做一個測試, 一樣設 media type, 但是資料都不動, 看看會怎麼...
我設定的media type 如果是用GetMediaType 得到的是我要的
可是CurrentMediaType 還是舊的
資料不動沒有改變
>
>你先試看看有什麼變化吧...
>

謝謝你的回覆幫忙
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/4/15 下午 12:46:53
我看到你的 code 有
pDest->SetActualDataLength(0);
你必須確定這一段不會跑到, 不然就是如果跑到的話, 必須要回傳 S_FALSE而不是 NO_ERROR. 這個回傳值會影響到 transform filter 會不會把這次的 sample 送到下游. 沒東西的media sample 是不用送到下游去的.

此外, 你設到 media sample 的 media type 如果是OK, 但是你 get output pin 的 media type是舊的的話,
你可以從

CTransformFilter::SetMediaType

CTransformFilter::CheckTransform
這兩個 function 著手,
看看你在重新設定自己的 media type 時, 是不是有遇到什麼問題...因為這個 media type 的控制權是在我們自己手上,
除非自己的程式有擋, 不然應該是一定會換成功的...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/7/26 下午 05:08:39
不好意思打擾你了

想請教你先前接觸 ffmpeg h264 encoder 的經驗

我現在有一個 h264 encoder

我希望他能輸出三種 profile ( baseline, main, extended) 的 h264 檔案

請問我該如何設定呢??

是設定 AVCodecContext -> profile 嗎

可是我改了以後 用特定的decoder 跑 結果都一樣

不知道您先前有遇到這個問題嗎

謝謝您的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/7/28 下午 11:06:30
當初我使用 ffmpeg 壓 H264, 主要是在測試 iPhone 的相容性, 所以其他的設定我並沒有特別去研究, 但是如果你想要設定libx264的話可以參考下面這個網頁的一些參數, 看看能不能有什麼提示..
http://h264.code-shop.com/trac/wiki/Encoding

如果你是用 3rd party 的video encoder filter的話, 決定的因素會是connect時的media type. 還有那個encoder的profile 設定.
當初我所使用的encoder有他自己設定profile的文件, 堶捧|有參數可以指定我要輸出哪一種profile..so...如果你是用外部的encoder的話, 可能得去找那個encoder提供的文件了...
作者 : tocute520(小飄)
[ 貼文 69 | 人氣 861 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/7/29 上午 10:07:50
再向你請教兩個問題

1. 如果可以用 ffmpeg.exe 下参數 達到的功能

     那換句話說 也可以用ffmpeg sdk 寫程式達到嗎 ??

2. 方便問您之前用的 encoder filter 是哪一個嗎

     因為我是把 ffmpeg 把它包一包 包成h264 encoder filter
 
   
謝謝你的回覆
作者 : pernghy(pernghy) DirectX卓越專家貼文超過500則人氣指數超過30000點
[ 貼文 618 | 人氣 37721 | 評價 2990 | 評價/貼文 4.84 | 送出評價 48 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/7/29 上午 10:14:08
只要是ffmpeg可以下的參數,用自己compile出來的版本(要包含該指示需要的library)一定能達到一樣的功能,你可以直接由source code堿搯捊こ|怎麼跑的就會知道他用了那些函數了和它到底是怎麼設定的。

我之前用的encoder是CyberLink的。
 板主 : 白老鼠(Gary)
 > DirectX - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - DirectX - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
DirectX
1 aming 4010 
2 pernghy 1780 
3 白老鼠(Gary) 1120 
4 Akira 1020 
5 冷眼 980 
6 PLAYER 690 
7 阿西德倫 480 
8 andre 450 
9 小弦 430 
10 藍斯洛 410 
DirectX
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.234375