summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2020-07-15*: bump to 0.4.20.4.2Vito Caputo
The AV-sync rework is significant enough for a release
2020-07-15get_frame: refresh capture_frameno post acquireVito Caputo
Acquiring the new frame can take a potentially significant amount of time, rather than letting any frames dropped during the acquire get all taken by the next frame, update this one to include them. It's both more accurate (the dropped frames occurred literally while this was going on) and makes it more likely get_frame() will have to wait on the upcoming cond_wait(time_cond) for the next tick. If the upcoming cond_wait(time_cond) doesn't wait because a new frame is already pending, it makes it more likely get_frame() will snatch yuv_mutex before the encode/cache thread can wake up and grab it. When that occurs it's effectively dropping frames because the encode/cache thread gets blocked on yuv_mutex while the contents get replaced, so the frames the previous contents were going to be applied to will instead get the updated contents that belong to the future sample's frames.
2020-07-15timer: maintain video side of avd in frame timerVito Caputo
Since the frame timer implements a frame counter, and that frame count is propagated through the get->encode pipeline for samples that get through, any missed frames are noticed and dealt with making it not lossy from the point of the timer down to the encoded stream in terms of number of frames. It's certainly lossy in terms of the contents of those frames, but synchronization is all about the temporal domain and as long as the frame counts all make it into the stream as frames, we can account for them at the timer in terms of avd. This in combination with the other commit moving the audio side of avd maintenance immediately upon capture into the raw buffer, shrinks the variable capacitance separating the audio timer and the frame timer to virtually nil. As a consequence, the frame timer can now be much more accurate in terms of how much longer/less to sleep or if a frame should be dropped to get the timer caught up. When avd was being maintained at points far removed from the actual things they represented there was too much elastic capacitance in there for sync_streams() to inform its adjustment accurately.
2020-07-15sound: move avd maintenance to point of captureVito Caputo
Since the sound capture buffers all sound in newly allocated memory, the "stream time" represented by those buffers can be accounted for immediately upon reading into the buffer. Doing it later in the different threads on the other side of the queue, especially after encoding, is an unnecessary pile of variable capacitance that just makes things less synchronized for zero gain.
2020-07-14timer: don't advance time_frameno when pausedVito Caputo
This requires a bit of adjustment in the get_frame time_cond wait loop so it still services the event loop when woken without advance At least now get_frame has no explicit pause code, but it does require the timer keep firing while paused so it signals time_cond.
2020-07-14*: get rid of unused frames_{total,lost}Vito Caputo
these concepts may return but not in this form
2020-07-14*: rework avd/frameno handling for cached modeVito Caputo
This brings the !--on-the-fly-encoding mode up to speed. The cached file header loses the total_frames counter, as the capture_frameno already represents this. Dropped frames are detected by simply looking at the difference between the previous capture_frameno and the current one. This simply gets passed to the encoder as a n_frames count so theora can duplicate the frames as needed. This was being done manually before by looking at the frameno and total frames in each header and maintaining separate counts for "extra frames" "missed frames" etc, and resubmitting entire frames multiply for encoding dropped frames. So a chunk of code has been thrown out from rmd_load_cache.c, and some general cleanups have occurred there as well. I also needed to add more locking around pdata->avd accesses.
2020-07-14timer: implement AV-syncVito Caputo
This is focused on keeping --on-the-fly-encoding in sync even over long videos. The existing code inevitably would fall into a permanently negative pdata->avd value letting things get increasingly out of sync and never correcting. Before removing the vestigial negative avd "don't wait" logic from get_frame when this permanently negative avd state was entered, get_frame would just start sampling at an unregulated fps. The timer thread which drives get_frame now consults avd on every tick, Depending on which which half is ahead, the timer will either cause get_frame to drop frames by advancing the frameno by more than one, or it will adjust its sleep delay in proportion to the delta. See comments in rmd_timer.c for more details. Note that in testing especially with a loaded system I observed some surprisingly large deltas where multi-second sleeps occurred to let the sound catch back up. I expect to revisit this issue more in the future, but would just like to get things more correct for now.
2020-07-14encode_image_buffer: duplicate missed framesVito Caputo
When the encoder finds the encoded - captured frameno delta > 1 it needs to fill the gap somehow. With how things are currently architected, the old yuv countents are gone so there's only the current frame available for filling. The newer theoraenc.h API exposes a theora_control() parameter for this purpose, so I've also added a theoraenc.h include implicitly bumping the libtheora dependency. But by now it shouldn't matter, and the rest of rmd should probably get updated to use the new theora API eventually anyways. I'm still uncertain what role pdata->avd will play in the long-run, but leaving its maintenance for now.
2020-07-14types: add avd_mutex to ProgDataVito Caputo
avd accesses aren't serialized currently despite occurring from concurrent threads. I'm reworking avd but this just introduces and initializes a mutex for the existing variable.
2020-07-14get_frame: s/cond_broadcast/cond_signal/Vito Caputo
Vestigial broadcast, only a single waiter on this now.
2020-07-14get_frame: don't let avd influence frame samplingVito Caputo
Maybe this made sense at some point in the original code, but the way I have this setup currently get_frame() should strictly capture a frame on every tick of the timer at the desired FPS to the best of its ability. The capture_frameno gets propagated to the encoder whenever a new frame is acquired on that timer. When the encoder consumes it, it should just dupe the frame to fill any gaps between the last encoded frameno and the new one. As-is, this avd value seems to drift permanently negative eventually at which point get_frame() ceases ever waiting on the timer. That's obviously broken, and devolves into a pinned CPU with get_frame() attempting an infinitely high frame rate. Which likely just makes things worse not better by starving the encoder of CPU time. I need to go check out the encoder now to make sure it fills frameno gaps.
2020-07-13*: more rmdThreadsSetName() callersVito Caputo
Name the timer and sound capture threads as well, and fixup the rmd{Encode,Cache}Sounds names -> rmd{Encode,Cache}Sound
2020-07-12flush_to_ogg: use enum for audio_or_videoVito Caputo
Nothing changed, just syntactic sugar to make this more readable
2020-07-12*: bump to 0.4.10.4.1Vito Caputo
Quick minor release primarily for the paused CPU burning fix
2020-07-12*: standardize sleeps on nanosleep()Vito Caputo
usleep() is deprecated by posix in favor of nanosleep(), nanosleep doesn't dick with signals so it's generally better anyways.
2020-07-12get_frame: insert brief sleep when pausedVito Caputo
rmdGetFrame() can't just block on pause_cond because it services the event loop, which may be the very thing responsible for unpausing when not triggered by an external signal. The existing code handles this correctly but it spins on polling the paused flag and running the event loop when paused. This commit just adds a short delay to that cycle so the rmdGetFrame thread doesn't pointlessly burn CPU while paused.
2020-07-12threads: introduce and use rmdThreadsSetName()Vito Caputo
Now users can easily differentiate which rmd subtasks are busy by using top-like tools in show-threads mode. Also aids in troubleshooting...
2020-07-11*: bump to 0.4.00.4.0Vito Caputo
Formally making first release since forking, I'm sure there are bugs but I doubt anyone will be inclined to help test any of this if there's nothing at least stating it's a newer version and some mention of the user-visible changes.
2020-07-11*: update AUTHORS and READMEVito Caputo
Just some quick modifications to reflect the forked status
2020-07-11*: drop {gtk,qt}-recordmydesktop subdirsVito Caputo
This restores the recordmydesktop/ subdir as root from the mirror I cloned by fork from. I have no particular interest in the gtk/qt frontends and it doesn't appear they were part of a single tree in the past. But I will probably preserve backwards compatibility of the cli so they can continue to work with this fork installed.
2020-07-11*: get libjack synchronization on the same pageVito Caputo
This isn't tested as I don't currently have a JACK setup, but it at least compiles and looks semi sane.
2020-07-11*: more formatting cleanupsVito Caputo
Nothing functionally changed
2020-07-11encode_sound_buffer: more formatting cleanupsVito Caputo
Nothing functionally changed
2020-07-11shortcuts: formatting cleanupsVito Caputo
Nothing significant changed
2020-07-11TODO: add entries for ogv playback/decode errorsVito Caputo
This may just be ffmpeg ogg decoding bugs, but it requires investigation to confirm. The playback does show corruption in mpv/vlc in my testing, but that problem existed pre-fork as well.
2020-07-11setbrwindow: formatting cleanupsVito Caputo
Nothing significant changed
2020-07-11*: no more enc_data->[xy]_offsetVito Caputo
With no rrect alignment adjustment happening, there's no need for this fuckery anymore. The theora encoding offsets will always be left at 0, the frame_{width, height} will clip to rrect.{width,height}, and the yuv buffer dimensions are the only thing 16x16 aligned.
2020-07-11setbrwindow: stop adjusting rrect for alignmentVito Caputo
rrect of any size/place should be perfectly usable now
2020-07-11*: more unfucking synchronizationVito Caputo
2020-07-11get_frame: more unfucking synchronizatoinVito Caputo
2020-07-11get_frame: s/blocknum_[xy]/blocks_[wh]/Vito Caputo
Minor cleanup
2020-07-11make_dummy_pointer: more formatting cleanupsVito Caputo
Nothing functionally changed
2020-07-11rescue: more formatting cleanupsVito Caputo
nothing functionally changed
2020-07-11cache: more formatting cleanupsVito Caputo
nothing functional changed
2020-07-11initialize_data: more formatting cleanupsVito Caputo
Nothing functionally changed
2020-07-11rectinsert: stop aligning rects on insert hereVito Caputo
Assume rects that come in for insertion are already as aligned as possible within the rrect bounds. If the rrect has odd dimensions, then there's potential for edge case odd rects too - but the only even-sensitive code is the YUV updating and that's been amended to at least ignore those edge cases gracefully. Also constify the supplied xrect while in here.
2020-07-11poll_events: align rectangles to even boundariesVito Caputo
The current rectinsert code does this, but it does it in the absolute root window coordinate space. In preparation for dropping all the alignment stuff out of rectinsert, do the alignment at the rectinsert caller and do it in the rrect-relative coordinate space.
2020-07-11get_frame: consolidate [yuv]blocks reset as a funcVito Caputo
Eliminate some pointless duplication
2020-07-11update_image: add some asserts on clipped rectVito Caputo
Just some sanity checks to ensure clipping is working properly
2020-07-11capture_sound: simplify locking and buffer acquisitionVito Caputo
More tidying of things
2020-07-11get_frame: perform shmctl(IPC_RMID) after shmat()Vito Caputo
No need to duplicate this down at the teardown, it won't go away with outstanding references so you can basically queue the rm.
2020-07-11*: introduce Image typeVito Caputo
Baby step towards encapsulating the shmem and ximage state
2020-07-11cache_frame: calculate size from yuv dimensionsVito Caputo
More preparation for yuv and rrect dimensions differing
2020-07-11*: more random minor cleanupsVito Caputo
Nothing significant
2020-07-11*: more random cleanupsVito Caputo
minor formatting/whitespace changes
2020-07-11yuv_utils: shrink [yuv]blocks to unsigned char[]Vito Caputo
No idea why this had such a large type, its members just hold 0 or 1.
2020-07-11yuv_utils: gracefully ignore odd pixels for UVVito Caputo
This is temporary, in preparation for potentially odd-dimensioned image buffers. For now I'll just skip the last row / column in the UV update for such odd dimensions. In the future there could be a read-modify-write dance for handling the last row/column or something like that.
2020-07-11yuv_utils: fixup dirty blocknum() parametersVito Caputo
This needs to maintain dirty blocks in the yuv frame coordinates, not in the captured image's cooridinates. The existing code assumes those are the same in double-buffer mode where the dirty block tracking is applied. But I'm working towards allowing the captured image dimensions to be free from the 16x16 alignment constraints the yuv buffers must conform to for theora. To handle that future, the block coordinates should at least use the (yuv)->y_width, not width_tm. I also added shifting the x,y but in double-buffer mode that shouldn't actually be needed since it'd always be full-shots unless I'm mistaken.
2020-07-11yuv_utils: more cleanups focusing on the macrosVito Caputo
Nothing really changed here, just rearranging some stuff and replacing some divides with shifts.
© All Rights Reserved