-
Notifications
You must be signed in to change notification settings - Fork 8
/
decode_frames_shm.py
68 lines (61 loc) · 2.24 KB
/
decode_frames_shm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# -*- coding=utf-8 -*-
# Library: ffio
# Author: dongrixinyu, koisi
# License: MIT
# Email: dongrixinyu.66@gmail.com
# Github: https://github.com/dongrixinyu/ffio
# Description: An easy-to-use Python wrapper for FFmpeg-C-API.
# Website: http://www.jionlp.com
# Note:
# - C log file is written in ~/.cache/ffio/clog-%d.txt.%s
import time
import numpy as np
from multiprocessing import shared_memory
import ffio
# Here is an example that shows you may use a SharedMemory buff,
# which contains some other data and not only one frame.
some_data_bytes = 2 * 4096
rgb_data_bytes = 30 * 1080 * 1920 * 3 # 30 frames of 1080p rgb data.
shm_size = some_data_bytes + rgb_data_bytes
your_shm = shared_memory.SharedMemory(create=True, size=shm_size)
target_url = "rtmp://..."
ffio = ffio.FFIO(
target_url, ffio.FFIOMode.DECODE, False, False,
your_shm.name, shm_size, shm_offset=some_data_bytes
)
if ffio:
time_last = time.time()
time_begin = time_last
time_total = 0
idx = 0
rgb_index = idx % 30
# If your shm contains more than one frame,
# you can specify an offset to place the RGB bytes in the desired location.
# Just do it like this:
rgbs = np.ndarray((30, 1080, 1920, 3), dtype=np.uint8, buffer=your_shm.buf, offset=some_data_bytes)
while ffio.decode_one_frame_to_shm( offset=(rgb_index * 1080 * 1920 * 3) ) and idx < 500:
# Access the rgb data:
frame = rgbs[rgb_index]
dt = time.time() - time_last
time_last += dt
time_total = time_last - time_begin
idx += 1
avg = time_total * 1000 / idx
fps = 1000 / avg
print(f"{idx}: dt:{dt * 1000:.2f}ms, avg:{avg:.2f}ms, {fps:.2f}fps, "
f"total: {time_total:.3f}s, shape:{frame.shape}")
rgb_index = idx % 30
# Attention !!
# Force quitting this script will result in a memory leak.
# Ensure the following process is executed.
ffio.release_memory()
your_shm.close()
your_shm.unlink()
print('successfully release memory of input stream context.')
# If you quit without cleanup the memory,
# you can find the shm in /dev/shm/, name like: psm_b699387a
# Than you can clean it manually:
# from multiprocessing import shared_memory
# _shm = shared_memory.SharedMemory(name="psm_b699387a")
# _shm.close()
# _shm.unlink()