+
+void PBOFrameAllocator::reconfigure(bmusb::PixelFormat pixel_format,
+ size_t frame_size,
+ GLuint width, GLuint height,
+ unsigned card_index,
+ MJPEGEncoder *mjpeg_encoder,
+ size_t num_queued_frames,
+ GLenum buffer,
+ GLenum permissions,
+ GLenum map_bits)
+{
+ if (pixel_format == this->pixel_format &&
+ frame_size == this->frame_size &&
+ width == this->width && height == this->height &&
+ card_index == this->card_index &&
+ mjpeg_encoder == this->mjpeg_encoder &&
+ num_queued_frames == this->num_queued_frames &&
+ buffer == this->buffer &&
+ permissions == this->permissions &&
+ map_bits == this->map_bits) {
+ return;
+ }
+
+ lock_guard<mutex> lock(freelist_mutex);
+ lingering_generations[generation] = LingeringGeneration{ move(userdata), this->num_queued_frames };
+ ++generation;
+
+ while (!freelist.empty()) {
+ Frame frame = freelist.front();
+ freelist.pop();
+ destroy_frame(&frame);
+ }
+
+ this->pixel_format = pixel_format;
+ this->frame_size = frame_size;
+ this->width = width;
+ this->height = height;
+ this->card_index = card_index;
+ this->mjpeg_encoder = mjpeg_encoder;
+ this->num_queued_frames = num_queued_frames;
+ this->buffer = buffer;
+ this->permissions = permissions;
+ this->map_bits = map_bits;
+
+ userdata.reset(new Userdata[num_queued_frames]);
+ for (size_t i = 0; i < num_queued_frames; ++i) {
+ init_frame(i, frame_size, width, height, permissions, map_bits, generation);
+ }
+
+ // There may still be frames out with the old configuration
+ // (for instance, living in GLWidget); they will be destroyed
+ // when they come back in release_frame().
+}