@@ -3,8 +3,11 @@ package main
3
3
import (
4
4
"bufio"
5
5
"context"
6
+ "errors"
6
7
"flag"
7
8
"fmt"
9
+ "github.com/pkg/profile"
10
+ "io"
8
11
"log"
9
12
"os"
10
13
"path"
@@ -19,8 +22,39 @@ const (
19
22
)
20
23
21
24
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
24
58
}
25
59
26
60
func main () {
@@ -29,23 +63,34 @@ func main() {
29
63
fmt .Fprintf (flag .CommandLine .Output (), "%s INPUT_FILE [FLAGS]:\n " , os .Args [0 ])
30
64
flag .PrintDefaults ()
31
65
}
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)" )
32
70
outDir := flag .String ("o" , "out" , "Output dir, 'out' by default" )
33
71
inputFile := astikit .FlagCmd ()
34
72
flag .Parse ()
35
73
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
+
36
80
infile , err := os .Open (inputFile )
37
81
if err != nil {
38
82
log .Fatalf ("%v" , err )
39
83
}
40
84
defer infile .Close ()
41
85
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
+ }
46
90
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
+ }
49
94
}
50
95
51
96
demux := astits .NewDemuxer (
@@ -59,17 +104,16 @@ func main() {
59
104
gotAllPMTs := false
60
105
// key is pid
61
106
muxers := map [uint16 ]* astits.Muxer {}
62
- outfiles := map [uint16 ]muxerOut {}
63
107
64
108
pmtsPrinted := false
65
109
66
110
timeStarted := time .Now ()
67
111
bytesWritten := 0
68
112
113
+ var d * astits.DemuxerData
69
114
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 ) {
73
117
break
74
118
}
75
119
log .Fatalf ("%v" , err )
@@ -86,8 +130,7 @@ func main() {
86
130
87
131
gotAllPMTs = true
88
132
for _ , p := range pat .Programs {
89
- _ , ok := pmts [p .ProgramNumber ]
90
- if ! ok {
133
+ if _ , ok := pmts [p .ProgramNumber ]; ! ok {
91
134
gotAllPMTs = false
92
135
break
93
136
}
@@ -105,29 +148,26 @@ func main() {
105
148
log .Printf ("\t Program %d PCR PID %d" , pmt .ProgramNumber , pmt .PCRPID )
106
149
}
107
150
for _ , es := range pmt .ElementaryStreams {
108
- _ , ok := muxers [es .ElementaryPID ]
109
- if ok {
151
+ if _ , ok := muxers [es .ElementaryPID ]; ok {
110
152
continue
111
153
}
112
154
113
155
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 {
116
158
log .Fatalf ("%v" , err )
117
159
}
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 {
123
168
log .Fatalf ("%v" , err )
124
169
}
125
170
mux .SetPCRPID (es .ElementaryPID )
126
-
127
- outfiles [es .ElementaryPID ] = muxerOut {
128
- f : outfile ,
129
- w : bufWriter ,
130
- }
131
171
muxers [es .ElementaryPID ] = mux
132
172
133
173
if ! pmtsPrinted {
@@ -164,10 +204,11 @@ func main() {
164
204
}
165
205
166
206
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 :
170
209
pcr = d .PES .Header .OptionalHeader .PTS
210
+ case astits .PTSDTSIndicatorBothPresent :
211
+ pcr = d .PES .Header .OptionalHeader .DTS
171
212
}
172
213
173
214
if pcr != nil {
@@ -178,29 +219,20 @@ func main() {
178
219
af .PCR = pcr
179
220
}
180
221
181
- n , err := mux .WriteData (& astits.MuxerData {
222
+ var written int
223
+ if written , err = mux .WriteData (& astits.MuxerData {
182
224
PID : pid ,
183
225
AdaptationField : af ,
184
226
PES : d .PES ,
185
- })
186
- if err != nil {
227
+ }); err != nil {
187
228
log .Fatalf ("%v" , err )
188
229
}
189
230
190
- bytesWritten += n
231
+ bytesWritten += written
191
232
}
192
233
193
234
timeDiff := time .Since (timeStarted )
194
235
log .Printf ("%d bytes written at rate %.02f mb/s" , bytesWritten , (float64 (bytesWritten )/ 1024.0 / 1024.0 )/ timeDiff .Seconds ())
195
236
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
-
205
237
log .Printf ("Done" )
206
238
}
0 commit comments