feat: hardware decoding
This commit is contained in:
parent
cbaf4069c7
commit
bc39a2ad99
@ -1,66 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
width="135"
|
||||
height="153"
|
||||
shape-rendering="crispEdges"
|
||||
id="svg29096"
|
||||
sodipodi:docname="cashu.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5, 2022-02-04)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs29100" />
|
||||
<sodipodi:namedview
|
||||
id="namedview29098"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9146341"
|
||||
inkscape:cx="-5.4840764"
|
||||
inkscape:cy="91.923567"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="838"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg29096"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<path
|
||||
id="rect2"
|
||||
d="m 18,0 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 V 8 7 6 5 4 3 2 1 0 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z m 0,9 H 17 16 15 14 13 12 11 10 9 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 V 17 16 15 14 13 12 11 10 Z M 9,18 H 8 7 6 5 4 3 2 1 0 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 H 1 2 3 4 5 6 7 8 9 V 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 Z M 0,53 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 H 8 7 6 V 60 59 58 57 H 5 4 3 V 56 55 54 53 H 2 1 Z m 9,55 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,18 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,9 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,9 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z m 81,0 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v 1 1 1 1 1 1 1 1 z"
|
||||
style="fill:#b89563;fill-opacity:1" />
|
||||
<path
|
||||
id="rect38"
|
||||
d="m 36,0 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 V 8 7 6 5 4 3 2 1 0 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z m 45,9 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 V 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 h -1 -1 -1 -1 -1 -1 -1 -1 z m 0,27 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 V 44 43 42 41 40 39 38 37 Z M 63,64 v 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,8 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,18 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z m 36,9 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z m 9,9 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 z"
|
||||
style="fill:#e2d2b3;fill-opacity:1" />
|
||||
<path
|
||||
id="rect1154"
|
||||
d="m 18,9 v 1 1 1 1 1 1 1 1 1 H 17 16 15 14 13 12 11 10 9 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h 1 1 1 1 1 1 1 1 1 V 17 16 15 14 13 12 11 10 9 H 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 Z M 9,61 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 z"
|
||||
style="fill:#c5a77f;fill-opacity:1" />
|
||||
<path
|
||||
id="rect1190"
|
||||
d="m 36,9 v 1 1 1 1 1 1 1 1 1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h 1 1 1 1 1 1 1 1 1 V 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z m 9,40 v 1 1 1 1 1 1 h -1 -1 v 1 1 1 h -1 -1 -1 v 1 1 1 h -1 -1 -1 -1 v 1 1 1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 v -1 -1 -1 h -1 -1 -1 v -1 -1 -1 -1 h -1 -1 -1 -1 v -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 z"
|
||||
style="fill:#dbbf98;fill-opacity:1" />
|
||||
<path
|
||||
id="rect7292"
|
||||
d="m 0,45 v 1 1 1 1 1 1 1 1 h 1 1 1 v 1 1 1 1 h 1 1 1 v 1 1 1 1 h 1 1 1 1 v 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 h 1 1 1 1 v -1 -1 -1 h 1 1 1 v -1 -1 -1 h 1 1 v -1 -1 -1 -1 -1 -1 h 1 1 1 1 1 1 v 1 1 1 1 1 1 1 1 h 1 1 1 1 v 1 1 1 1 h 1 1 1 v 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 h 1 1 1 1 v -1 -1 -1 -1 h 1 1 1 1 v -1 -1 -1 -1 h 1 1 1 1 V 52 51 50 49 48 47 46 45 H 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 Z m 6,4 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v 1 1 1 1 h -1 -1 -1 -1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 1 H 17 16 15 14 V 60 59 58 57 H 13 12 11 10 V 56 55 54 53 H 9 8 7 6 v -1 -1 -1 z m 8,8 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 z m 44,-8 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v 1 1 1 1 h 1 1 1 1 v 1 1 1 1 h -1 -1 -1 -1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 1 h -1 -1 -1 -1 v -1 -1 -1 -1 h -1 -1 -1 -1 v -1 -1 -1 -1 h -1 -1 -1 -1 v -1 -1 -1 z m 8,8 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 z"
|
||||
style="fill:#000000;fill-opacity:1" />
|
||||
<path
|
||||
id="rect8072"
|
||||
d="m 6,49 v 1 1 1 1 h 1 1 1 1 V 52 51 50 49 H 9 8 7 Z m 4,4 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m 4,0 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 z m 4,0 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m 4,4 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m -4,0 h -1 -1 -1 -1 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 z m 40,-8 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m 4,4 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m 4,0 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 -1 v 1 1 1 z m 4,0 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m 4,4 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 -1 h -1 -1 -1 z m -4,0 h -1 -1 -1 -1 v 1 1 1 1 h 1 1 1 1 v -1 -1 -1 z"
|
||||
style="fill:#ffffff;fill-opacity:1" />
|
||||
<path
|
||||
id="rect17144"
|
||||
d="m 99,99 v 1 1 1 1 1 1 1 1 1 h 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 v -1 -1 -1 -1 -1 -1 -1 -1 -1 h -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 z"
|
||||
style="fill:#f7f8f3;fill-opacity:1" />
|
||||
</svg>
|
Before Width: | Height: | Size: 9.4 KiB |
@ -1,6 +1,6 @@
|
||||
use ffmpeg_rs_raw::{Decoder, Demuxer};
|
||||
use ffmpeg_rs_raw::{Decoder, Demuxer, DemuxerInfo};
|
||||
use ffmpeg_sys_the_third::AVHWDeviceType::{AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VDPAU};
|
||||
use ffmpeg_sys_the_third::{av_frame_free, av_packet_free};
|
||||
use std::collections::HashMap;
|
||||
use std::env::args;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Read};
|
||||
@ -20,20 +20,6 @@ fn main() {
|
||||
|
||||
let fd = read_as_file(path.clone());
|
||||
scan_input(fd);
|
||||
|
||||
let mut opt = HashMap::new();
|
||||
opt.insert("analyzeduration".to_string(), "999".to_string());
|
||||
let svg = include_bytes!("./cashu.svg");
|
||||
let mut dx = Demuxer::new_custom_io(svg.as_slice(), Some("cashu.svg".to_string()));
|
||||
dx.set_opt(opt.clone()).unwrap();
|
||||
unsafe {
|
||||
let mut decoder = Decoder::new();
|
||||
let info = dx.probe_input().expect("probe failed");
|
||||
for chan in &info.channels {
|
||||
decoder.setup_decoder(chan, None).expect("setup failed");
|
||||
}
|
||||
loop_decoder(dx, decoder);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_as_custom_io(path: PathBuf) -> Demuxer {
|
||||
@ -51,12 +37,20 @@ fn scan_input(mut demuxer: Demuxer) {
|
||||
unsafe {
|
||||
let info = demuxer.probe_input().expect("demuxer failed");
|
||||
println!("{}", info);
|
||||
decode_input(demuxer);
|
||||
decode_input(demuxer, info);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn decode_input(demuxer: Demuxer) {
|
||||
let decoder = Decoder::new();
|
||||
unsafe fn decode_input(demuxer: Demuxer, info: DemuxerInfo) {
|
||||
let mut decoder = Decoder::new();
|
||||
decoder.enable_hw_decoder(AV_HWDEVICE_TYPE_VDPAU);
|
||||
decoder.enable_hw_decoder(AV_HWDEVICE_TYPE_CUDA);
|
||||
for ref stream in info.channels {
|
||||
decoder
|
||||
.setup_decoder(stream, None)
|
||||
.expect("decoder setup failed");
|
||||
}
|
||||
println!("{}", decoder);
|
||||
loop_decoder(demuxer, decoder);
|
||||
}
|
||||
|
||||
|
119
src/decode.rs
119
src/decode.rs
@ -1,21 +1,25 @@
|
||||
use crate::{options_to_dict, StreamInfoChannel};
|
||||
use std::collections::HashMap;
|
||||
use crate::{options_to_dict, return_ffmpeg_error, StreamInfoChannel};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ffi::CStr;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ptr;
|
||||
|
||||
use anyhow::Error;
|
||||
use ffmpeg_sys_the_third::AVPictureType::AV_PICTURE_TYPE_NONE;
|
||||
use ffmpeg_sys_the_third::{
|
||||
av_buffer_alloc, av_frame_alloc, avcodec_alloc_context3, avcodec_find_decoder,
|
||||
avcodec_free_context, avcodec_get_name, avcodec_open2, avcodec_parameters_to_context,
|
||||
avcodec_receive_frame, avcodec_send_packet, AVCodec, AVCodecContext, AVFrame, AVMediaType,
|
||||
AVPacket, AVStream, AVERROR, AVERROR_EOF,
|
||||
av_buffer_alloc, av_buffer_ref, av_frame_alloc, av_frame_copy_props, av_frame_free,
|
||||
av_hwdevice_ctx_create, av_hwdevice_get_type_name, av_hwframe_transfer_data,
|
||||
avcodec_alloc_context3, avcodec_find_decoder, avcodec_free_context, avcodec_get_hw_config,
|
||||
avcodec_get_name, avcodec_open2, avcodec_parameters_to_context, avcodec_receive_frame,
|
||||
avcodec_send_packet, AVCodec, AVCodecContext, AVCodecHWConfig, AVFrame, AVHWDeviceType,
|
||||
AVMediaType, AVPacket, AVStream, AVERROR, AVERROR_EOF, AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX,
|
||||
};
|
||||
use libc::memcpy;
|
||||
|
||||
pub struct DecoderCodecContext {
|
||||
pub context: *mut AVCodecContext,
|
||||
pub codec: *const AVCodec,
|
||||
pub hw_config: *const AVCodecHWConfig,
|
||||
}
|
||||
|
||||
impl DecoderCodecContext {
|
||||
@ -39,17 +43,61 @@ impl Drop for DecoderCodecContext {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for DecoderCodecContext {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
unsafe {
|
||||
let codec_name = CStr::from_ptr(avcodec_get_name((*self.codec).id))
|
||||
.to_str()
|
||||
.unwrap();
|
||||
write!(
|
||||
f,
|
||||
"DecoderCodecContext: codec={}, hw={}",
|
||||
codec_name,
|
||||
if self.hw_config.is_null() {
|
||||
"no"
|
||||
} else {
|
||||
CStr::from_ptr(av_hwdevice_get_type_name((*self.hw_config).device_type))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for DecoderCodecContext {}
|
||||
unsafe impl Sync for DecoderCodecContext {}
|
||||
|
||||
pub struct Decoder {
|
||||
codecs: HashMap<i32, DecoderCodecContext>,
|
||||
/// List of [AVHWDeviceType] which are enabled
|
||||
hw_decoder_types: Option<HashSet<AVHWDeviceType>>,
|
||||
}
|
||||
|
||||
impl Display for Decoder {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
for (idx, codec) in &self.codecs {
|
||||
writeln!(f, "{}: {}", idx, codec)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Decoder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
codecs: HashMap::new(),
|
||||
hw_decoder_types: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable hardware decoding with [hw_type]
|
||||
pub fn enable_hw_decoder(&mut self, hw_type: AVHWDeviceType) {
|
||||
if let Some(ref mut t) = self.hw_decoder_types {
|
||||
t.insert(hw_type);
|
||||
} else {
|
||||
let mut hwt = HashSet::new();
|
||||
hwt.insert(hw_type);
|
||||
self.hw_decoder_types = Some(hwt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,8 +139,38 @@ impl Decoder {
|
||||
if context.is_null() {
|
||||
anyhow::bail!("Failed to alloc context")
|
||||
}
|
||||
if avcodec_parameters_to_context(context, (*stream).codecpar) != 0 {
|
||||
anyhow::bail!("Failed to copy codec parameters to context")
|
||||
|
||||
let mut ret = avcodec_parameters_to_context(context, (*stream).codecpar);
|
||||
return_ffmpeg_error!(ret, "Failed to copy codec parameters to context");
|
||||
|
||||
// try use HW decoder
|
||||
let mut hw_config = ptr::null();
|
||||
if let Some(ref hw_types) = self.hw_decoder_types {
|
||||
let mut hw_buf_ref = ptr::null_mut();
|
||||
let mut i = 0;
|
||||
loop {
|
||||
hw_config = avcodec_get_hw_config(codec, i);
|
||||
i += 1;
|
||||
if hw_config.is_null() {
|
||||
break;
|
||||
}
|
||||
if !hw_types.contains(&(*hw_config).device_type) {
|
||||
continue;
|
||||
}
|
||||
let hw_flag = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX as libc::c_int;
|
||||
if (*hw_config).methods & hw_flag == hw_flag {
|
||||
ret = av_hwdevice_ctx_create(
|
||||
&mut hw_buf_ref,
|
||||
(*hw_config).device_type,
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
0,
|
||||
);
|
||||
return_ffmpeg_error!(ret, "Failed to create HW ctx");
|
||||
(*context).hw_device_ctx = av_buffer_ref(hw_buf_ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut dict = if let Some(options) = options {
|
||||
options_to_dict(options)?
|
||||
@ -100,10 +178,14 @@ impl Decoder {
|
||||
ptr::null_mut()
|
||||
};
|
||||
|
||||
if avcodec_open2(context, codec, &mut dict) < 0 {
|
||||
anyhow::bail!("Failed to open codec")
|
||||
}
|
||||
Ok(e.insert(DecoderCodecContext { context, codec }))
|
||||
ret = avcodec_open2(context, codec, &mut dict);
|
||||
return_ffmpeg_error!(ret, "Failed to open codec");
|
||||
|
||||
Ok(e.insert(DecoderCodecContext {
|
||||
context,
|
||||
codec,
|
||||
hw_config,
|
||||
}))
|
||||
} else {
|
||||
anyhow::bail!("Decoder already setup");
|
||||
}
|
||||
@ -146,7 +228,7 @@ impl Decoder {
|
||||
|
||||
let mut pkgs = Vec::new();
|
||||
while ret >= 0 {
|
||||
let frame = av_frame_alloc();
|
||||
let mut frame = av_frame_alloc();
|
||||
ret = avcodec_receive_frame(ctx.context, frame);
|
||||
if ret < 0 {
|
||||
if ret == AVERROR_EOF || ret == AVERROR(libc::EAGAIN) {
|
||||
@ -155,6 +237,17 @@ impl Decoder {
|
||||
return Err(Error::msg(format!("Failed to decode {}", ret)));
|
||||
}
|
||||
|
||||
// copy frame from GPU
|
||||
if !ctx.hw_config.is_null() {
|
||||
let sw_frame = av_frame_alloc();
|
||||
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
|
||||
return_ffmpeg_error!(ret, "Failed to transfer data from GPU");
|
||||
|
||||
av_frame_copy_props(sw_frame, frame);
|
||||
av_frame_free(&mut frame);
|
||||
frame = sw_frame;
|
||||
}
|
||||
|
||||
(*frame).pict_type = AV_PICTURE_TYPE_NONE; // encoder prints warnings
|
||||
pkgs.push((frame, stream));
|
||||
}
|
||||
|
@ -17,7 +17,12 @@ mod stream_info;
|
||||
macro_rules! return_ffmpeg_error {
|
||||
($x:expr) => {
|
||||
if $x < 0 {
|
||||
return Err(Error::msg(get_ffmpeg_error_msg($x)));
|
||||
anyhow::bail!(crate::get_ffmpeg_error_msg($x))
|
||||
}
|
||||
};
|
||||
($x:expr,$msg:expr) => {
|
||||
if $x < 0 {
|
||||
anyhow::bail!(format!("{}: {}", $msg, crate::get_ffmpeg_error_msg($x)))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user