[問題] 兩程式間傳資料 stdout 與 stdin 的問題
遇到的問題: (題意請描述清楚)
由於影音轉檔需要,要用到 avs2wav 把資料由 stdout 輸出給 NeroAACEnc 轉檔
程式用途:
PS: avs 是一種偽裝avi檔的 frame server,用來把各種格式的影音檔
偽裝成 avi 給程式如 x264 去轉換
avs2wav --> 把 avs (Avisynth) 轉成 wav,或者 stdout 輸出
NeroAACEnc --> 把 wav 轉成 aac,可吃 stdin
lame --> 把 wav 轉成 mp3,可吃 stdin
指令:
avs2wav input.avs out.wav
avs2wav input.avs - | neroaacenc -ignorelength -br 128000 -if - -of out.m4a
avs2wav input.avs - | lame -h -b 128 --cbr - out.mp3
但是發現 avs2wav 的 stdout 結果有問題
wav 只能正確輸出不到2秒 接下來都是雜訊
而且大小也不正確
經交叉比對後,不論是由 NeroAACEnc 或者 lame 去轉都一樣失敗
所以可以判斷是 avs2wav 的 stdout 部分有問題
對於 stdout/stdin 實在不太了解
想請問使用 stdout 有什麼要注意的才不會使 stdout 破損?
有想過所遇到的問題或許來自 buffer ?
用了 setvbuf (stdout, NULL, _IONBF, NULL);
或 setvbuf (stdout, buff, _IOFBF, buffs);
其中 char buff[buffs]; // buffs = 超大 或 很小
不管如何狀況都一樣,最終產生的檔案也完全一樣
開發平台: (例: VC++ or gcc/g++ or Dev-C++, Windows or Linux)
VC++ 2008 (原始碼可用 2008 compile)
只要開新專案,把 AVS2WAV.cpp, AVS2WAV.h 加入即可
有問題的code: (請善用置底文標色功能)
分析原始碼,avs2wav 使用的方法如下
FILE* m_Outputfile;
m_OutputFile = stdout;
setmode(1, O_BINARY);
while( ..... ){
fwrite( .....);
}
fclose(m_OutputFile);
補充說明:
avs2wav 來源:
下載頁面 http://www.avisynth.info/?avs2wav
已編譯檔案(含原始碼) http://home.pages.at/kassandro/avs2wav.rar
PS: 由於使用了 VfW 的 avi interface function, 可能需要加上一行
#pragma comment(lib, "Vfw32.lib")
才能正確編譯
NeroAACEnc 來源:
http://www.nero.com/eng/downloads-nerodigital-nero-aac-codec.php
Avisynth: *可能需要安裝,系統才能認識 avs (用 2.5.8)
http://sourceforge.net/projects/avisynth2/files/
所需的檔案一起通包: 檔案都一樣
http://www.mediafire.com/?ljwzvjfiyjm
http://rapidshare.com/files/320068516/Package.zip.html
http://www.megaupload.com/?d=3DFD3LNE
http://www.badongo.com/file/19010795
http://vspace.cc/file/DFLUYBM63S5SJ797.html
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.229.14.202
推
12/13 10:42, , 1F
12/13 10:42, 1F
→
12/13 10:42, , 2F
12/13 10:42, 2F
→
12/13 11:03, , 3F
12/13 11:03, 3F
→
12/13 11:03, , 4F
12/13 11:03, 4F
→
12/13 11:29, , 5F
12/13 11:29, 5F
#include "stdafx.h"
#include <io.h>
int _tmain(int argc, _TCHAR* argv[])
{
FILE* pOut;
int i=0;
char byte;
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);
return 0;
}
倘若無誤的話,我的電腦只能吃到該有的 695,852 中的 1,804 Bytes
比用 NeroAACEnc 或者 lame 還要慘
附上測試用的 stdout 產生器,用65535的大魔王血量長度是測試正常的
#include "stdafx.h"
#include <io.h>
#include <fcntl.h>
int _tmain(int argc, _TCHAR* argv[])
{
_setmode(_fileno( stdout ), _O_BINARY);
for(int i=0;i<65535;i++){
fwrite("a",1,1,stdout);
}
return 0;
}
================================================================
除此之外,另一個軟體 MeGUI
看過原始碼,裡頭用的也是 stdout 送給 audio encoder
位置: \megui\trunk\packages\audio\AudioEncoderInterface.cs
只不過他用的是 C#
看起來有在寫wave檔頭,註解裡也有提到送出資料到 encoder 的 stdin
所以可以判斷 MeGUI 一樣使用 stdout
那既然同樣都是 stdout
MeGUI 可以正確轉檔,avs2wav 卻不行
似乎更可以確定 audio encoder 的 stdin 接收應該沒有問題
而是 avs2wav 的 stdout 有問題
※ 編輯: logs 來自: 125.229.14.202 (12/13 11:49)
推
12/13 13:35, , 6F
12/13 13:35, 6F
→
12/13 13:36, , 7F
12/13 13:36, 7F
→
12/13 13:36, , 8F
12/13 13:36, 8F
→
12/13 13:36, , 9F
12/13 13:36, 9F
推
12/13 13:38, , 10F
12/13 13:38, 10F
推
12/13 13:44, , 11F
12/13 13:44, 11F
→
12/13 13:44, , 12F
12/13 13:44, 12F
→
12/13 13:45, , 13F
12/13 13:45, 13F
→
12/13 13:46, , 14F
12/13 13:46, 14F
→
12/13 13:48, , 15F
12/13 13:48, 15F
→
12/13 13:49, , 16F
12/13 13:49, 16F
→
12/13 13:50, , 17F
12/13 13:50, 17F
→
12/13 13:52, , 18F
12/13 13:52, 18F
→
12/13 13:53, , 19F
12/13 13:53, 19F
→
12/13 13:53, , 20F
12/13 13:53, 20F
→
12/13 14:13, , 21F
12/13 14:13, 21F
→
12/13 14:13, , 22F
12/13 14:13, 22F
討論串 (同標題文章)
以下文章回應了本文:
完整討論串 (本文為第 1 之 2 篇):