DeaDBeeF-Player / deadbeef

DeaDBeeF Player
https://deadbeef.sourceforge.io/
Other
1.6k stars 175 forks source link

configure misbehaves under msys+mingw #1587

Closed eblanca closed 8 years ago

eblanca commented 8 years ago

I'm running the configure script shipped with deadbeef-0.7.2 in a windows environment, under msys-1 and mingw32, with gcc-4.9.3 and binutils-2.25.1. Well, the issue is the script skips some checks when activating the --enable-staticlink option, and now the just created Makefiles expect some libraries I actually do not have installed. Let me show:

$ ./configure --disable-gtk3 --disable-vtx --disable-gme --disable-sid --disable-adplug --disable-wildmidi --disable-tta --disable-mms --disable-psf --disable-dumb --disable-shn --disable-sc68 --disable-dca --disable-shellexec --disable-ffap --disable-alac --disable-wma --disable-nls --disable-converter (this is a basic configure with minimal optional components for deadbeef) [...] Plugin Summary:

stdio: yes - Standard IO plugin
gme: no - chiptune music player based on GME
nullout: yes - NULL output
alsa: no - ALSA output
oss: no - oss output plugin
pulse: no - PulseAudio output plugin
coreaudio: no - CoreAudio output plugin
sid: no - SID player based on libsidplay2
ffap: no - Monkey's audio (APE) decoder
lastfm: no - last.fm scrobbler
mp3: yes - mp3 plugin
    libmad: yes - libmad backend for mp3 plugin
    libmpg123: no - libmpg123 backend for mp3 plugin
vorbis: yes - ogg vorbis player
flac: no - flac player
wavpack: no - wavpack player
sndfile: no - PCM (wav,aiff,etc) player based on libsndfile
vtx: no - vtx file player (ay8910/12 emulation)
adplug: no - adplug player (OPL2/OPL3 emulation)
vfs_curl: no - http/ftp streaming support
cdda: no - cd audio player
gtkui: yes - GTK2 user interface
gtkui3: no - GTK3 user interface
hotkeys: no - Local and global hotkeys support
ffmpeg: no - ffmpeg codecs
artwork: no - Cover art plugin
supereq: yes - Equalizer based on Super EQ library by Naoki Shibata
notify: no - notification-daemon support plugin
shellexec: no - shell commands plugin
shellexecui: no - GTK user interface for setting up shellexec plugin
musepack: yes - musepack player plugin
wildmidi: no - WildMidi player plugin
tta: no - TTA player plugin
dca: no - libdca (DTS Audio) player plugin
aac: no - AAC player (m4a, aac, mp4) based on FAAD2
mms: no - mms streaming support
dsp_src: no - High quality samplerate conversion using libsamplerate
m3u: yes - M3U and PLS playlist support
vfs_zip: no - zip archive support
converter: no - plugin for converting files to any formats
psf: no - PSF format plugin, using AOSDK
dumb: no - DUMB module plugin, for MOD, S3M, etc
shn: no - SHN plugin based on xmms-shn
mono2stereo: yes - mono2stereo DSP plugin
alac: no - ALAC plugin
wma: no - WMA plugin
pltbrowser: yes - playlist browser gui plugin
sc68: no - sc68 Atari ST And Amiga player

$ ./configure --disable-gtk3 --disable-vtx --disable-gme --disable-sid --disable-adplug --disable-wildmidi --disable-tta --disable-mms --disable-psf --disable-dumb --disable-shn --disable-sc68 --disable-dca --disable-shellexec --disable-ffap --disable-alac --disable-wma --disable-nls --disable-converter --enable-staticlink (the same configure settings with staticlink set)

Plugin Summary:

stdio: yes - Standard IO plugin
gme: no - chiptune music player based on GME
nullout: yes - NULL output
alsa: yes - ALSA output
oss: no - oss output plugin
pulse: yes - PulseAudio output plugin
coreaudio: no - CoreAudio output plugin
sid: no - SID player based on libsidplay2
ffap: no - Monkey's audio (APE) decoder
lastfm: yes - last.fm scrobbler
mp3: yes - mp3 plugin
    libmad: yes - libmad backend for mp3 plugin
    libmpg123: yes - libmpg123 backend for mp3 plugin
