Valkka  1.6.1
OpenSource Video Management
muxer.h
Go to the documentation of this file.
1 #ifndef muxer_HEADER_GUARD
2 #define muxer_HEADER_GUARD
3 /*
4  * muxer.h : FFmpeg muxers, implemented as Valkka framefilters
5  *
6  * (c) Copyright 2017-2024 Sampsa Riikonen
7  *
8  * Authors: Sampsa Riikonen <sampsa.riikonen@iki.fi>
9  *
10  * This file is part of the Valkka library.
11  *
12  * Valkka is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this program. If not, see <https://www.gnu.org/licenses/>
24  *
25  */
26 
43 #include "constant.h"
44 #include "framefilter.h"
45 
46 
47 class MuxFrameFilter : public FrameFilter { // <pyapi>
48 
49 public: //
50  MuxFrameFilter(const char* name, FrameFilter *next = NULL); //
51  virtual ~MuxFrameFilter(); //
52 
53 protected:
54  bool active;
57  bool ready;
60  bool initialized;
61  long int mstimestamp0;
62  long int zerotime;
63  long int prevpts;
64  bool zerotimeset;
65  bool testflag;
66  // bool sps_ok, pps_ok;
67 
68  std::string format_name;
69 
70 public: // so that child static methods can access..
71  uint32_t missing, ccf;
72 
73 protected: //libav stuff
74  AVFormatContext *av_format_ctx;
75  AVIOContext *avio_ctx;
76  uint8_t *avio_ctx_buffer;
77  AVRational timebase;
78  std::vector<AVCodecContext*> codec_contexes;
79  std::vector<AVStream*> streams;
80  AVFormatContext *av_format_context;
81  AVPacket *avpkt;
82  AVDictionary *av_dict;
83  //AVBufferRef *avbuffer;
84 
85  static const size_t avio_ctx_buffer_size = 4096;
86 
87 protected: //mutex stuff
88  std::mutex mutex;
89  std::condition_variable condition;
90 
91 protected: //frames
92  std::vector<SetupFrame> setupframes;
93 
94 public:
95  BasicFrame internal_basicframe;
98 
99 protected:
100  virtual void defineMux() = 0;
101  virtual void go(Frame* frame);
102  virtual void run(Frame* frame);
103  void initMux();
104  void closeMux();
105  void deActivate_();
106  void writeFrame(BasicFrame* frame);
107 
108 public: // API calls // <pyapi>
109  // setFileName(const char* fname); ///< Sets the output filename // <pyapi>
110  void activate(long int zerotime=0);
111  void deActivate();
112 
113 protected:
114  static int write_packet(void *opaque, uint8_t *buf, int buf_size); // define separately in child classes
115  static int read_packet(void *opaque, uint8_t *buf, int buf_size) {return 0;} // dummy function
116  static int64_t seek(void *opaque, int64_t offset, int whence) {return 0;} // dummy function
117 }; // <pyapi>
118 
119 
120 class FragMP4MuxFrameFilter : public MuxFrameFilter { // <pyapi>
121 
122 public: // <pyapi>
123  FragMP4MuxFrameFilter(const char* name, FrameFilter *next = NULL); // <pyapi>
124  virtual ~FragMP4MuxFrameFilter(); // <pyapi>
125 
126 public:
127  bool got_ftyp, got_moov;
128  MuxFrame ftyp_frame, moov_frame;
129 
130 protected:
131  virtual void defineMux();
132 
133 public: // API calls // <pyapi>
134  void sendMeta(); // <pyapi>
135 
136 protected:
137  static int write_packet(void *opaque, uint8_t *buf, int buf_size_);
138  static int read_packet(void *opaque, uint8_t *buf, int buf_size) {return 0;} // {std::cout << "muxer: dummy read packet" << std::endl; return 0;} // dummy function
139  static int64_t seek(void *opaque, int64_t offset, int whence) {return 0;}// {std::cout << "muxer: dummy seek" << std::endl; return 0;} // dummy function
140 }; // <pyapi>
141 
142 
143 // helper functions for minimal MP4 parsing
144 // the right way to do this:
145 // class: MP4Box with subclasses like moov, moof, etc.
146 // all boxes have pointers to the point in memory where they start
147 // MP4Box has a child-parent structure, can iterate over children, etc.
148 
149 
152 void getLenName(uint8_t* data, uint32_t& len, char* name);
153 
156 uint32_t getSubBoxIndex(uint8_t* data, const char name[4]);
157 
158 /* Example usage:
159 
160 char name[4];
161 getLenName(payload.data(), len, &name[0])
162 
163 if strcmp(name, "moof") == 0 {
164  i_traf = getSubBoxIndex(payload.data(), "traf")
165  i_trun = getSubBoxIndex(payload.data() + i, "trun")
166  getLenName(payload.data() + i_trun, len, name) # this shoud be "trun"
167  # now inspect the payload.data() + i_trun
168 }
169 
170 */
171 
172 bool moofHasFirstSampleFlag(uint8_t* data);
173 
174 #endif
Custom payload Frame.
Definition: frame.h:166
Definition: muxer.h:120
virtual void defineMux()
Define container format (format_name) & muxing parameters (av_dict). Define in child classes.
Definition: muxer.cpp:617
static int write_packet(void *opaque, uint8_t *buf, int buf_size_)
Definition: muxer.cpp:638
The mother class of all frame filters! FrameFilters are used to create "filter chains".
Definition: framefilter.h:44
FrameFilter * next
The next frame filter in the chain to be applied.
Definition: framefilter.h:60
Frame: An abstract queueable class.
Definition: frame.h:112
Definition: muxer.h:47
void deActivate()
Stop streaming // <pyapi>
Definition: muxer.cpp:575
std::mutex mutex
Mutex protecting the "active" boolean.
Definition: muxer.h:88
std::vector< SetupFrame > setupframes
deep copies of the arrived setup frames
Definition: muxer.h:92
long int zerotime
Start time set explicitly by the user.
Definition: muxer.h:62
long int mstimestamp0
Time of activation (i.e. when the recording started)
Definition: muxer.h:61
bool initialized
After ready & active, initMux is called (set streams, codec ctx, etc.
Definition: muxer.h:60
BasicFrame extradata_frame
capture decoder extradata here
Definition: muxer.h:97
bool has_extradata
Got "extradata" (sps & pps)
Definition: muxer.h:55
virtual void run(Frame *frame)
Calls this->go(Frame* frame) and then calls the this->next->run(Frame* frame) (if this->next !...
Definition: muxer.cpp:302
virtual void defineMux()=0
Define container format (format_name) & muxing parameters (av_dict). Define in child classes.
virtual void go(Frame *frame)
Does the actual filtering/modification to the Frame. Define in subclass.
Definition: muxer.cpp:308
bool ready
Got enough setup frames & extradata.
Definition: muxer.h:57
MuxFrame internal_frame
outgoing muxed frame
Definition: muxer.h:96
void initMux()
Open file, reserve codec_contexes, streams, write preamble, set initialized=true if success.
Definition: muxer.cpp:93
std::condition_variable condition
Condition variable for the mutex.
Definition: muxer.h:89
int extradata_count
Check that we have the sps => pps sequence.
Definition: muxer.h:56
void activate(long int zerotime=0)
Request streaming to asap (when config frames have arrived) // <pyapi>
Definition: muxer.cpp:564
bool active
Writing to muxer has been requested.
Definition: muxer.h:54
void closeMux()
Close file, dealloc codec_contexes, streams.
Definition: muxer.cpp:256
A muxed packet (in some container format)
Definition: frame.h:220
Constant/default values, version numbers.
Definition of FrameFilter and derived classes for various purposes.
uint32_t getSubBoxIndex(uint8_t *data, const char name[4])
Gives index of a certain MP4 sub-box, as identified by the box type's name.
Definition: muxer.cpp:810
void getLenName(uint8_t *data, uint32_t &len, char *name)
Gives length and name of an MP4 box.
Definition: muxer.cpp:804