Napisałem program, który symuluje kamerę i konwertuje wyjście do strumienia wideo. Program musi działać w systemie Windows. Istnieją dwa elementy w systemie:Przesyłanie strumieniowe wideo z obrazu za pomocą FFMPEG na Windows
- Symulator aparatu. Program C++, który symuluje kamerę. Kopiuje on wstępnie wygenerowaną ramkę (to jest plik PNG) co 0,1 sekundy, używając polecenia Windows
copy
, do ścieżki docelowej o strumieniu wideo. Używając FFmpeg, tworzy strumień wideo z kopiowanych obrazów. FFmpeg jest prowadzony za pomocą następującego polecenia:ffmpeg -loop 1 -i ./target/target_image.png -r 10 -vcodec mpeg4 -f mpegts udp://127.0.0.1:1234
Uruchamiając całość razem, to działa dobrze przez kilka sekund, aż przystankach ffmpeg. Oto log podczas pracy w trybie debugowania:
ffmpeg version N-52458-gaa96439 Copyright (c) 2000-2013 the FFmpeg developers
built on Apr 24 2013 22:19:32 with gcc 4.8.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 27.101/52. 27.101
libavcodec 55. 6.100/55. 6.100
libavformat 55. 3.100/55. 3.100
libavdevice 55. 0.100/55. 0.100
libavfilter 3. 60.101/3. 60.101
libswscale 2. 2.100/2. 2.100
libswresample 0. 17.102/0. 17.102
libpostproc 52. 3.100/52. 3.100
Splitting the commandline.
Reading option '-loop' ... matched as AVOption 'loop' with argument '1'.
Reading option '-i' ... matched as input file with argument './target/target_image.png'.
Reading option '-r' ... matched as option 'r' (set frame rate (Hz value, fraction or abbreviation)) with argument '10'.
Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'mpeg4'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'mpegts'.
Reading option 'udp://127.0.0.1:1234' ... matched as output file.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option loglevel (set logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input file ./target/target_image.png.
Successfully parsed a group of options.
Opening an input file: ./target/target_image.png.
[AVIOContext @ 02678840] Statistics: 234307 bytes read, 0 seeks
[AVIOContext @ 02678840] Statistics: 221345 bytes read, 0 seeks
Last message repeated 1 times
[AVIOContext @ 02678840] Statistics: 226329 bytes read, 0 seeks
Last message repeated 2 times
[AVIOContext @ 02678840] Statistics: 228676 bytes read, 0 seeks
Last message repeated 2 times
[AVIOContext @ 02678840] Statistics: 230685 bytes read, 0 seeks
Last message repeated 2 times
[AVIOContext @ 02678840] Statistics: 232697 bytes read, 0 seeks
Last message repeated 5 times
[AVIOContext @ 02678840] Statistics: 234900 bytes read, 0 seeks
Last message repeated 2 times
[AVIOContext @ 02678840] Statistics: 236847 bytes read, 0 seeks
[image2 @ 02677ac0] Probe buffer size limit of 5000000 bytes reached
Input #0, image2, from './target/target_image.png':
Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
Stream #0:0, 22, 1/25: Video: png, rgb24, 1274x772 [SAR 1:1 DAR 637:386], 1/25, 25 fps, 25 tbr, 25 tbn, 25 tbc
Successfully opened the file.
Parsing a group of options: output file udp://127.0.0.1:1234.
Applying option r (set frame rate (Hz value, fraction or abbreviation)) with argument 10.
Applying option vcodec (force video codec ('copy' to copy stream)) with argument mpeg4.
Applying option f (force format) with argument mpegts.
Successfully parsed a group of options.
Opening an output file: udp://127.0.0.1:1234.
Successfully opened the file.
[graph 0 input from stream 0:0 @ 02769280] Setting 'video_size' to value '1274x772'
[graph 0 input from stream 0:0 @ 02769280] Setting 'pix_fmt' to value '2'
[graph 0 input from stream 0:0 @ 02769280] Setting 'time_base' to value '1/25'
[graph 0 input from stream 0:0 @ 02769280] Setting 'pixel_aspect' to value '1/1'
[graph 0 input from stream 0:0 @ 02769280] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 02769280] Setting 'frame_rate' to value '25/1'
[graph 0 input from stream 0:0 @ 02769280] w:1274 h:772 pixfmt:rgb24 tb:1/25 fr:25/1 sar:1/1 sws_param:flags=2
[format @ 02768ba0] compat: called with args=[yuv420p]
[format @ 02768ba0] Setting 'pix_fmts' to value 'yuv420p'
[auto-inserted scaler 0 @ 02768740] Setting 'w' to value '0'
[auto-inserted scaler 0 @ 02768740] Setting 'h' to value '0'
[auto-inserted scaler 0 @ 02768740] Setting 'flags' to value '0x4'
[auto-inserted scaler 0 @ 02768740] w:0 h:0 flags:'0x4' interl:0
[format @ 02768ba0] auto-inserting filter 'auto-inserted scaler 0' between the filter 'Parsed_null_0' and the filter 'format'
[AVFilterGraph @ 026772c0] query_formats: 4 queried, 3 merged, 1 already done, 0 delayed
[auto-inserted scaler 0 @ 02768740] w:1274 h:772 fmt:rgb24 sar:1/1 -> w:1274 h:772 fmt:yuv420p sar:1/1 flags:0x4
[mpeg4 @ 02785020] detected 4 logical cores
[mpeg4 @ 02785020] intra_quant_bias = 0 inter_quant_bias = -64
[mpegts @ 0277da40] muxrate VBR, pcr every 1 pkts, sdt every 200, pat/pmt every 40 pkts
Output #0, mpegts, to 'udp://127.0.0.1:1234':
Metadata:
encoder : Lavf55.3.100
Stream #0:0, 0, 1/90000: Video: mpeg4, yuv420p, 1274x772 [SAR 1:1 DAR 637:386], 1/10, q=2-31, 200 kb/s, 90k tbn, 10 tbc
Stream mapping:
Stream #0:0 -> #0:0 (png -> mpeg4)
Press [q] to stop, [?] for help
*** drop!
Last message repeated 10 times
frame= 11 fps=0.0 q=4.0 size= 118kB time=00:00:01.10 bitrate= 875.1kbits/s dup=0 drop=11
Statistics: 242771 bytes read, 0 seeks
[AVIOContext @ 02674a60] Statistics: 246525 bytes read, 0 seeks
*** drop!
[AVIOContext @ 02674a60] Statistics: 230678 bytes read, 0 seeks
[AVIOContext @ 02674a60] Statistics: 244023 bytes read, 0 seeks
*** drop!
[AVIOContext @ 02674a60] Statistics: 246389 bytes read, 0 seeks
*** drop!
[AVIOContext @ 02674a60] Statistics: 224478 bytes read, 0 seeks
[AVIOContext @ 02674a60] Statistics: 228013 bytes read, 0 seeks
*** drop!
[image2 @ 02677ac0] Could not open file : ./target/target_image.png
./target/target_image.png: Input/output error
[output stream 0:0 @ 02768c20] EOF on sink link output stream 0:0:default.
No more output streams to write to, finishing.
frame= 164 fps= 17 q=31.0 Lsize= 959kB time=00:00:16.40 bitrate= 478.9kbits/s dup=0 drop=240
video:869kB audio:0kB subtitle:0 global headers:0kB muxing overhead 10.285235%
404 frames successfully decoded, 0 decoding errors
[AVIOContext @ 026779c0] Statistics: 0 seeks, 746 writeouts
Wydaje mi się tam jakaś kolizji między czytania i pisania do/z tego samego pliku. Co ciekawe, na Linuksie (zastępując copy
z cp
) program działa dobrze.
Czy ktoś może zaproponować sposób rozwiązania tego problemu? Rozwiązania alternatywne są również dopuszczalne, o ile logiczny przepływ pracy pozostaje taki sam.
Dzięki! Wydaje się, że jest niewielka poprawa, ponieważ ffmpeg ulega awarii po dłuższym czasie działania, ale problem nadal występuje. Nadal uważam, że jest to problem z synchronizacją. Nawet jeśli obrazy są kopiowane z prędkością 10 klatek na sekundę, a ffmpeg odczytuje obraz z prędkością 10 klatek na sekundę, jest szansa, że oba procesy uzyskają dostęp do pliku w tym samym czasie, prawda? –
Tak, to prawda. Być może możesz spojrzeć w kierunku rurociągu, jak przy użyciu '-f image2pipe'. Nigdy tego nie używałem, więc nie jestem pewien, czy to prawda. –