vorbis: yes - ogg vorbis player
flac: yes - flac player
wavpack: yes - wavpack player
sndfile: yes - PCM (wav,aiff,etc) player based on libsndfile
vtx: no - vtx file player (ay8910/12 emulation)
adplug: no - adplug player (OPL2/OPL3 emulation)
vfs_curl: yes - http/ftp streaming support
cdda: yes - cd audio player
gtkui: yes - GTK2 user interface
gtkui3: no - GTK3 user interface
hotkeys: yes - Local and global hotkeys support
ffmpeg: yes - ffmpeg codecs
artwork: yes - Cover art plugin
supereq: yes - Equalizer based on Super EQ library by Naoki Shibata
notify: yes - notification-daemon support plugin
shellexec: no - shell commands plugin
shellexecui: no - GTK user interface for setting up shellexec plugin
musepack: yes - musepack player plugin
wildmidi: no - WildMidi player plugin
tta: no - TTA player plugin
dca: no - libdca (DTS Audio) player plugin
aac: yes - AAC player (m4a, aac, mp4) based on FAAD2
mms: no - mms streaming support
dsp_src: yes - High quality samplerate conversion using libsamplerate
m3u: yes - M3U and PLS playlist support
vfs_zip: yes - zip archive support
converter: no - plugin for converting files to any formats
psf: no - PSF format plugin, using AOSDK
dumb: no - DUMB module plugin, for MOD, S3M, etc
shn: no - SHN plugin based on xmms-shn
mono2stereo: yes - mono2stereo DSP plugin
alac: no - ALAC plugin
wma: no - WMA plugin
pltbrowser: yes - playlist browser gui plugin
sc68: no - sc68 Atari ST And Amiga player

Please note, in addition, the appearing libmpg123 which I cannot turn off, even when I set the --disable-libmpg123 option.

If I run make, then the build stops very soon with an error because every Makefile is now filled with many USE_LIBSOMETHING macros referring to a non-existent library. I really don't know how to fix this, can you help me?

eblanca commented 8 years ago

Further, if I don't use the --enable-staticlink option, deadbeef builds (I added many fixes in order to achieve this) but the executable does just nothing perhaps because it fails when trying to enumerate plugins. That's why I'm trying to build everything as static.

Oleksiy-Yakovenko commented 8 years ago

Well, the issue is the script skips some checks when activating the --enable-staticlink option, and now the just created Makefiles expect some libraries I actually do not have installed.

This is not a bug. This is by design. The --enable-staticlink option expects you to have those libraries precompiled, and placed in the folder "static-deps".

This feature is only implemented for Linux, and won't work on any other target (not just windows, but neither mac, or *bsd, etc)

The static-deps for linux i686 and x86_64 can be downloaded here: http://sourceforge.net/projects/deadbeef/files/staticdeps/ddb-static-deps-latest.tar.bz2/download

You can see how to download & unpack them e.g. here: https://github.com/Alexey-Yakovenko/deadbeef/blob/master/travis/build.sh

Oleksiy-Yakovenko commented 8 years ago

Further, if I don't use the --enable-staticlink option, deadbeef builds (I added many fixes in order to achieve this) but the executable does just nothing perhaps because it fails when trying to enumerate plugins. That's why I'm trying to build everything as static.

At the very minimum, it should print some text to the console. The console output is supposed to help you to find out what's not working.

Oleksiy-Yakovenko commented 8 years ago

I really don't know how to fix this, can you help me?

you'd need to compile all of the required libraries in the same prefix, place them in e.g. deadbeef/static-deps/win32 folder, and add windows target support so that makefiles can find the libraries.

