1
+ /*
2
+ ** Command & Conquer Generals Zero Hour(tm)
3
+ ** Copyright 2025 TheSuperHackers
4
+ **
5
+ ** This program is free software: you can redistribute it and/or modify
6
+ ** it under the terms of the GNU General Public License as published by
7
+ ** the Free Software Foundation, either version 3 of the License, or
8
+ ** (at your option) any later version.
9
+ **
10
+ ** This program is distributed in the hope that it will be useful,
11
+ ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ ** GNU General Public License for more details.
14
+ **
15
+ ** You should have received a copy of the GNU General Public License
16
+ ** along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ // //////////////////////////////////////////////////////////////////////////////
20
+ // //
21
+ // (c) 2001-2003 Electronic Arts Inc. //
22
+ // //
23
+ // //////////////////////////////////////////////////////////////////////////////
24
+
25
+ // ////// FFmpegFile.h ///////////////////////////
26
+ // Stephan Vedder, April 2025
27
+ // ///////////////////////////////////////////////
28
+
29
+ #pragma once
30
+
31
+ #include < Lib/BaseType.h>
32
+
33
+ #include < functional>
34
+ #include < vector>
35
+
36
+ struct AVFormatContext ;
37
+ struct AVIOContext ;
38
+ struct AVCodec ;
39
+ struct AVCodecContext ;
40
+ struct AVFrame ;
41
+ struct AVPacket ;
42
+ struct File ;
43
+
44
+ using FFmpegFrameCallback = std::function<void (AVFrame *, int , int , void *)>;
45
+
46
+ class FFmpegFile
47
+ {
48
+ public:
49
+ FFmpegFile ();
50
+ // The constructur takes ownership of the file
51
+ explicit FFmpegFile (File *file);
52
+ ~FFmpegFile ();
53
+
54
+ Bool open (File *file);
55
+ void close ();
56
+ void setFrameCallback (FFmpegFrameCallback callback) { m_frameCallback = callback; }
57
+ void setUserData (void *user_data) { m_userData = user_data; }
58
+ // Read & decode a packet from the container. Note that we could/should split this step
59
+ Bool decodePacket ();
60
+ void seekFrame (int frame_idx);
61
+ Bool hasAudio () const ;
62
+
63
+ // Audio specific
64
+ Int getSizeForSamples (Int numSamples) const ;
65
+ Int getNumChannels () const ;
66
+ Int getSampleRate () const ;
67
+ Int getBytesPerSample () const ;
68
+
69
+ // Video specific
70
+ Int getWidth () const ;
71
+ Int getHeight () const ;
72
+ Int getNumFrames () const ;
73
+ Int getCurrentFrame () const ;
74
+ Int getPixelFormat () const ;
75
+ UnsignedInt getFrameTime () const ;
76
+
77
+ private:
78
+ struct FFmpegStream
79
+ {
80
+ AVCodecContext *codec_ctx = nullptr ;
81
+ const AVCodec *codec = nullptr ;
82
+ Int stream_idx = -1 ;
83
+ Int stream_type = -1 ;
84
+ AVFrame *frame = nullptr ;
85
+ };
86
+
87
+ static Int readPacket (void *opaque, UnsignedByte *buf, Int buf_size);
88
+ const FFmpegStream *findMatch (int type) const ;
89
+
90
+ FFmpegFrameCallback m_frameCallback = nullptr ; // /< Callback for frame processing
91
+ AVFormatContext *m_fmtCtx = nullptr ; // /< Format context for AVFormat
92
+ AVIOContext *m_avioCtx = nullptr ; // /< IO context for AVFormat
93
+ AVPacket *m_packet = nullptr ; // /< Current packet
94
+ std::vector<FFmpegStream> m_streams; // /< List of streams in the file
95
+ File *m_file = nullptr ; // /< File handle for the file
96
+ void *m_userData = nullptr ; // /< User data for the callback
97
+ };
0 commit comments