Skip to content

Commit 0f8f7a8

Browse files
committed
timeBase was propagated incorrectly, so replaced it by a more robust, proper MetaData system that separates frame rate from time base
1 parent 3fcad71 commit 0f8f7a8

27 files changed

+154
-82
lines changed

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/AudioInputStream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace ffmpegcpp
44
{
5-
AudioInputStream::AudioInputStream(AudioFrameSink* frameSink, AVStream* stream)
6-
: InputStream(stream)
5+
AudioInputStream::AudioInputStream(AudioFrameSink* frameSink, AVFormatContext* format, AVStream* stream)
6+
: InputStream(format, stream)
77
{
88
SetFrameSink(frameSink);
99
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ffmpegcpp
1111

1212
public:
1313

14-
AudioInputStream(AudioFrameSink* frameSink, AVStream* stream);
14+
AudioInputStream(AudioFrameSink* frameSink, AVFormatContext* format, AVStream* stream);
1515
~AudioInputStream();
1616

1717
protected:

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

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ using namespace std;
66

77
namespace ffmpegcpp
88
{
9-
InputStream::InputStream(AVStream* stream)
9+
InputStream::InputStream(AVFormatContext* format, AVStream* stream)
1010
{
1111
this->stream = stream;
12+
this->format = format;
1213

1314
// find decoder for the stream
1415
AVCodec* codec = CodecDeducer::DeduceDecoder(stream->codecpar->codec_id);
@@ -85,14 +86,43 @@ namespace ffmpegcpp
8586
av_frame_free(&frame);
8687
frame = nullptr;
8788
}
89+
if (metaData != nullptr)
90+
{
91+
delete metaData;
92+
metaData = nullptr;
93+
}
8894
}
8995

9096
void InputStream::SetFrameSink(FrameSink* frameSink)
9197
{
9298
output = frameSink->CreateStream();
9399
}
94100

95-
int inputSampleCount = 0;
101+
StreamData* InputStream::DiscoverMetaData()
102+
{
103+
/*metaData = new StreamData();
104+
105+
AVRational* time_base = &timeBaseCorrectedByTicksPerFrame;
106+
if (!timeBaseCorrectedByTicksPerFrame.num)
107+
{
108+
time_base = &stream->time_base;
109+
}
110+
111+
metaData->timeBase.num = time_base->num;
112+
metaData->timeBase.den = time_base->den;*/
113+
114+
AVRational overrideFrameRate;
115+
overrideFrameRate.num = 0;
116+
117+
AVRational tb = overrideFrameRate.num ? av_inv_q(overrideFrameRate) : stream->time_base;
118+
AVRational fr = overrideFrameRate;
119+
if (!fr.num) fr = av_guess_frame_rate(format, stream, NULL);
120+
121+
StreamData* metaData = new StreamData();
122+
metaData->timeBase = tb;
123+
metaData->frameRate = fr;
124+
return metaData;
125+
}
96126

97127
void InputStream::DecodePacket(AVPacket *pkt)
98128
{
@@ -122,16 +152,16 @@ namespace ffmpegcpp
122152
frame->sample_aspect_ratio = stream->sample_aspect_ratio;
123153
}
124154

125-
AVRational* time_base = &timeBaseCorrectedByTicksPerFrame;
126-
if (!timeBaseCorrectedByTicksPerFrame.num)
155+
// the meta data does not exist yet - we figure it out!
156+
if (metaData == nullptr)
127157
{
128-
time_base = &stream->time_base;
158+
metaData = DiscoverMetaData();
129159
}
130160

131161
// push the frame to the next stage.
132162
// The time_base is filled in in the codecContext after the first frame is decoded
133163
// so we can fetch it from there.
134-
output->WriteFrame(frame, time_base);
164+
output->WriteFrame(frame, metaData);
135165
}
136166
}
137167

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ffmpegcpp
1111

1212
public:
1313

14-
InputStream(AVStream* stream);
14+
InputStream(AVFormatContext* format, AVStream* stream);
1515
~InputStream();
1616

1717
void Open();
@@ -33,11 +33,16 @@ namespace ffmpegcpp
3333

3434
AVRational timeBaseCorrectedByTicksPerFrame;
3535

36+
AVFormatContext* format;
3637
AVStream* stream;
3738

3839
FrameSinkStream* output;
3940

4041
AVFrame* frame;
42+
43+
StreamData* metaData = nullptr;
44+
45+
StreamData* DiscoverMetaData();
4146

4247
void CleanUp();
4348
};

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/StreamData.cpp

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include "ffmpeg.h"
4+
5+
namespace ffmpegcpp
6+
{
7+
struct StreamData
8+
{
9+
AVRational timeBase;
10+
AVRational frameRate;
11+
};
12+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace ffmpegcpp
44
{
5-
VideoInputStream::VideoInputStream(VideoFrameSink* frameSink, AVStream* stream)
6-
: InputStream(stream)
5+
VideoInputStream::VideoInputStream(VideoFrameSink* frameSink, AVFormatContext* format, AVStream* stream)
6+
: InputStream(format, stream)
77
{
88
SetFrameSink(frameSink);
99
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ffmpegcpp
1111

1212
public:
1313

14-
VideoInputStream(VideoFrameSink* frameSink, AVStream* stream);
14+
VideoInputStream(VideoFrameSink* frameSink, AVFormatContext* format, AVStream* stream);
1515
~VideoInputStream();
1616

1717
protected:

source/ffmpeg-cpp/ffmpeg-cpp/Frame Sinks/AudioEncoder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace ffmpegcpp
2626
finalBitRate = bitRate;
2727
}
2828

29-
void AudioEncoder::OpenLazily(AVFrame* frame, AVRational* timeBase)
29+
void AudioEncoder::OpenLazily(AVFrame* frame, StreamData* metaData)
3030
{
3131
// configure the parameters for the codec based on the frame, our settings & defaults
3232
int bitRate = finalBitRate;
@@ -92,12 +92,12 @@ namespace ffmpegcpp
9292
return oneInputFrameSink->CreateStream();
9393
}
9494

95-
void AudioEncoder::WriteFrame(int streamIndex, AVFrame* frame, AVRational* timeBase)
95+
void AudioEncoder::WriteFrame(int streamIndex, AVFrame* frame, StreamData* metaData)
9696
{
9797
// if we haven't opened the codec yet, we do it now!
9898
if (codec == nullptr)
9999
{
100-
OpenLazily(frame, timeBase);
100+
OpenLazily(frame, metaData);
101101
}
102102

103103
// set the PTS properly

source/ffmpeg-cpp/ffmpeg-cpp/Frame Sinks/AudioEncoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace ffmpegcpp
2121
virtual ~AudioEncoder();
2222

2323
FrameSinkStream* CreateStream();
24-
void WriteFrame(int streamIndex, AVFrame* frame, AVRational* timeBase);
24+
void WriteFrame(int streamIndex, AVFrame* frame, StreamData* metaData);
2525
void Close(int streamIndex);
2626

2727
virtual void WriteConvertedFrame(AVFrame* frame);
@@ -30,7 +30,7 @@ namespace ffmpegcpp
3030

3131
private:
3232

33-
void OpenLazily(AVFrame* frame, AVRational* timeBase);
33+
void OpenLazily(AVFrame* frame, StreamData* metaData);
3434

3535
void CleanUp();
3636

0 commit comments

Comments
 (0)