so instead of this block:

  i386-*-* | i486-*-* | i586-*-* | i686-*-* | i86pc-*-*)
    AC_DEFINE(ARCH_X86_32, 1, [architecture is x86])
    LIB="static-deps/lib-x86-32"
    YASM_FLAGS="-f elf -D ARCH_X86_32 -m x86"
    APE_USE_YASM=yes
    ;;
  x86_64-*-* | amd64-*-*)
    AC_DEFINE(ARCH_X86_64, 1, [architecture is x86_64])
    LIB="static-deps/lib-x86-64"
    YASM_FLAGS="-f elf -D ARCH_X86_64 -m amd64"
    APE_USE_YASM=yes
    ;;

you'd need to be more explicit (something like x86_64-linux-* etc), and add new block for Windows.

Oleksiy-Yakovenko commented 8 years ago

It might be much easier and more reliable on Windows to create a Visual Studio project with all necessary libraries, and deadbeef source code, and use this instead of Autotools.

I did this on OSX + Xcode, and it works very well.

I heard that the latest VS already supports CLang as compiler (this is critical, because Deadbeef is using C99), and VS Community is free.

Oleksiy-Yakovenko commented 8 years ago

I hope I answered all of your questions, and I'm closing the issue. But feel free to post any further questions here.

eblanca commented 8 years ago

Finally, I stayed on the primary plan to achieve a "classic"build and avoid to link everything statically (with mingw). Well, it was a long work and it required tricks and accuracy but... now deadbeef is running into my virtualboxed windows xp! Goin' for some tests, stay tuned for updates...

Oleksiy-Yakovenko commented 8 years ago

Wow! that's an achievement! what are you using for sound output?

eblanca commented 8 years ago

Actually, audio output wasn't an issue at all, and the only output plugin is now the "nullout". My only target was getting the whole application to build and run, and it all was achieved. Further work has yet to be done, in order to get the same amount of features deadbeef has in linux fully available on the MS platform too. Now deadbeef runs, I can safely close the application, but preferences don't get saved. Mp3 files can be loaded, I can even see their properties. No play, if I press the Play button the application freezes someway. I can also load an mp3 file with its cue sheet and see the playlist nicely populated! Ogg vorbis files cannot load, and I expected they could. I specifically built the vorbis plugin and the liboggedit plugin, but when I select a vorbis file to load, something fast appears and disappears, but no new entry gets added to the playlist. Every hard-coded path has to be reviewed (and fixed) because the plugins are now in an uncomfortable directory and the config file is saved in a wrong place (is it saved? not sure...). Anyway, a basic deadbeef is running, and from now on things can only go better than this :-)

Oleksiy-Yakovenko commented 8 years ago

Congratulations with getting to this milestone! 👍 Not that I have any use for deadbeef on windows, since there's foobar2000, but I heard some people want it.

eblanca commented 8 years ago

I am one of those! I used to play my music (in windows environment) using fb2k but I like deadbeef much much more because it's free software! So I wanted in any possible way to replace the closed source fb2k with yours.

eblanca commented 8 years ago

About the audio output, none of the current output plugins support windows (maybe pulse?) but my idea is not to write an on-purpose plugin for windows. Instead, I think it could be easy to build a new plugin based upon the xiph's libao, which officially supports windows and it's a reliable starting point.

Oleksiy-Yakovenko commented 8 years ago

In my opinion, it should be significantly easier to build a plugin for one of the win32 native audio systems, and get more features, and less problems. Especially when you get to the multichannel output problems, etc.

BTW, not sure if this is useful, but it should be possible to dig out the SDL plugin sources from git history.. It existed before deadbeef got plugins, but it would be at least a starting point, and SDL supports windows too.

Have a look: https://github.com/Alexey-Yakovenko/deadbeef/blob/8e2e95f37a8509c7cbc7b85a61ab7b53f9d7b9d3/psdl.c

eblanca commented 8 years ago

My personal choice would go to a multi-platform audio library (ao or sdl or whatever) rather than a native audio library because the "official" validation could be done on another supported platform (i.e. linux). Then, after everything works* for sure, I would evaluate a porting to windows.

