質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Q&A

0回答

4542閲覧

OpenCvSharp で RTSPストリーム を複数スレッド録画した場合に受信量に差が出ます

teratera7964

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

0グッド

0クリップ

投稿2020/08/28 08:35

編集2020/09/14 03:07

C#でOpenCvSharpを使ってRTSPストリームを録画しています。

以下に示すソースの様なスレッドを作り、
同じfps, framewidth, frameheightのRTSPストリーム6本に対して
6スレッド起動、6本を同時録画しています。

そこでなぜか、ほぼ同じデータ量のRTSPストリーム6本なのにも関わらず、
起動した順に若いほうのスレッドほど保存ファイルのサイズ(ソース中の
dstFile)が大きい事に気づきました。

(以下FPS=10と仮定して書きます)
vSrc が IsOpened だったら Read する、というループなのですが、
敢えて Sleep を入れていません。
これが原因なんだろうな、とは思うのですが。。

1秒間にReadが10回だけ呼ばれる様に、
残り時間をミリミリ確認しながら正しくSleepさせる必要がある?

何故だ?

そもそもストリームには1秒間に10フレームしか届いて来ないのだから
先走って11回目のReadを実行してしまったスレッドは次のフレームが
届くまで待たされる筈で、
待たされたならそのタイミングで別のスレッドが動くんじゃないのか?
と。
vSrc.Read 関数は上記の様なタイムスライスを起こさない、
ブロッキングしてしまう関数、という事なのでしょうか?

ヘタにsleepを入れて記録時間がズレるのも嫌で
ミリミリの質問で恐縮なのですが、
知見のあるかたいらっしゃいましたらよろしくお願い致します。

<スレッドのソースです↓>

C#

1 /// <summary> 2 /// 録画スレッド 3 /// </summary> 4 /// <param name="dstFolder"></param> 5 /// <param name="srcURL"></param> 6 private void RecThread(string dstFile, string srcURL) 7 { 8 PUTLOG("Thread started. ----------------------------------------------------------"); 9 10 VideoWriter vDst = null; 11 12 while(true) 13 { 14 try 15 { 16 int fourcc = VideoWriter.FourCC('m', 'p', '4', 'v'); 17 VideoCapture vSrc = new VideoCapture(srcURL); 18 19 PUTLOG("RTSP stream is opened."); 20 PUTLOG("source :" + srcURL); 21 PUTLOG("fps :" + vSrc.Fps); 22 PUTLOG("frame width :" + vSrc.FrameWidth); 23 PUTLOG("frame height :" + vSrc.FrameHeight); 24 25 vDst = new VideoWriter(dstFile, fourcc, vSrc.Fps, new OpenCvSharp.Size(vSrc.FrameWidth, vSrc.FrameHeight), true); 26 27 PUTLOG("Capturing start..."); 28 29 while (vSrc.IsOpened()) 30 { 31 Mat mat = new Mat(); 32 try 33 { 34 if (vSrc.Read(mat)) 35 { 36 if (mat.IsContinuous()) 37 { 38 if (vDst != null) 39 { 40 vDst.Write(mat); 41 } 42 } 43 else 44 { 45 break; 46 } 47 } 48 else 49 { 50 break; 51 } 52 mat.Dispose(); 53 } 54 catch (Exception e) 55 { 56 PUTLOG("error : " + e.Message); 57 } 58 } 59 vSrc.Dispose(); 60 if (vDst != null) vDst.Dispose(); 61 62 PUTLOG("error : the RTSP stream is unknowingly closed. try reopening.. "); 63 } 64 catch (Exception e) 65 { 66 PUTLOG("error : " + e.Message); 67 } 68 Thread.Sleep(60000); 69 } 70 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2020/08/31 08:54

知見は全くありません。以下完全な妄想です。 まずマークダウン記法でソースのインデントを正確にしてください。 動画はfpsと解像度が同じだけで同じサイズが保証されるわけではありませんよね。 またストリーミングはリアルタイムなので、ある程度の通信異常に耐えられるような作りになってる(UDPにしたりして欠損に柔軟に対処する)と思うので、受け手の状況次第で内容が変わることもあるのではないでしょうか? 傾向として後に受信処理を起動したスレッドほどサイズが小さい規則性があるとして、何が原因と考えられると言ってるのでしょう? コードはインデントされてないので見てません。
teratera7964

2020/09/14 03:13

回答ありがとうございます(コード崩れ、返事遅れ、重ねて失礼しました)。 >受け手の状況次第で内容が変わることもあるのではないでしょうか? はい、そう思います。ですので受け手側は下手にsleepなどせず来たものを素直に読む、としないと時間ずれが生じるだろうと思っています。 > 傾向として後に受信処理を起動したスレッドほどサイズが小さい規則性があるとして、何が原因と考えられると言ってるのでしょう? 先に起動したスレッドほど優先的に受信処理される様な事が起きてたりしないかな?と思っています。
dameo

2020/09/14 06:37

ソースをチラっと見ましたが、内容を理解して書いているコメントに見えないので、私はこれで失礼します。 よく分からずにコピペで作ったソフトがご自身の想定どおりに動かないからといって、他人に聞くのはどうかと思いますよ。自分の力で作らないと、あなたのためになりません。95%理解していて、こう書けばこう動くはずなのに、違う形で動作する、という話なら、こちらも勘違いした5%を説明するだけで済みます。しかし、どう動くのか分からないものをとりあえずコピペしたらなんか動いたっぽいけど、期待したのと違うから、期待どおりに動かすにはどうしたらいいのか?だと、あなたが理解して書いた部分が0%なので、説明しようがないのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問