Skip to content

Commit bf157fb

Browse files
authored
Profiling es-split + fixes for probe (#49)
* Bytewise crc32 * Bump go-astikit to 0.30. Make crc32 generator. Remove old crc32 calculation func and corresponding tests/benchmarks. * Replace OpenFile with Create in crc32 generator. Some minor changes * Es-split memory and cpu profiler. Es-split discard output. Es-split muxerOut as WriteCloser. Some formatting changes in Es-split. Fix profiler in Probe. * Fix Close() method for muxerOut. --------- Co-authored-by: Danil Korymov <[email protected]>
1 parent d8a24c5 commit bf157fb

File tree

2 files changed

+85
-47
lines changed

2 files changed

+85
-47
lines changed

cmd/astits-es-split/main.go

Lines changed: 76 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ package main
33
import (
44
"bufio"
55
"context"
6+
"errors"
67
"flag"
78
"fmt"
9+
"github.com/pkg/profile"
10+
"io"
811
"log"
912
"os"
1013
"path"
@@ -19,8 +22,39 @@ const (
1922
)
2023

2124
type muxerOut struct {
22-
f *os.File
23-
w *bufio.Writer
25+
name string
26+
closer io.Closer
27+
*bufio.Writer
28+
}
29+
30+
func newMuxerOut(name string, discard bool) (*muxerOut, error) {
31+
var w io.Writer
32+
var c io.Closer
33+
if !discard {
34+
f, err := os.Create(name)
35+
if err != nil {
36+
return nil, err
37+
}
38+
name = f.Name()
39+
c = f
40+
w = f
41+
} else {
42+
name += " --discard--"
43+
w = io.Discard
44+
}
45+
return &muxerOut{name, c, bufio.NewWriterSize(w, ioBufSize)}, nil
46+
}
47+
48+
func (m *muxerOut) Close() error {
49+
if err := m.Flush(); err != nil {
50+
log.Printf("Error flushing %s: %v", m.name, err)
51+
}
52+
if m.closer != nil {
53+
if err := m.closer.Close(); err != nil {
54+
return fmt.Errorf("error closing %s: %w", m.name, err)
55+
}
56+
}
57+
return nil
2458
}
2559

2660
func main() {
@@ -29,23 +63,34 @@ func main() {
2963
fmt.Fprintf(flag.CommandLine.Output(), "%s INPUT_FILE [FLAGS]:\n", os.Args[0])
3064
flag.PrintDefaults()
3165
}
66+
67+
memoryProfiling := flag.Bool("mp", false, "if yes, memory profiling is enabled")
68+
cpuProfiling := flag.Bool("cp", false, "if yes, cpu profiling is enabled")
69+
discard := flag.Bool("discard", false, "if yes, output will be passed to discard (profiling/debug only)")
3270
outDir := flag.String("o", "out", "Output dir, 'out' by default")
3371
inputFile := astikit.FlagCmd()
3472
flag.Parse()
3573

74+
if *cpuProfiling {
75+
defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
76+
} else if *memoryProfiling {
77+
defer profile.Start(profile.MemProfile, profile.ProfilePath(".")).Stop()
78+
}
79+
3680
infile, err := os.Open(inputFile)
3781
if err != nil {
3882
log.Fatalf("%v", err)
3983
}
4084
defer infile.Close()
4185

42-
_, err = os.Stat(*outDir)
43-
if !os.IsNotExist(err) {
44-
log.Fatalf("can't write to `%s': already exists", *outDir)
45-
}
86+
if !*discard {
87+
if _, err = os.Stat(*outDir); !os.IsNotExist(err) {
88+
log.Fatalf("can't write to '%s': already exists", *outDir)
89+
}
4690

47-
if err = os.MkdirAll(*outDir, os.ModePerm); err != nil {
48-
log.Fatalf("%v", err)
91+
if err = os.MkdirAll(*outDir, os.ModePerm); err != nil {
92+
log.Fatalf("%v", err)
93+
}
4994
}
5095

5196
demux := astits.NewDemuxer(
@@ -59,17 +104,16 @@ func main() {
59104
gotAllPMTs := false
60105
// key is pid
61106
muxers := map[uint16]*astits.Muxer{}
62-
outfiles := map[uint16]muxerOut{}
63107

64108
pmtsPrinted := false
65109

66110
timeStarted := time.Now()
67111
bytesWritten := 0
68112

113+
var d *astits.DemuxerData
69114
for {
70-
d, err := demux.NextData()
71-
if err != nil {
72-
if err == astits.ErrNoMorePackets {
115+
if d, err = demux.NextData(); err != nil {
116+
if errors.Is(err, astits.ErrNoMorePackets) {
73117
break
74118
}
75119
log.Fatalf("%v", err)
@@ -86,8 +130,7 @@ func main() {
86130

87131
gotAllPMTs = true
88132
for _, p := range pat.Programs {
89-
_, ok := pmts[p.ProgramNumber]
90-
if !ok {
133+
if _, ok := pmts[p.ProgramNumber]; !ok {
91134
gotAllPMTs = false
92135
break
93136
}
@@ -105,29 +148,26 @@ func main() {
105148
log.Printf("\tProgram %d PCR PID %d", pmt.ProgramNumber, pmt.PCRPID)
106149
}
107150
for _, es := range pmt.ElementaryStreams {
108-
_, ok := muxers[es.ElementaryPID]
109-
if ok {
151+
if _, ok := muxers[es.ElementaryPID]; ok {
110152
continue
111153
}
112154

113155
esFilename := path.Join(*outDir, fmt.Sprintf("%d.ts", es.ElementaryPID))
114-
outfile, err := os.Create(esFilename)
115-
if err != nil {
156+
var outWriter *muxerOut
157+
if outWriter, err = newMuxerOut(esFilename, *discard); err != nil {
116158
log.Fatalf("%v", err)
117159
}
118-
119-
bufWriter := bufio.NewWriterSize(outfile, ioBufSize)
120-
mux := astits.NewMuxer(context.Background(), bufWriter)
121-
err = mux.AddElementaryStream(*es)
122-
if err != nil {
160+
defer func() {
161+
if err = outWriter.Close(); err != nil {
162+
log.Print(err)
163+
}
164+
}()
165+
166+
mux := astits.NewMuxer(context.Background(), outWriter)
167+
if err = mux.AddElementaryStream(*es); err != nil {
123168
log.Fatalf("%v", err)
124169
}
125170
mux.SetPCRPID(es.ElementaryPID)
126-
127-
outfiles[es.ElementaryPID] = muxerOut{
128-
f: outfile,
129-
w: bufWriter,
130-
}
131171
muxers[es.ElementaryPID] = mux
132172

133173
if !pmtsPrinted {
@@ -164,10 +204,11 @@ func main() {
164204
}
165205

166206
var pcr *astits.ClockReference
167-
if d.PES.Header.OptionalHeader.PTSDTSIndicator == astits.PTSDTSIndicatorBothPresent {
168-
pcr = d.PES.Header.OptionalHeader.DTS
169-
} else if d.PES.Header.OptionalHeader.PTSDTSIndicator == astits.PTSDTSIndicatorOnlyPTS {
207+
switch d.PES.Header.OptionalHeader.PTSDTSIndicator {
208+
case astits.PTSDTSIndicatorOnlyPTS:
170209
pcr = d.PES.Header.OptionalHeader.PTS
210+
case astits.PTSDTSIndicatorBothPresent:
211+
pcr = d.PES.Header.OptionalHeader.DTS
171212
}
172213

173214
if pcr != nil {
@@ -178,29 +219,20 @@ func main() {
178219
af.PCR = pcr
179220
}
180221

181-
n, err := mux.WriteData(&astits.MuxerData{
222+
var written int
223+
if written, err = mux.WriteData(&astits.MuxerData{
182224
PID: pid,
183225
AdaptationField: af,
184226
PES: d.PES,
185-
})
186-
if err != nil {
227+
}); err != nil {
187228
log.Fatalf("%v", err)
188229
}
189230

190-
bytesWritten += n
231+
bytesWritten += written
191232
}
192233

193234
timeDiff := time.Since(timeStarted)
194235
log.Printf("%d bytes written at rate %.02f mb/s", bytesWritten, (float64(bytesWritten)/1024.0/1024.0)/timeDiff.Seconds())
195236

196-
for _, f := range outfiles {
197-
if err = f.w.Flush(); err != nil {
198-
log.Printf("Error flushing %s: %v", f.f.Name(), err)
199-
}
200-
if err = f.f.Close(); err != nil {
201-
log.Printf("Error closing %s: %v", f.f.Name(), err)
202-
}
203-
}
204-
205237
log.Printf("Done")
206238
}

cmd/astits-probe/main.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,24 @@ func main() {
7070
case "data":
7171
// Fetch data
7272
if err = data(dmx); err != nil {
73-
log.Fatal(fmt.Errorf("astits: fetching data failed: %w", err))
73+
if !errors.Is(err, astits.ErrNoMorePackets) {
74+
log.Fatal(fmt.Errorf("astits: fetching data failed: %w", err))
75+
}
7476
}
7577
case "packets":
7678
// Fetch packets
7779
if err = packets(dmx); err != nil {
78-
log.Fatal(fmt.Errorf("astits: fetching packets failed: %w", err))
80+
if !errors.Is(err, astits.ErrNoMorePackets) {
81+
log.Fatal(fmt.Errorf("astits: fetching packets failed: %w", err))
82+
}
7983
}
8084
default:
8185
// Fetch the programs
8286
var pgms []*Program
8387
if pgms, err = programs(dmx); err != nil {
84-
log.Fatal(fmt.Errorf("astits: fetching programs failed: %w", err))
88+
if !errors.Is(err, astits.ErrNoMorePackets) {
89+
log.Fatal(fmt.Errorf("astits: fetching programs failed: %w", err))
90+
}
8591
}
8692

8793
// Print

0 commit comments

Comments
 (0)