*"works" means that the communication plugin -> audio_subsystem is implemented and it works as expected.

Oleksiy-Yakovenko commented 8 years ago

This may sound like a good idea when you want to develop & test on linux, but run on windows..

But I'm not accepting pull requests adding new audio plugins, which work on Linux, even if their main purpose is supporting Windows, and I'll explain why.

The Linux users will start using them, instead of the 2 already provided output plugins (alsa + pulse), and will start sending the bug / support requests to me.

This is a general rule: don't duplicate features, unless you have to.

Another thing is that deadbeef is not trying to be "cross-platform" in the most popular sense.

It's attempting to be native on all platforms.

This is why it's using Cocoa and CoreAudio on OSX, instead of GTK & SDL.

This is the only way to deliver the native and reach experience to the end users.

That being said, it doesn't mean of course, that you can't use AO or SDL, or whatever you want. It just means that you will have to maintain your fork on your own.

eblanca commented 8 years ago

I'm playin' a bit with nullout plugin. (configuration issues now seem to be fixed, as well as playlist saving) Now, I need to fix a strange behaviour. When I press "Play" on an mp3 file, it doesn't play. Well, you may say, I'm using a null output plugin, and I know, but the strange thing is the time indicator on the status bar never changes! It always stays at 0:00. The file is read indeed, and I can see it is a 128 kbps mp3 file and also the total duration, but it seems the decoding is not working. Also, the color seek bar never gets filled. I enabled (many) trace messages into "cmp3_scan_stream" and here's what I can see:

cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
mp3: skipping 10240(2800H) bytes of junk
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample -1 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: setting startoffset to 10240
mp3 totalsamples: 12778607 (12779136, 529, 0 | 529 12779135)
mp3: seeking to 10240(0H) start offset
cmp3_scan_stream: ***************************************************
cmp3_scan_stream: sample 529 (offs: 10240)
cmp3_scan_stream: initpos 10240
cmp3_scan_stream: cursample=529, frame: 0, skipsamples: 529, filepos: 2800, lead-in frames: 0
seeked to 529
mp3: startsample: 529, endsample: 12779135, currentsample: 529
mp3 format: bps:16 sr:44100 channels:2
quitting gtk
gtkui_stop completed
gui plugin has quit; waiting for mainloop thread to finish
plug_disconnect_all
plug_unload_all
stopping GTK2 user interface...
quitting gtk
stopping Null output plugin...
stopping OggVorbis decoder...
stopped all plugins
all plugins had been unloaded
messagepump_free
plug_cleanup
hej-hej!

(the asterixed bar means the function begins) It seems cmp3_scan_stream is only called with parameter -1 (scan entire stream) and 529 (which should be a seek request) but this same operation is requested many times. May this be related to the fake mpeg playing? Do you have any suggestion about this?

Oleksiy-Yakovenko commented 8 years ago

I suggest running deadbeef in debugger, and seeing what happens. I think the streamer is attempting to initialize the mp3 decoding, fails, then tries again, and so on.

You should also try uncommenting trace macro in the streamer.c, this way you'll get lots of information about what's happening.

Oleksiy-Yakovenko commented 8 years ago

I suspect, that you had to modify the vfs_stdio to make it work on windows. It is very likely, that it's not working correctly anymore, so mp3 decoder is not getting the correct data.

eblanca commented 8 years ago

Thank you, I'll have a look at that.

eblanca commented 8 years ago

You were right, it was there! I took some macro from another project of mine, enabled USE_STDIO and now the whole module works! Not only the mp3 reading works, now the ogg vorbis file works too!

eblanca commented 8 years ago

