Skip to content

Commit 16a6b41

Browse files
eilnmarcan
authored andcommitted
m1n1/avd: Add initial AVD driver prototype/tracer
Not much to see here, most of the juice is over at: https://github.com/eiln/avd.git The kernel driver (m1n1.fw.avd) only really pipes the instruction stream into the respective hardware FIFOs and then hushes the interrupt lines. Most of the work (bitstream syntax parsing and instruction generation) is done in the avid repo above. I'm hoping to keep this userland-kernel separation in the very imminent actual driver. experiments/avd.py: Decode on the command line. Read file for usage. experiments/avd_e.py: Decode via emulated instruction stream. experiments/avd_f.py: Decode via Cortex-M3 firmware (for debugging). hv/trace_avd.py: Tracer. Read file for usage. m1n1/fw/avd/__init__.py: Driver base class (power, tunables, etc). m1n1/fw/avd/decoder.py: Codec-specific decode logic + mini media player. Signed-off-by: Eileen Yoon <[email protected]>
1 parent 90eef72 commit 16a6b41

6 files changed

Lines changed: 1013 additions & 0 deletions

File tree

proxyclient/experiments/avd.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: MIT
3+
import sys, pathlib, argparse
4+
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
5+
sys.path.append("/home/eileen/asahi/avd") # git clone https://github.com/eiln/avd.git
6+
# Decode with our own generated instruction stream
7+
8+
from m1n1.setup import *
9+
from m1n1.utils import *
10+
from m1n1.fw.avd import *
11+
from tools.common import ffprobe
12+
13+
if __name__ == "__main__":
14+
parser = argparse.ArgumentParser()
15+
#
16+
# Usage:
17+
# ffmpeg -i input.mp4 -c:v copy (or reencode libx264) input.264
18+
# python3 experiments/avd.py -i input.264 -a
19+
#
20+
# - Supports .264, .265, and .ivf formats.
21+
# - Regarding the codec, it's whatever codec features are supported.
22+
# Check avid for details.
23+
# - Also ensure to change the sys.path.append above to the avid repo
24+
# as it does not install system-wide.
25+
#
26+
parser.add_argument('-i', '--input', type=str, required=True, help="path to input bitstream")
27+
parser.add_argument('-n', '--num', type=int, default=1, help="frame count")
28+
parser.add_argument('-a', '--all', action='store_true', help="run all frames")
29+
parser.add_argument('-x', '--stfu', action='store_true')
30+
parser.add_argument('-p', '--poll', action='store_true', help="poll iommu space")
31+
parser.add_argument('--save-raw', type=str, default="", help="file name to save raw yuv")
32+
parser.add_argument('--save-images', type=str, default="", help="dirname to save images")
33+
args = parser.parse_args()
34+
mode = ffprobe(args.input)
35+
36+
if (mode == "h264"):
37+
from avid.h264.decoder import AVDH264Decoder
38+
dec = AVDH264Decoder()
39+
elif (mode == "h265"):
40+
from avid.h265.decoder import AVDH265Decoder
41+
dec = AVDH265Decoder()
42+
elif (mode == "vp09"):
43+
from avid.vp9.decoder import AVDVP9Decoder
44+
dec = AVDVP9Decoder()
45+
else:
46+
raise RuntimeError("unsupported codec")
47+
if (args.stfu):
48+
dec.stfu = True
49+
dec.hal.stfu = True
50+
nal_stop = 0 if args.all else 1
51+
units = dec.setup(args.input, nal_stop=nal_stop, num=args.num)
52+
53+
avd = AVDDevice(u)
54+
if (mode == "h264"):
55+
avd.decoder = AVDH264Dec(avd)
56+
elif (mode == "h265"):
57+
avd.decoder = AVDH265Dec(avd)
58+
elif (mode == "vp09"):
59+
avd.decoder = AVDVP9Dec(avd)
60+
else:
61+
raise RuntimeError("unsupported codec")
62+
avd.decoder.winname = args.input
63+
if (args.stfu):
64+
avd.stfu = True
65+
avd.boot()
66+
67+
rawvideo = b''
68+
num = len(units) if args.all else min(args.num, len(units))
69+
for i,unit in enumerate(units[:num]):
70+
print(unit)
71+
inst = dec.decode(unit)
72+
if (i == 0):
73+
avd.ioalloc_at(0x0, dec.allocator_top(), stream=0, val=0)
74+
if (args.poll):
75+
avd.iomon.add(0x0, dec.allocator_top())
76+
frame = avd.decoder.decode(dec.ctx, unit, inst)
77+
if (frame != None):
78+
if (args.save_raw):
79+
rawvideo += frame.y_data + frame.uv_data
80+
if (args.save_images):
81+
os.makedirs(f"data/out/{args.save_images}", exist_ok=True)
82+
path = os.path.join(f"data/out/{args.save_images}", "out%03d.png" % (avd.decoder.count))
83+
cv2.imwrite(path, frame.img)
84+
if (args.save_raw):
85+
path = os.path.join(f"data/out/{args.save_raw}")
86+
open(path, "wb").write(rawvideo)

