Skip to content

Commit bac4f7d

Browse files
authored
Fix frame rate for streaming video demuxing (#470)
and simplify impl for demux_window
1 parent 1825ab4 commit bac4f7d

File tree

2 files changed

+23
-24
lines changed

2 files changed

+23
-24
lines changed

src/libspdl/core/demuxing.cpp

+1-10
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ namespace spdl::core {
2222
namespace detail {
2323
// Implemented in core/detail/ffmpeg/demuxing.cpp
2424
void init_fmt_ctx(DataInterface*);
25-
AVStream* get_stream(DataInterface*, enum MediaType);
2625
template <MediaType media_type>
2726
Generator<PacketsPtr<media_type>> streaming_demux(
2827
DataInterface* di,
@@ -32,7 +31,6 @@ Generator<PacketsPtr<media_type>> streaming_demux(
3231
template <MediaType media_type>
3332
PacketsPtr<media_type> demux_window(
3433
DataInterface*,
35-
AVStream* stream,
3634
const std::optional<std::tuple<double, double>>& window = std::nullopt,
3735
const std::optional<std::string>& bsf = std::nullopt);
3836

@@ -107,14 +105,7 @@ template <MediaType media_type>
107105
PacketsPtr<media_type> Demuxer::demux_window(
108106
const std::optional<std::tuple<double, double>>& window,
109107
const std::optional<std::string>& bsf) {
110-
auto stream = detail::get_stream(di.get(), media_type);
111-
auto packets =
112-
detail::demux_window<media_type>(di.get(), stream, window, bsf);
113-
if constexpr (media_type == MediaType::Video) {
114-
auto frame_rate = av_guess_frame_rate(fmt_ctx, stream, nullptr);
115-
packets->frame_rate = Rational{frame_rate.num, frame_rate.den};
116-
}
117-
return packets;
108+
return detail::demux_window<media_type>(di.get(), window, bsf);
118109
}
119110

120111
template PacketsPtr<MediaType::Audio> Demuxer::demux_window(

src/libspdl/core/detail/ffmpeg/demuxing.cpp

+22-14
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,13 @@ std::tuple<double, double> NO_WINDOW{
100100
template <MediaType media_type>
101101
PacketsPtr<media_type> demux_window(
102102
DataInterface* di,
103-
AVStream* stream,
104103
const std::optional<std::tuple<double, double>>& window = std::nullopt,
105104
const std::optional<std::string>& bsf = std::nullopt) {
106105
TRACE_EVENT("demuxing", "detail::demux_window");
107106
auto [start, end] = window ? *window : NO_WINDOW;
108107

108+
auto stream = get_stream(di, media_type);
109+
109110
if constexpr (media_type == MediaType::Video) {
110111
// Note:
111112
// Since the video frames can be non-chronological order, so we add small
@@ -145,24 +146,25 @@ PacketsPtr<media_type> demux_window(
145146
break;
146147
}
147148
}
149+
if constexpr (media_type == MediaType::Video) {
150+
auto frame_rate = av_guess_frame_rate(fmt_ctx, stream, nullptr);
151+
ret->frame_rate = Rational{frame_rate.num, frame_rate.den};
152+
}
148153
return ret;
149154
}
150155

151156
template PacketsPtr<MediaType::Audio> demux_window(
152157
DataInterface* fmt_ctx,
153-
AVStream* stream,
154158
const std::optional<std::tuple<double, double>>& window,
155159
const std::optional<std::string>& bsf);
156160

157161
template PacketsPtr<MediaType::Video> demux_window(
158162
DataInterface* fmt_ctx,
159-
AVStream* stream,
160163
const std::optional<std::tuple<double, double>>& window,
161164
const std::optional<std::string>& bsf);
162165

163166
template PacketsPtr<MediaType::Image> demux_window(
164167
DataInterface* fmt_ctx,
165-
AVStream* stream,
166168
const std::optional<std::tuple<double, double>>& window,
167169
const std::optional<std::string>& bsf);
168170

@@ -182,29 +184,35 @@ Generator<PacketsPtr<media_type>> streaming_demux(
182184
return BitStreamFilter{*bsf, stream->codecpar};
183185
}();
184186

187+
Rational frame_rate;
188+
if constexpr (media_type == MediaType::Video) {
189+
auto fr = av_guess_frame_rate(fmt_ctx, stream, nullptr);
190+
frame_rate = Rational{fr.num, fr.den};
191+
}
192+
auto make_packets = [&](std::vector<AVPacket*>&& pkts) {
193+
auto ret = std::make_unique<DemuxedPackets<media_type>>(
194+
di->get_src(),
195+
bsf ? filter->get_output_codec_par() : stream->codecpar,
196+
Rational{stream->time_base.num, stream->time_base.den},
197+
std::move(pkts));
198+
ret->frame_rate = frame_rate;
199+
return std::move(ret);
200+
};
185201
auto demuxing = demux_and_filter(fmt_ctx, stream, filter);
186202
std::vector<AVPacket*> packets;
187203
packets.reserve(num_packets);
188204
while (demuxing) {
189205
packets.push_back(demuxing().release());
190206
if (packets.size() >= num_packets) {
191-
co_yield std::make_unique<DemuxedPackets<media_type>>(
192-
di->get_src(),
193-
bsf ? filter->get_output_codec_par() : stream->codecpar,
194-
Rational{stream->time_base.num, stream->time_base.den},
195-
std::move(packets));
207+
co_yield make_packets(std::move(packets));
196208

197209
packets = std::vector<AVPacket*>();
198210
packets.reserve(num_packets);
199211
}
200212
}
201213

202214
if (packets.size() > 0) {
203-
co_yield std::make_unique<DemuxedPackets<media_type>>(
204-
di->get_src(),
205-
bsf ? filter->get_output_codec_par() : stream->codecpar,
206-
Rational{stream->time_base.num, stream->time_base.den},
207-
std::move(packets));
215+
co_yield make_packets(std::move(packets));
208216
}
209217
}
210218

0 commit comments

Comments
 (0)