Я хотел бы представить сценарий и обсудить подходящие шаблоны проектирования для его решения.
Рассмотрим простую ситуацию: камера записывает в буфер памяти в течение десяти секунд, прежде чем остановиться. После завершения записи открывается дескриптор двоичного файла, и данные передаются на диск.
Основным ограничением этого подхода является то, что запись ограничивается доступным размером оперативной памяти. Однако потеря кадров может и не быть проблемой.
Чтобы смягчить эту проблему, одним из возможных решений является использование выделенного потока или процесса для записи на диск. В этой настройке буфер памяти производителя используется совместно между основным потоком/процессом и записывающим потоком. Однако при этом возникает новая проблема: когда поток записи блокирует буфер, камера может оказаться неспособной разместить новые кадры, что может привести к потере кадров.
Вопрос >
Существует ли шаблон проектирования, который решает проблему, описанную во втором сценарии?
Ниже приведены примеры кода для двух сценариев на Python.
Первый сценарий на Python:
import io
from picamera2 import Picamera2
from picamera2.encoders import Encoder as NullEncoder
from picamera2.outputs import FileOutput
# Init camera
cam = Picamera2()
# Init memory buffer
mem_buff = io.BytesIO()
mem_out = FileOutput(mem_buff)
# Open camera
cam.start()
# Just writes frames without encoding i.e.: BGR888
encoder = NullEncoder()
# Recording time
to_record = 10
print(f"Start recording for {to_record} seconds")
cam.start_recording(encoder, mem_out)
time.sleep(to_record)
cam.stop_recording()
print("Finish recording")
cam.close()
# Begin data transfer to disk
out_fpath = "video.bin"
disk_transfer_start = time.perf_counter()
with open(out_fpath, "wb") as fd:
fd.write(mem_buff.getvalue())
disk_transfer_el = time.perf_counter() - disk_transfer_start
print(f"Data transfer took {disk_transfer_el} sec")
# Get a sense of how many frames are missing
totbytes = os.path.getsize(out_fpath)
byteel = 2304*1296*3 # (frame_width * frame_height * num_channels)
num_frames = totbytes / byteel
print(f"Video has {num_frames} frames")
Возможная реализация второго сценария на Python:
import io
from threading import Thread, Event, Lock
from picamera2 import Picamera2
from picamera2.encoders import Encoder as NullEncoder
from picamera2.outputs import FileOutput
def disk_writer(mem_buff: io.BytesIO, bin_fd, write_interval: int, stop_event: Event, lock: Lock):
while not stop_event.is_set():
start_loop = time.perf_counter()
lock.acquire()
curr_buff_pos = mem_buff.tell()
lock.release()
if curr_buff_pos > 0:
lock.acquire()
bin_fd.write(mem_buff.getvalue())
mem_buff.seek(0)
mem_buff.truncate(0)
lock.release()
elapsed = time.perf_counter() - start_loop
if elapsed < write_interval:
time.sleep(write_interval - elapsed)
if mem_buff.tell() > 0:
bin_fd.write(mem_buff.getvalue())
mem_buff.seek(0)
mem_buff.truncate(0)
# Init camera
cam = Picamera2()
# Init memory buffer
mem_buff = io.BytesIO()
mem_out = FileOutput(mem_buff)
# Get output file descriptor
bin_fd = open("video.bin", "wb")
# Open camera
cam.start()
# Create writing thread and start
stop_event = Event()
lock = Lock()
write_interval = 5
writer_thread = Thread(target=disk_writer, args=(mem_buff, bin_fd, write_interval, stop_event, lock))
writer_thread.start()
# Just writes frames without encoding i.e.: BGR888
encoder = NullEncoder()
# Recording time
to_record = 10
print(f"Start recording for {to_record} seconds")
cam.start_recording(encoder, mem_out)
time.sleep(to_record)
cam.stop_recording()
print("Finish recording")
stop_event.set()
writer_thread.join()
cam.close()
bin_fd.close()
# Get a sense of how many frames are missing
totbytes = os.path.getsize(out_fpath)
byteel = 2304*1296*3 # (frame_width * frame_height * num_channels)
num_frames = totbytes / byteel
print(f"Video has {num_frames} frames")
Подробнее здесь: https://stackoverflow.com/questions/791 ... s-possible
Из буфера памяти на диск как можно быстрее ⇐ Python
Программы на Python
-
Anonymous
1731595650
Anonymous
Я хотел бы представить сценарий и обсудить подходящие шаблоны проектирования для его решения.
Рассмотрим простую ситуацию: камера записывает в буфер памяти в течение десяти секунд, прежде чем остановиться. После завершения записи открывается дескриптор двоичного файла, и данные передаются на диск.
Основным ограничением этого подхода является то, что запись ограничивается доступным размером оперативной памяти. Однако потеря кадров может и не быть проблемой.
Чтобы смягчить эту проблему, одним из возможных решений является использование выделенного потока или процесса для записи на диск. В этой настройке буфер памяти производителя используется совместно между основным потоком/процессом и записывающим потоком. Однако при этом возникает новая проблема: когда поток записи блокирует буфер, камера может оказаться неспособной разместить новые кадры, что может привести к потере кадров.
[b]Вопрос[/b] >
Существует ли шаблон проектирования, который решает проблему, описанную во втором сценарии?
Ниже приведены примеры кода для двух сценариев на Python.
Первый сценарий на Python:
import io
from picamera2 import Picamera2
from picamera2.encoders import Encoder as NullEncoder
from picamera2.outputs import FileOutput
# Init camera
cam = Picamera2()
# Init memory buffer
mem_buff = io.BytesIO()
mem_out = FileOutput(mem_buff)
# Open camera
cam.start()
# Just writes frames without encoding i.e.: BGR888
encoder = NullEncoder()
# Recording time
to_record = 10
print(f"Start recording for {to_record} seconds")
cam.start_recording(encoder, mem_out)
time.sleep(to_record)
cam.stop_recording()
print("Finish recording")
cam.close()
# Begin data transfer to disk
out_fpath = "video.bin"
disk_transfer_start = time.perf_counter()
with open(out_fpath, "wb") as fd:
fd.write(mem_buff.getvalue())
disk_transfer_el = time.perf_counter() - disk_transfer_start
print(f"Data transfer took {disk_transfer_el} sec")
# Get a sense of how many frames are missing
totbytes = os.path.getsize(out_fpath)
byteel = 2304*1296*3 # (frame_width * frame_height * num_channels)
num_frames = totbytes / byteel
print(f"Video has {num_frames} frames")
Возможная реализация второго сценария на Python:
import io
from threading import Thread, Event, Lock
from picamera2 import Picamera2
from picamera2.encoders import Encoder as NullEncoder
from picamera2.outputs import FileOutput
def disk_writer(mem_buff: io.BytesIO, bin_fd, write_interval: int, stop_event: Event, lock: Lock):
while not stop_event.is_set():
start_loop = time.perf_counter()
lock.acquire()
curr_buff_pos = mem_buff.tell()
lock.release()
if curr_buff_pos > 0:
lock.acquire()
bin_fd.write(mem_buff.getvalue())
mem_buff.seek(0)
mem_buff.truncate(0)
lock.release()
elapsed = time.perf_counter() - start_loop
if elapsed < write_interval:
time.sleep(write_interval - elapsed)
if mem_buff.tell() > 0:
bin_fd.write(mem_buff.getvalue())
mem_buff.seek(0)
mem_buff.truncate(0)
# Init camera
cam = Picamera2()
# Init memory buffer
mem_buff = io.BytesIO()
mem_out = FileOutput(mem_buff)
# Get output file descriptor
bin_fd = open("video.bin", "wb")
# Open camera
cam.start()
# Create writing thread and start
stop_event = Event()
lock = Lock()
write_interval = 5
writer_thread = Thread(target=disk_writer, args=(mem_buff, bin_fd, write_interval, stop_event, lock))
writer_thread.start()
# Just writes frames without encoding i.e.: BGR888
encoder = NullEncoder()
# Recording time
to_record = 10
print(f"Start recording for {to_record} seconds")
cam.start_recording(encoder, mem_out)
time.sleep(to_record)
cam.stop_recording()
print("Finish recording")
stop_event.set()
writer_thread.join()
cam.close()
bin_fd.close()
# Get a sense of how many frames are missing
totbytes = os.path.getsize(out_fpath)
byteel = 2304*1296*3 # (frame_width * frame_height * num_channels)
num_frames = totbytes / byteel
print(f"Video has {num_frames} frames")
Подробнее здесь: [url]https://stackoverflow.com/questions/79188039/from-memory-buffer-to-disk-as-fast-as-possible[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия