Commit 1ee56bf09afe357467cce5e90d1f2c7638afed9d

Authored by bhklein
1 parent f330d4d8

fix timestamps for keyframesGallery

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;
... ...