OpenCV 2.0 の cv::VideoWriter.open() で fourcc に "hymt" や "DIB " を与えるとこけるのをなんとかした

OpenCV 2.0.0a め,内蔵の FFMPEG が未知の FOURCC なら throw なんかしてないでおとなしく false を返せよ.そして cvCreateVideoWriter_VFW() 実行に進ませろよ」

FOURCC が "hymt" のとき,次のメッセージが現れる.

OpenCV Error: Unsupported format or combination of formats (FFMPEG could not fin
d a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto
selection.) in CvVideoWriter_FFMPEG::open, file c:\Software\Develop\opencvlibrar
y\OpenCV2.0\src\highgui\cvcap_ffmpeg.cpp, line 1234

メッセージで示されている部分はここ.

	const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
        if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ){
			CV_ERROR( CV_StsUnsupportedFormat,
				"FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection." );
		}
	}

強引に変えてライブラリをビルドし直す.bin/ と lib/ を上書きし,試行するとうまくいった.

	const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL};
        if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ){
			// insert 2 lines
			perror("FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection." );
			return false;
			// original: return false しているから無視される
			CV_ERROR( CV_StsUnsupportedFormat,
				"FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOURCC_DEFAULT for auto selection." );
		}

上記のとおり変更すると,cvcap_w32.cpp の cvCreateVideoWriter_Win32 で,if() が false != 0 で偽となる.ゆえに無事 cvCreateVideoWriter_VFW() へ移って成功する.

CvVideoWriter* cvCreateVideoWriter_Win32( const char* filename, int fourcc,
                                          double fps, CvSize frameSize, int isColor )
{
    CvVideoWriter_FFMPEG_proxy* result = new CvVideoWriter_FFMPEG_proxy;

    if( result->open( filename, fourcc, fps, frameSize, isColor != 0 ))
        return result;
    delete result;

    return cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, isColor);
}

メッセージはこう変化する.テストコードは後で作る別エントリに掲載する.また,出力される映像ファイルはFOURCC は HYMT とされるものの,実質 "DIB "(圧縮なし)になるようだ.ファイルサイズが変化しない.

FFMPEG could not find a codec matching the given FOURCC code. Use fourcc=CV_FOUR
CC_DEFAULT for auto selection.: Invalid argument
wrote 90 frame(s)

さて,冒頭のエラーは cxsystem.cpp によるものだ.throw exc で止まる.

void error( const Exception& exc )
{
    if (customErrorCallback != 0) 
        customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(),
                            exc.file.c_str(), exc.line, customErrorCallbackData);
    else
    {
        const char* errorStr = cvErrorStr(exc.code);
        char buf[1 << 16];

        sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
            errorStr, exc.err.c_str(), exc.func.size() > 0 ?
            exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
        fprintf( stderr, "%s\n", buf );
        fflush( stderr );
    }
    if(breakOnError)
    {
        static volatile int* p = 0;
        *p = 0;
    }
    throw exc;
}