I need some deeper detail about the streamer module. I decided to put into null output plugin a dummy wait in a statement like this: usleep((1000000/(plugin.fmt.samplerate*plugin.fmt.channels*(plugin.fmt.bps/8)))*AUDIO_BUFFER_SIZE); in order to see duration grow in a 'real' time into the statusbar. The 'pnull_callback' function calls a read deadbeef->streamer_read (stream, len); always using the same 'len' parameter (it refers to a fixed size buffer). Now, when playing a 32 bps track (the vorbis track) instead of a 16 bps track (the mp3 file) the duration into the statusbar grows two times faster! Well, I'm quite sure the wait formula is right, so there must be something else which wrongly counts how many times the plugin calls the streamer to fill its buffer! It is obvious that a 32 bps track needs two times the callings to fill the buffer with respect to a 16 bps track. But why does duration grow according to these doubled calls? This absolutely is not clear to me.

Oleksiy-Yakovenko commented 8 years ago

The current playback position is determined by the current read pointer, which is updated in the streamer_read.

You would need to put a wait just after calling streamer_read, and wait for exactly the amount of time, that would take to play back the data you fetched, in real time.

Oleksiy-Yakovenko commented 8 years ago

It is obvious that a 32 bps track needs two times the callings

No, because nullout is always set to 44100/16/stereo -- the streamer will always give it 44100/16/stereo.

The above is wrong, corrected below.

Oleksiy-Yakovenko commented 8 years ago

It would make a lot of sense if you put your code on github. It's nearly impossible to guess what you're doing, and why it isn't working the way you expect.

Oleksiy-Yakovenko commented 8 years ago

@eblanca Ah wait.. I was wrong. nullout isn't always using 44100/16/stereo. It's setting whatever format was passed to pnull_setformat.

eblanca commented 8 years ago

I forked the whole deadbeef master branch, and I just completed the updates. In the next days I will investigate the root of the time acceleration during vorbis playback.

eblanca commented 8 years ago

There is a point I see in both audio output plugins (alsa and pulse). In their main threads there is a char buffer (char buf[]) which varies its size according to the current sample size (channels and bps) and this buffer is then used for streamer reads. This is a noticeable difference with respect to my wait implementation into the null output plugins, since my calls to the streamer read are always with a fized size, and not tied to the current sample size. Nevertheless, I cannot see why this makes a timing difference.

Oleksiy-Yakovenko commented 8 years ago

@eblanca have you tried running in debugger and looking where the calculations go wrong?

eblanca commented 8 years ago

I fixed the null output dummy wait using a float variable for calculations. There was approximation caused by integer only calculations which brought too much oscillation and caused noticeable error. Anyway, I did some mistakes into my deadbeef repository and I finally deleted it. I'll restore it again including my latest modifications.

eblanca commented 8 years ago

I finally uploaded my modified source code on github ( https://github.com/eblanca/deadbeef-0.7.2 ), and I keep workin' on it. I decided at last for a native output plugin based on the waveout interface (source into plugins/waveout/), so it will only be available in windows xp and newer systems (and wine too, eh eh). It is still at an early stage, it produces some sounds but needs some more work. My approach is to add fixes bounded into prepocessor macros (#ifdef / #ifndef) and left the most part unchanged, in fact my "patched" deadbeef-0.7.2 is still buildable (and it works) in a *nix system as it always did.

Oleksiy-Yakovenko commented 8 years ago

@eblanca what you should do next is take a fresh git clone of deadbeef, and apply all of your changes to it, so that there's history.

This would be useful because right now it's not possible to see what's changed compared to the upstream version, and not possible to pick/merge/PR anything.

I also noticed that you used 0.7.2 snapshot, which is weird, because master branch is evolving very quickly, and has a ton of changes, so it would be even harder to merge anything. Unless you only changed small things, but even then it would be hard.

I think you should be using master branch instead.

eblanca commented 8 years ago

Yes, I chose the 0.7.2 branch on purpose, so I can work on my patches without being concerned about changes that may break something (under windows, I mean) in other areas, whereas the "old" branch stays freezed and stable. But a time will come when I'll apply patches on the master branch, when the output plugin will be in a reliable state (and I feel more confident with git too).

Oleksiy-Yakovenko commented 8 years ago

@eblanca

Master branch is relatively stable (I'm using builds from master as my main player). You can always "freeze" your version at certain commit.

Basically, you're working on your own branch anyway, and don't need to pull from upstream all the time.