ffmpeg: Add transcoder example program.

Includes support to toggle GPU via CLI flags.

Also update documentation.
This commit is contained in:
Josh Allmann
2019-05-01 06:12:59 +00:00
parent fb4f965ce6
commit fb696c073b
3 changed files with 118 additions and 1 deletions

View File

@@ -131,4 +131,39 @@ To handle HLS playback:
}) })
``` ```
### GPU Support
Processing on Nvidia GPUs is supported. To enable this capability, FFmpeg needs
to be built with GPU support. See the
[FFmpeg guidelines](https://trac.ffmpeg.org/wiki/HWAccelIntro#NVENCNVDEC) on
this.
To execute the nvidia tests within the `ffmpeg` directory, run this command:
```
go test -tag=nvidia -run Nvidia
```
To run the tests on a particular GPU, use the GPU_DEVICE environment variable:
```
# Runs on GPU number 3
GPU_DEVICE=3 go test -tag nvidia -run Nvidia
```
Aside from the tests themselves, there is a
[sample program](https://github.com/livepeer/lpms/blob/master/cmd/transcoding/transcoding.go)
that can be used as a reference to the LPMS GPU transcoding API. The sample
program can select GPU or software processing via CLI flags. Run the sample
program via:
```
# software processing
go run cmd/transcoding/transcoding.go transcoder/test.ts P144p30fps16x9,P240p30fps16x9 sw
# nvidia processing, GPU number 2
go run cmd/transcoding/transcoding.go transcoder/test.ts P144p30fps16x9,P240p30fps16x9 nv 2
```
You can follow the development of LPMS and Livepeer @ our [forum](http://forum.livepeer.org) You can follow the development of LPMS and Livepeer @ our [forum](http://forum.livepeer.org)

View File

@@ -0,0 +1,78 @@
package main
import (
"fmt"
"os"
"strings"
"github.com/livepeer/lpms/ffmpeg"
)
func validRenditions() []string {
valids := make([]string, len(ffmpeg.VideoProfileLookup))
for p, _ := range ffmpeg.VideoProfileLookup {
valids = append(valids, p)
}
return valids
}
func main() {
if len(os.Args) <= 3 {
panic("Usage: <input file> <output renditions, comma separated> <sw/nv>")
}
str2accel := func(inp string) (ffmpeg.Acceleration, string) {
if inp == "nv" {
return ffmpeg.Nvidia, "nv"
}
return ffmpeg.Software, "sw"
}
str2profs := func(inp string) []ffmpeg.VideoProfile {
profs := []ffmpeg.VideoProfile{}
strs := strings.Split(inp, ",")
for _, k := range strs {
p, ok := ffmpeg.VideoProfileLookup[k]
if !ok {
panic(fmt.Sprintf("Invalid rendition %s. Valid renditions are:\n%s", k, validRenditions()))
}
profs = append(profs, p)
}
return profs
}
fname := os.Args[1]
profiles := str2profs(os.Args[2])
accel, lbl := str2accel(os.Args[3])
profs2opts := func(profs []ffmpeg.VideoProfile) []ffmpeg.TranscodeOptions {
opts := []ffmpeg.TranscodeOptions{}
for i := range profs {
o := ffmpeg.TranscodeOptions{
Oname: fmt.Sprintf("out_%s_%d_out.mkv", lbl, i),
Profile: profs[i],
Accel: accel,
}
opts = append(opts, o)
}
return opts
}
options := profs2opts(profiles)
var dev string
if accel == ffmpeg.Nvidia {
if len(os.Args) <= 4 {
panic("Expected device number")
}
dev = os.Args[4]
}
ffmpeg.InitFFmpeg()
fmt.Printf("Setting fname %s encoding %d renditions with %v\n", fname, len(options), lbl)
err := ffmpeg.Transcode2(&ffmpeg.TranscodeOptionsIn{
Fname: fname,
Accel: accel,
Device: dev,
}, options)
if err != nil {
panic(err)
}
}

View File

@@ -42,7 +42,11 @@ go test -logtostderr=true
t7=$? t7=$?
cd .. cd ..
if (($t1!=0||$t2!=0||$t3!=0||$t4!=0||$t5!=0||$t6!=0||$t7!=0)) echo 'Testing example program'
go run cmd/transcoding/transcoding.go transcoder/test.ts P144p30fps16x9,P240p30fps16x9 sw
t8=$?
if (($t1!=0||$t2!=0||$t3!=0||$t4!=0||$t5!=0||$t6!=0||$t7!=0||$t8!=0))
then then
printf "\n\nSome Tests Failed\n\n" printf "\n\nSome Tests Failed\n\n"
exit -1 exit -1