Skip to content

Commit ffc8a37

Browse files
committed
added a frame count to the stream info
1 parent 0874f7c commit ffc8a37

File tree

6 files changed

+60
-21
lines changed

6 files changed

+60
-21
lines changed

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/InputStream.cpp

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,6 @@ namespace ffmpegcpp
2828
}
2929

3030
codecContext->framerate = stream->avg_frame_rate;
31-
}
32-
33-
InputStream::~InputStream()
34-
{
35-
CleanUp();
36-
}
37-
38-
void InputStream::ConfigureCodecContext()
39-
{
40-
// does nothing by default
41-
}
42-
43-
void InputStream::Open(FrameSink* frameSink)
44-
{
45-
output = frameSink->CreateStream();
46-
47-
const AVCodec* codec = codecContext->codec;
4831

4932
// Copy codec parameters from input stream to output codec context
5033
int ret;
@@ -76,6 +59,21 @@ namespace ffmpegcpp
7659
}
7760
}
7861

62+
InputStream::~InputStream()
63+
{
64+
CleanUp();
65+
}
66+
67+
void InputStream::ConfigureCodecContext()
68+
{
69+
// does nothing by default
70+
}
71+
72+
void InputStream::Open(FrameSink* frameSink)
73+
{
74+
output = frameSink->CreateStream();
75+
}
76+
7977
void InputStream::CleanUp()
8078
{
8179
if (codecContext != nullptr)
@@ -158,13 +156,26 @@ namespace ffmpegcpp
158156
// push the frame to the next stage.
159157
// The time_base is filled in in the codecContext after the first frame is decoded
160158
// so we can fetch it from there.
161-
output->WriteFrame(frame, metaData);
159+
if (output == nullptr)
160+
{
161+
// No frame sink specified - just release the frame again.
162+
}
163+
else
164+
{
165+
output->WriteFrame(frame, metaData);
166+
}
167+
++nFramesProcessed;
162168
}
163169
}
164170

171+
int InputStream::GetFramesProcessed()
172+
{
173+
return nFramesProcessed;
174+
}
175+
165176
void InputStream::Close()
166177
{
167-
output->Close();
178+
if (output != nullptr) output->Close();
168179
}
169180

170181
bool InputStream::IsPrimed()

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/InputStream.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace ffmpegcpp
2121
void Close();
2222

2323
bool IsPrimed();
24+
int GetFramesProcessed();
2425

2526
virtual void AddStreamInfo(ContainerInfo* info) = 0;
2627

@@ -41,14 +42,15 @@ namespace ffmpegcpp
4142

4243
AVRational timeBaseCorrectedByTicksPerFrame;
4344

44-
45-
FrameSinkStream* output;
45+
FrameSinkStream* output = nullptr;
4646

4747
AVFrame* frame;
4848

4949
StreamData* metaData = nullptr;
5050

5151
StreamData* DiscoverMetaData();
52+
53+
int nFramesProcessed = 0;
5254

5355
void CleanUp();
5456

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/VideoInputStream.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ namespace ffmpegcpp
2222
{
2323
VideoStreamInfo info;
2424

25+
info.id = stream->id - 1; // starts counting from 1!
26+
2527
AVRational overrideFrameRate;
2628
overrideFrameRate.num = 0;
2729

source/ffmpeg-cpp/ffmpeg-cpp/Sources/Demuxer.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ namespace ffmpegcpp
182182
// already exists
183183
if (inputStreams[streamIndex] != nullptr) return inputStreams[streamIndex];
184184

185+
// The stream doesn't exist but we already processed all our frames, so it makes no sense
186+
// to add it anymore.
187+
if (IsDone()) throw new FFmpegException("Demuxer already fully processed... you cannot use it anymore.");
188+
185189
AVStream* stream = containerContext->streams[streamIndex];
186190
AVCodec* codec = CodecDeducer::DeduceDecoder(stream->codecpar->codec_id);
187191
if (codec == nullptr) return nullptr; // no codec found - we can't really do anything with this stream!
@@ -303,4 +307,22 @@ namespace ffmpegcpp
303307

304308
return info;
305309
}
310+
311+
int Demuxer::GetFrameCount(int streamId)
312+
{
313+
// Make sure all streams exist, so we can query them later.
314+
for (int i = 0; i < containerContext->nb_streams; ++i)
315+
{
316+
GetInputStream(i);
317+
}
318+
319+
// Process the entire container so we can know how many frames are in each
320+
while (!IsDone())
321+
{
322+
Step();
323+
}
324+
325+
// Return the right stream's frame count.
326+
return GetInputStream(streamId)->GetFramesProcessed();
327+
}
306328
}

source/ffmpeg-cpp/ffmpeg-cpp/Sources/Demuxer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace ffmpegcpp
3030
virtual void Step();
3131

3232
ContainerInfo GetInfo();
33+
int GetFrameCount(int streamId);
3334

3435
private:
3536

source/ffmpeg-cpp/print_info/print_info.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ int main()
3030
<< ", bit rate " << stream.bitRate << "kb/s"
3131
<< ", fps " << ((float)stream.frameRate.num / (float)stream.frameRate.den)
3232
<< ", time base " << stream.timeBase.num << "/" << stream.timeBase.den
33+
<< ", " << demuxer->GetFrameCount(stream.id) << " frames"
3334
<< endl;
3435
}
3536

0 commit comments

Comments
 (0)