proxyclient/experiments/avd_e.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: MIT
3+
import sys, pathlib, argparse, os
4+
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
5+
sys.path.append("/home/eileen/asahi/avd") # git clone https://github.com/eiln/avd.git
6+
# Decode via firmware-emulated AVD instruction stream
7+
8+
from m1n1.setup import *
9+
from m1n1.utils import *
10+
from m1n1.fw.avd import *
11+
12+
from avd_emu import AVDEmulator
13+
from tools.common import ffprobe
14+
15+
if __name__ == "__main__":
16+
parser = argparse.ArgumentParser()
17+
parser.add_argument('-i', '--input', type=str, required=True, help="input bitstream")
18+
parser.add_argument('-d', '--dir', type=str, required=True, help="path to trace dir")
19+
parser.add_argument('-f', '--firmware', type=str, default="data/fw.bin", help="path to fw")
20+
parser.add_argument('-n', '--num', type=int, default=1, help="count")
21+
parser.add_argument('-a', '--all', action='store_true', help="run all")
22+
parser.add_argument('-x', '--stfu', action='store_true')
23+
parser.add_argument('-p', '--poll', action='store_true', help="poll iommu space")
24+
parser.add_argument('--save-raw', action='store_true', help="save raw yuv")
25+
args = parser.parse_args()
26+
mode = ffprobe(args.input)
27+
28+
emu = AVDEmulator(args.firmware, stfu=True)
29+
emu.start()
30+
paths = os.listdir(os.path.join(args.dir))
31+
paths = sorted([os.path.join(args.dir, path) for path in paths if "frame" in path])
32+
assert(len(paths))
33+
num = len(paths) if args.all else args.num
34+
num = min(len(paths), num)
35+
36+
if (mode == "h264"):
37+
from avid.h264.decoder import AVDH264Decoder
38+
dec = AVDH264Decoder()
39+
elif (mode == "h265"):
40+
from avid.h265.decoder import AVDH265Decoder
41+
dec = AVDH265Decoder()
42+
elif (mode == "vp09"):
43+
from avid.vp9.decoder import AVDVP9Decoder
44+
dec = AVDVP9Decoder()
45+
else:
46+
raise RuntimeError("unsupported codec")
47+
if (args.stfu):
48+
dec.stfu = True
49+
dec.hal.stfu = True
50+
units = dec.setup(args.input)
51+
52+
avd = AVDDevice(u)
53+
if (mode == "h264"):
54+
avd.decoder = AVDH264Dec(avd)
55+
elif (mode == "h265"):
56+
avd.decoder = AVDH265Dec(avd)
57+
elif (mode == "vp09"):
58+
avd.decoder = AVDVP9Dec(avd)
59+
else:
60+
raise RuntimeError("unsupported codec")
61+
avd.decoder.winname = args.input
62+
if (args.stfu):
63+
avd.stfu = True
64+
avd.boot()
65+
avd.ioalloc_at(0x0, 0xf000000, stream=0)
66+
if (args.poll):
67+
avd.iomon.add(0x0, 0xf000000)
68+
69+
for i,unit in enumerate(units[:num]):
70+
print(unit)
71+
inst = dec.decode(unit)
72+
path = paths[i]
73+
print(path)
74+
inst = emu.avd_cm3_cmd_decode(path)
75+
avd.decoder.decode(dec.ctx, unit, inst)
76+
if (args.save_raw):
77+
y_data = avd.ioread(dec.ctx.y_addr, dec.ctx.luma_size, stream=0)
78+
uv_data = avd.ioread(dec.ctx.uv_addr, dec.ctx.chroma_size, stream=0)
79+
open("data/raw-emu/%03d.bin" % (i), "wb").write(y_data + uv_data)

