Commit 1ee56bf09afe357467cce5e90d1f2c7638afed9d

Authored by bhklein
1 parent f330d4d8

fix timestamps for keyframesGallery

openbr/plugins/gallery/keyframes.cpp
@@ -59,6 +59,7 @@ public: @@ -59,6 +59,7 @@ public:
59 fps = 0.f; 59 fps = 0.f;
60 time_base = 0.f; 60 time_base = 0.f;
61 idx = 0; 61 idx = 0;
  62 + idxOffset = -1;
62 } 63 }
63 64
64 ~keyframesGallery() 65 ~keyframesGallery()
@@ -95,6 +96,9 @@ public: @@ -95,6 +96,9 @@ public:
95 frame = av_frame_alloc(); 96 frame = av_frame_alloc();
96 cvt_frame = av_frame_alloc(); 97 cvt_frame = av_frame_alloc();
97 98
  99 + av_init_packet(&packet);
  100 + packet.data = NULL;
  101 + packet.size = 0;
98 // Get fps, stream time_base and allocate space for frame buffer with av_malloc. 102 // Get fps, stream time_base and allocate space for frame buffer with av_malloc.
99 fps = (float)avFormatCtx->streams[streamID]->avg_frame_rate.num / 103 fps = (float)avFormatCtx->streams[streamID]->avg_frame_rate.num /
100 (float)avFormatCtx->streams[streamID]->avg_frame_rate.den; 104 (float)avFormatCtx->streams[streamID]->avg_frame_rate.den;
@@ -128,26 +132,50 @@ public: @@ -128,26 +132,50 @@ public:
128 Template output; 132 Template output;
129 output.file = file; 133 output.file = file;
130 134
131 - AVPacket packet;  
132 - av_init_packet(&packet); 135 +
133 int ret = 0; 136 int ret = 0;
134 while (!ret) { 137 while (!ret) {
135 if (av_read_frame(avFormatCtx, &packet) >= 0) { 138 if (av_read_frame(avFormatCtx, &packet) >= 0) {
136 if (packet.stream_index == streamID) { 139 if (packet.stream_index == streamID) {
137 avcodec_decode_video2(avCodecCtx, frame, &ret, &packet); 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 av_free_packet(&packet); 148 av_free_packet(&packet);
140 } else { 149 } else {
141 av_free_packet(&packet); 150 av_free_packet(&packet);
142 } 151 }
143 } else { 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 // Convert from native format 179 // Convert from native format
152 sws_scale(avSwsCtx, 180 sws_scale(avSwsCtx,
153 frame->data, 181 frame->data,
@@ -164,9 +192,9 @@ public: @@ -164,9 +192,9 @@ public:
164 avcodec_flush_buffers(avCodecCtx); 192 avcodec_flush_buffers(avCodecCtx);
165 193
166 QString URL = file.get<QString>("URL", file.name); 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 TemplateList dst; 198 TemplateList dst;
171 dst.append(output); 199 dst.append(output);
172 return dst; 200 return dst;
@@ -204,7 +232,10 @@ protected: @@ -204,7 +232,10 @@ protected:
204 AVCodec *avCodec; 232 AVCodec *avCodec;
205 AVFrame *frame; 233 AVFrame *frame;
206 AVFrame *cvt_frame; 234 AVFrame *cvt_frame;
  235 + AVPacket packet;
207 uint8_t *buffer; 236 uint8_t *buffer;
  237 +
  238 + int64_t idxOffset;
208 bool opened; 239 bool opened;
209 int streamID; 240 int streamID;
210 float fps; 241 float fps;