@@ -3,8 +3,11 @@ package main
33import (
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
2124type 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
2660func 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 ("\t Program %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}
0 commit comments