proxyclient/experiments/avd_fw.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: MIT
3+
import sys, pathlib, argparse
4+
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
5+
sys.path.append("/home/eileen/asahi/avd") # git clone https://github.com/eiln/avd.git
6+
# Decode via AVD Cortex-M3 firmware
7+
8+
from m1n1.setup import *
9+
from m1n1.utils import *
10+
from m1n1.fw.avd import *
11+
import cv2
12+
13+
from avd_emu import AVDEmulator
14+
from avid.h264.decoder import AVDH264Decoder
15+
from avid.vp9.decoder import AVDVP9Decoder
16+
from avid.utils import *
17+
from tools.common import *
18+
19+
if __name__ == "__main__":
20+
parser = argparse.ArgumentParser()
21+
parser.add_argument('-f','--firmware', type=str, default="data/fw.bin", help="path to CM3 firmware")
22+
parser.add_argument('-i','--input', type=str, required=True, help="path to CM3 firmware")
23+
parser.add_argument('-d','--dir', type=str, required=True, help="frame_params trace dir")
24+
parser.add_argument('-p', '--poll', action='store_true', help="poll iommu space")
25+
args = parser.parse_args()
26+
27+
paths = os.listdir(os.path.join(args.dir))
28+
paths = sorted([os.path.join(args.dir, path) for path in paths if "frame" in path])
29+
assert(len(paths))
30+
31+
avd = AVDDevice(u)
32+
avd.decoder = AVDVP9Dec(avd)
33+
avd.boot()
34+
avd.mcpu_decode_init(args.firmware)
35+
avd.poll()
36+
37+
avd.ioalloc_at(0x0, 0xff0000, stream=0)
38+
if (args.poll):
39+
avd.iomon.add(0x0, 0xff0000)
40+
avd.ioalloc_at(0x0, 0xb84000, stream=1)
41+
avd.iomon.poll()
42+
emu = AVDEmulator(args.firmware, stfu=True)
43+
emu.start()
44+
45+
dec = AVDVP9Decoder()
46+
dec.stfu = True
47+
dec.hal.stfu = True
48+
units = dec.setup(args.input, num=4, do_probs=True)
49+
for n,unit in enumerate(units):
50+
inst = dec.decode(unit)
51+
avd.decoder.set_payload(dec.ctx, units[n])
52+
avd.decoder.avd.iowrite(dec.ctx.probs_addr, unit.get_probs(), stream=0)
53+
avd.iomon.poll()
54+
cmd = emu.set_params(paths[n])
55+
xxde(cmd)
56+
avd.iowrite(0x0, emu.dart1_space, stream=1)
57+
avd.iomon.poll()
58+
avd.avd_wbuf(emu.get_cmd_addr(n), cmd)
59+
avd.avd_w32(0x1098054, emu.get_cmd_addr(n))
60+
avd.poll()
61+
avd.iomon.poll()
62+
img = avd.decoder.get_nv12_disp_frame(dec.ctx)
63+
cv2.imshow(avd.decoder.winname, img); cv2.waitKey(1)

0 commit comments

Comments
 (0)