@@ -100,12 +100,13 @@ std::tuple<double, double> NO_WINDOW{
100
100
template <MediaType media_type>
101
101
PacketsPtr<media_type> demux_window (
102
102
DataInterface* di,
103
- AVStream* stream,
104
103
const std::optional<std::tuple<double , double >>& window = std::nullopt,
105
104
const std::optional<std::string>& bsf = std::nullopt) {
106
105
TRACE_EVENT (" demuxing" , " detail::demux_window" );
107
106
auto [start, end] = window ? *window : NO_WINDOW;
108
107
108
+ auto stream = get_stream (di, media_type);
109
+
109
110
if constexpr (media_type == MediaType::Video) {
110
111
// Note:
111
112
// Since the video frames can be non-chronological order, so we add small
@@ -145,24 +146,25 @@ PacketsPtr<media_type> demux_window(
145
146
break ;
146
147
}
147
148
}
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
+ }
148
153
return ret;
149
154
}
150
155
151
156
template PacketsPtr<MediaType::Audio> demux_window (
152
157
DataInterface* fmt_ctx,
153
- AVStream* stream,
154
158
const std::optional<std::tuple<double , double >>& window,
155
159
const std::optional<std::string>& bsf);
156
160
157
161
template PacketsPtr<MediaType::Video> demux_window (
158
162
DataInterface* fmt_ctx,
159
- AVStream* stream,
160
163
const std::optional<std::tuple<double , double >>& window,
161
164
const std::optional<std::string>& bsf);
162
165
163
166
template PacketsPtr<MediaType::Image> demux_window (
164
167
DataInterface* fmt_ctx,
165
- AVStream* stream,
166
168
const std::optional<std::tuple<double , double >>& window,
167
169
const std::optional<std::string>& bsf);
168
170
@@ -182,29 +184,35 @@ Generator<PacketsPtr<media_type>> streaming_demux(
182
184
return BitStreamFilter{*bsf, stream->codecpar };
183
185
}();
184
186
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
+ };
185
201
auto demuxing = demux_and_filter (fmt_ctx, stream, filter);
186
202
std::vector<AVPacket*> packets;
187
203
packets.reserve (num_packets);
188
204
while (demuxing) {
189
205
packets.push_back (demuxing ().release ());
190
206
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));
196
208
197
209
packets = std::vector<AVPacket*>();
198
210
packets.reserve (num_packets);
199
211
}
200
212
}
201
213
202
214
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));
208
216
}
209
217
}
210
218
0 commit comments