Re: [問題] 兩程式間傳資料 stdout 與 stdin 的問題
經分析發現, AVS2WAV 使用的 AVIStreamRead()
會莫名奇妙產生兩次 MPEG 1.0 layer II ... 的訊息到 stdout 流中
使得後面用 stdin 來吃資料的程式會錯誤
但是後面的程式不能改
AVIStreamRead() 沒有原始碼 ( 參考 Vfw.h )
有沒有辦法在程式呼叫 AVIStreamRead() 以前
讓一切不管是 stdout 還是 stderr 都不要被 stdout
然後呼叫完以後才還原
==============以下是囉哩八唆的分析,問題已陳述在上======================
推
12/13 13:35,
12/13 13:35
→
12/13 13:36,
12/13 13:36
→
12/13 13:36,
12/13 13:36
→
12/13 13:36,
12/13 13:36
推
12/13 13:38,
12/13 13:38
推
12/13 13:44,
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 測試程式已修正完畢,感謝!
→
12/13 13:44,
12/13 13:44
→
12/13 13:45,
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
→
12/16 14:53, , 1F
12/16 14:53, 1F
→
12/16 15:30, , 2F
12/16 15:30, 2F
→
12/16 15:31, , 3F
12/16 15:31, 3F
→
12/16 15:32, , 4F
12/16 15:32, 4F
→
12/16 15:32, , 5F
12/16 15:32, 5F
推
12/16 16:05, , 6F
12/16 16:05, 6F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):