LINUX.ORG.RU

Почему av_write_frame в FFmpeg такой медленный???

 ,


0

2

Читаю данные с SD карты на одноплатнике и отправляю их по сети через ффмпеговские либы, дамп на передающей стороне выглядит так

Output #0, mjpeg, to 'udp://192.168.1.1:5555':
  Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1920x1080, q=2-31, 10 fps, 90k tbn

решил тут померить почему выдает нагрузку на сеть всего 4мбит/c и оказывается операция av_write_frame занимает в среднем 300-350 мс!!!

В чем может быть причина???

К слову за те же 300 мс с карты удается считать по 4Мбайта

★★★

Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от i-rinat

) ну из того что было в той теме ссылок на доступы из ответов других чатов, не гпт пишет такое

There are a few possible reasons why av_write_frame can be slow in this code:

1. Buffering - By default, avformat uses buffering for writes which can delay actual writes to disk. You can disable buffering by passing AVIO_FLAG_DIRECT to avio_open. This will write packets directly without buffering.

2. Flush latency - Even with buffering disabled, it takes time for data to make it from the application to the disk. Calling av_write_frame does not necessarily mean the data has been written to disk yet. You may need to call av_write_trailer to flush all buffered data.

3. Disk speed - The disk where the file is being written may simply be slow, which limits the write speed. Using a faster disk can improve performance.

4. Format overhead - Some formats require additional processing that can slow down writes. For example, formats that require seeking (like MP4) may be slower than simpler formats (like FLV).

5. Threading - av_write_frame is not thread-safe. If you are calling it from multiple threads, the threads can interfere with each other and reduce performance.

Some things you can try to improve write speed:

1. Disable buffering by passing AVIO_FLAG_DIRECT to avio_open.

2. Call av_write_trailer periodically to flush buffered data.

3. Use a faster disk or SSD. 

4. Choose a simpler format like FLV over MP4.

5. Ensure av_write_frame is only called from a single thread.

I hope this helps explain some possible reasons for the slow writes and gives you some ideas to try and improve the performance. Let me know if you have any other questions!
wolverin ★★★
() автор топика
Ответ на: комментарий от i-rinat

еще варианты

There are a few possible reasons for slow upload speed in this code:

1. Fragmentation - The code splits input JPEG frames into multiple packets, creating overhead from packet headers. This can slow down the upload.

2. Timestamp accuracy - The code uses millisecond timestamps (converted to AVPacket timestamps), which have limited accuracy. This can cause AVFormatContext to pad packets to achieve better accuracy, reducing effective payload size.

3. CPU load - The code is doing a lot of JPEG parsing, buffer copying and other operations on the CPU. This can overload the CPU and slow down the actual network upload.

4. Network buffering - The network stack may be buffering the outgoing packets, causing bursts of fast upload followed by longer pauses. This can average out to slower overall speed.

5. Inefficient I/O - The code is reading from a file on disk. File I/O has more overhead than in-memory I/O, which can impact performance.

Some potential fixes could be:

• Reduce fragmentation by encoding JPEG frames into fewer, larger packets. 
• Use a larger timebase for timestamps (e.g. milliseconds instead of micro seconds) to reduce padding. 
• Offload some CPU-intensive work to other cores or optimize the JPEG parsing. 
• Flush the network buffer periodically to send packets more consistently. 
• Read from memory instead of a file, if possible. 

Without seeing more details on the specific implementation and environment, it's hard to determine the exact cause and solution. But the above points should give some ideas to try improving the upload speed.

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

кстати вариант с миллисекундами очень даже выглядит правдоподоно

про фрагментацию непонятно - т.е. нужно засунуть сразу весь считанный буфер, содержащий несколько кадров, в ав_врайт_фрейм!?

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)
Ответ на: комментарий от wolverin

Не вижу причин, задержек в ffmpeg. Из этого кода выходит, что это аналог ffmpeg -i file.mjpeg -f mjpeg udp://host:port сырой mjpeg как есть валит в udp send, без синхронизации. Если нигде в udp протокол не прилетает bitrate, то нет никаких задержек.

hizel ★★★★★
()
Ответ на: комментарий от hizel

… думаете стоит попробовать налить мжпег файл и послать его через ффмпег

да этот вариант отправки и делал, иба если указывать rtp, то надо подсовывать sdp, а зачем он нужен, если отправляю и получаю я всегда известные с обоих стороны поток.

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

ты можешь на хосте своем запустить так ffmpeg и посмотреть как он работает? энивей, вообще не понятно, зачем тебе в этой схеме ffmpeg, ты можешь выкинуть весь код и слать просто свой mjpeg в udp сокет, поведение принципиально не поменяется

hizel ★★★★★
()
Ответ на: комментарий от hizel

потому что на принимающей стороне я жму в х264 и сохраняю сразу в mp4, при этом принимающая строна сразу используя тот же ффмпег многие параметры берет самостоятельно из получаемого потока (размеры, цветовое пространство и тыды), а если так послать даже не знаю поймет ли ффмпег что в него шлют

сейчас попробовал через ентернеты послать - есть конечно же потери, но более менее, мож и плюнуть что быстрее не высылает, зато терпимое качество для 2Мп

wolverin ★★★
() автор топика
Ответ на: комментарий от wolverin

в том то и дело, что сейчас твой код примерно эквивалентен отправки данных как есть в udp сокет, ты тоже можешь собрать вообще без ffmpeg без изменений на принимающей стороне.

конечно в интернете у тебя будут бится данные

hizel ★★★★★
()
Ответ на: комментарий от hizel

хотелось просто уже используемые в проекте либы применить )

так то высылал через сокеты, но то все мелкие файлы и так для теста возможности проходить через 2 симметричных НАТа

wolverin ★★★
() автор топика
Ответ на: комментарий от i-rinat

похоже нейросеть была где то близко про фрагментацию-буферизацию )

увеличение исходящего буфера до 200К подняло скорость до 50Мбит/с

но помогли здесь http://ffmpeg.org/pipermail/libav-user/2023-April/013356.html

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)

идей про netcat и чтобы им проверить «отдачу с SD по UDP» конечно-же не возникало.

ещё раз: «у вас нет системных проблем со скоростью чтения SD или выдачи udp-ей в сеть»..

у вас есть проблема с внутренней организацией личного кода.

MKuznetsov ★★★★★
()