Commit 1ee56bf09afe357467cce5e90d1f2c7638afed9d
1 parent
f330d4d8
fix timestamps for keyframesGallery
Showing
1 changed file
with
41 additions
and
10 deletions
openbr/plugins/gallery/keyframes.cpp
| ... | ... | @@ -59,6 +59,7 @@ public: |
| 59 | 59 | fps = 0.f; |
| 60 | 60 | time_base = 0.f; |
| 61 | 61 | idx = 0; |
| 62 | + idxOffset = -1; | |
| 62 | 63 | } |
| 63 | 64 | |
| 64 | 65 | ~keyframesGallery() |
| ... | ... | @@ -95,6 +96,9 @@ public: |
| 95 | 96 | frame = av_frame_alloc(); |
| 96 | 97 | cvt_frame = av_frame_alloc(); |
| 97 | 98 | |
| 99 | + av_init_packet(&packet); | |
| 100 | + packet.data = NULL; | |
| 101 | + packet.size = 0; | |
| 98 | 102 | // Get fps, stream time_base and allocate space for frame buffer with av_malloc. |
| 99 | 103 | fps = (float)avFormatCtx->streams[streamID]->avg_frame_rate.num / |
| 100 | 104 | (float)avFormatCtx->streams[streamID]->avg_frame_rate.den; |
| ... | ... | @@ -128,26 +132,50 @@ public: |
| 128 | 132 | Template output; |
| 129 | 133 | output.file = file; |
| 130 | 134 | |
| 131 | - AVPacket packet; | |
| 132 | - av_init_packet(&packet); | |
| 135 | + | |
| 133 | 136 | int ret = 0; |
| 134 | 137 | while (!ret) { |
| 135 | 138 | if (av_read_frame(avFormatCtx, &packet) >= 0) { |
| 136 | 139 | if (packet.stream_index == streamID) { |
| 137 | 140 | avcodec_decode_video2(avCodecCtx, frame, &ret, &packet); |
| 138 | - idx = packet.dts; // decompression timestamp | |
| 141 | + // Use presentation timestamp if available | |
| 142 | + // Otherwise decode timestamp | |
| 143 | + if (frame->pkt_pts != AV_NOPTS_VALUE) | |
| 144 | + idx = frame->pkt_pts; | |
| 145 | + else | |
| 146 | + idx = frame->pkt_dts; | |
| 147 | + | |
| 139 | 148 | av_free_packet(&packet); |
| 140 | 149 | } else { |
| 141 | 150 | av_free_packet(&packet); |
| 142 | 151 | } |
| 143 | 152 | } else { |
| 144 | - av_free_packet(&packet); | |
| 145 | - release(); | |
| 146 | - *done = true; | |
| 147 | - return TemplateList(); | |
| 153 | + AVPacket empty_packet; | |
| 154 | + av_init_packet(&empty_packet); | |
| 155 | + empty_packet.data = NULL; | |
| 156 | + empty_packet.size = 0; | |
| 157 | + | |
| 158 | + avcodec_decode_video2(avCodecCtx, frame, &ret, &empty_packet); | |
| 159 | + if (frame->pkt_pts != AV_NOPTS_VALUE) | |
| 160 | + idx = frame->pkt_pts; | |
| 161 | + else if (frame->pkt_dts != AV_NOPTS_VALUE) | |
| 162 | + idx = frame->pkt_dts; | |
| 163 | + else // invalid frame | |
| 164 | + ret = 0; | |
| 165 | + | |
| 166 | + if (!ret) { | |
| 167 | + av_free_packet(&packet); | |
| 168 | + av_free_packet(&empty_packet); | |
| 169 | + release(); | |
| 170 | + *done = true; | |
| 171 | + return TemplateList(); | |
| 172 | + } | |
| 148 | 173 | } |
| 149 | 174 | } |
| 150 | 175 | |
| 176 | + if (idxOffset < 0) { | |
| 177 | + idxOffset = idx; | |
| 178 | + } | |
| 151 | 179 | // Convert from native format |
| 152 | 180 | sws_scale(avSwsCtx, |
| 153 | 181 | frame->data, |
| ... | ... | @@ -164,9 +192,9 @@ public: |
| 164 | 192 | avcodec_flush_buffers(avCodecCtx); |
| 165 | 193 | |
| 166 | 194 | QString URL = file.get<QString>("URL", file.name); |
| 167 | - output.file.set("URL", URL + "#t=" + QString::number((int)(idx * time_base)) + "s"); | |
| 168 | - output.file.set("timestamp", QString::number((int)(idx * time_base * 1000))); | |
| 169 | - output.file.set("frame", QString::number(idx * time_base * fps)); | |
| 195 | + output.file.set("URL", URL + "#t=" + QString::number((int)((idx-idxOffset) * time_base)) + "s"); | |
| 196 | + output.file.set("timestamp", QString::number((int)((idx-idxOffset) * time_base * 1000))); | |
| 197 | + output.file.set("frame", QString::number((idx-idxOffset) * time_base * fps)); | |
| 170 | 198 | TemplateList dst; |
| 171 | 199 | dst.append(output); |
| 172 | 200 | return dst; |
| ... | ... | @@ -204,7 +232,10 @@ protected: |
| 204 | 232 | AVCodec *avCodec; |
| 205 | 233 | AVFrame *frame; |
| 206 | 234 | AVFrame *cvt_frame; |
| 235 | + AVPacket packet; | |
| 207 | 236 | uint8_t *buffer; |
| 237 | + | |
| 238 | + int64_t idxOffset; | |
| 208 | 239 | bool opened; |
| 209 | 240 | int streamID; |
| 210 | 241 | float fps; | ... | ... |