推 LPH66:唔...剛剛拿了個比較程式去比發現了一個嚴重的問題: 12/13 13:35
→ LPH66:avs2wav 在 scanning 時會輸出 MPEG 1.0 layer II ...的訊息 12/13 13:36
→ LPH66:但這些訊息並不是送去 stderr 的 而是送去 stdout 的...||| 12/13 13:36
→ LPH66:所以當輸出檔也輸出到 stdout 就會全部寫入檔案裡...orz 12/13 13:36
推 LPH66:然後這個訊息貌似不在 avs2wav.cpp 裡面..|| 12/13 13:38
推 LPH66:OK, 確認問題是在那個地方了 orz 那個東西以外都是一樣的 12/13 13:44
如您所說,在很奇怪的地方,被加一些料到 stdout stream 中
用了簡單的 fprintf 已找出在 Avs2Ogg::ReadHeaders () 中的
while (bMoreStreams) {
...
ret = AVIFileGetStream(m_AVIFile, &myAVIStream, 0, currentAVIStream);
...
ret = AVIStreamInfo(myAVIStream, &myAVIStreamInfo,
sizeof(myAVIStreamInfo));
...
}
上面分別呼叫的兩個函式 AVIFileGetStream, AVIStreamInfo
其中第一個在第一次呼叫時居然會自動印出 MPEG 1.0 layer II ...的訊息
而且被強制送到 stdout
另外仔細觀察發現那個 MPEG 1.0 layer II ...的訊息
假設完整長度是 20 (隨意舉例,沒去數)
標準 WAVE 檔頭是 RIFF 開頭
這個錯誤的 stdout 會在 RIFF 前面塞一大堆 MPEG 1.0 layer II ...
而且長度不是 20 的倍數,會不完整好像是 padding 字串一樣
而這部份很神奇的解法,居然是在 while 上面加一行
fprintf (stdout, ""); // 送出空字串到 stdout
就把這部份的詭異訊息屏蔽掉了 ....XD
但是這個 stdout 的 bug 還沒有完結
拿出 fc /b 作比較,address=0x4 的地方
也就是 緊接著 RIFF 四個字的字串後的 long 值 (Chunk Data Size)
就不一樣啦
PS: WAVE Header Format
http://www.sonicspot.com/guide/wavefiles.html
平平都是一樣的 code 只差在 stdout 或是 檔案模式
怎麼連計算的結果都不一樣捏?
更怪的是後來用舊版程式再跑一遍
那個 "padding" 也不再出現了
(有 exit 再重回 console 也一樣 --> 大概要重開機 bug 才會再現吧)
再來的不同是 0x60000 之後 那個 MPEG 1.0 layer II 又來了
源於 AVIStreamRead()
還會產生兩次的 MPEG 1.0...
音軌錯誤就是斷在這裡
此外,手動去掉第二段的 MPEG 1.0 layer II 之後
結尾還多了 8 Bytes 的奇異資料
總而言之,真的只要把 MPEG 1.0 layer II 去掉
播放起來就沒有差別
可是 fprintf(stdout,""); 只能去掉第一段...
第二段就沒輒了
有辦法在呼叫 AVIStreamRead() 以前讓 他的 stdout 還是 stderr
不要真的背送出 stdout
然後呼叫完畢以後才還原?
=============
關於之前的讀 stdin 測試程式已修正完畢,感謝!
→ LPH66:然後你的測試程式的問題在於你用了 text mode 讀 stdin... 12/13 13:44
→ LPH66:所以碰到 0x1A 就被認為是 EOF 了 12/13 13:45
感謝指點, 忘記加了 setmode binary, 加了之後就可以讀了
#include "stdafx.h"
#include <io.h>
#include <fcntl.h>
int _tmain(int argc, _TCHAR* argv[])
{
FILE* pOut; int i=0; char byte;
_setmode(_fileno( stdin ), _O_BINARY);
fopen_s(&pOut,"stdouts.wav","wb");
while (fread(&byte,1,1,stdin))
i++; fwrite(&byte,1,1,pOut);
printf("gets %d bytes from stdin\n",i);
fclose(pOut);
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.229.2.42
→ logs:問題絕大部分已經解決了喔, 用 CreatePipe() 把正確的導出 12/16 14:53
→ logs:最後多出的 8 byte 來自於原始程式想在 stdout 用 fseek 12/16 15:30
→ logs:但是覆水難收,這樣是不可行的,所以就附加在檔尾 12/16 15:31
→ logs:offset=4 也就是第5個 byte 開始的 4byte 錯誤 12/16 15:32
→ logs:源自於原始程式碼對檔案大小的錯誤估計. 修正後就正常了 12/16 15:32
推 VictorTom:推一下原po查出問題有回來總結:) 12/16 16:05