Guest - Testers are needed for the reworked CDateTime core component. See... https://forum.kodi.tv/showthread.php?tid=378981 (September 29) x
  • 1
  • 6
  • 7
  • 8(current)
  • 9
  • 10
  • 23
Comskip for Linux released
FYI - looks like comskip (the kaashoek version as well, not just this port) chokes on Handbrake files which have been encoded via x264 with a variable frame rate - which is Handbrake's default.

If you're comskipping on the source before re-encoding (e.g. if you're working on an H.264 HD recording), you're fine, although you're obviously trusting Handbrake to keep the same timings afterwards; if you're encoding first (e.g. to correct TS errors, or to shrink the file) and thus working off an H.264 encoded version, you'll need to use constant frame rate, otherwise comskip will shoot itself (the malloc in initComSkip simply can't grab enough RAM, unless you have terabytes of the stuff).

From what I can work out, comskip detects the VFR as a frame rate of 90000fps (peak frame rate? Theoretical maximum? Derived from the MPEG timebase?), and then promptly fails to allocate enough memory (not surprising if you remember that 90k fps is 3600x a normal PAL frame rate, so needs 3600x the memory).

Interestingly, mkvinfo, VLC, SMplayer, ffplay and XBMC itself will all tell you that the encoded file is the correct frame rate, so it's something about how comskip (and a few other programs, e.g. tsmuxer) work out the frame rate.

I'm no C/C++ expert, but I think the issue arises in inputReffer in comskip.cpp, but I'll confess to not having fully dissected the code.
Reply
(2013-01-27, 01:37)Prof Yaffle Wrote: FYI - looks like comskip (the kaashoek version as well, not just this port) chokes on Handbrake files which have been encoded via x264 with a variable frame rate - which is Handbrake's default.

If you're comskipping on the source before re-encoding (e.g. if you're working on an H.264 HD recording), you're fine, although you're obviously trusting Handbrake to keep the same timings afterwards; if you're encoding first (e.g. to correct TS errors, or to shrink the file) and thus working off an H.264 encoded version, you'll need to use constant frame rate, otherwise comskip will shoot itself (the malloc in initComSkip simply can't grab enough RAM, unless you have terabytes of the stuff).

From what I can work out, comskip detects the VFR as a frame rate of 90000fps (peak frame rate? Theoretical maximum? Derived from the MPEG timebase?), and then promptly fails to allocate enough memory (not surprising if you remember that 90k fps is 3600x a normal PAL frame rate, so needs 3600x the memory).

Interestingly, mkvinfo, VLC, SMplayer, ffplay and XBMC itself will all tell you that the encoded file is the correct frame rate, so it's something about how comskip (and a few other programs, e.g. tsmuxer) work out the frame rate.

I'm no C/C++ expert, but I think the issue arises in inputReffer in comskip.cpp, but I'll confess to not having fully dissected the code.

You're in luck, I've been in the process of improving memory management and it was quite easy to identify the cause of your problem.

Fixed in 0.92o.

Reply
Excellent, thank you - I've tried to test, but I only have HD H.264 recordings at the moment, and life's too short to fully process those on an Atom :-)

FYI, the processed VFR file is now detected as:

Code:
Input #0, matroska,webm, from '/home/xbmc/Network/Videos/Recordings/VFR_test.mkv':
  Duration: 02:44:57.70, start: 0.000000, bitrate: 5187 kb/s
    Stream #0:0(eng): Video: h264 (Main), yuv420p, 1918x1078 [SAR 1:1 DAR 137:77], 25 fps, 25 tbr, 1k tbn, 180k tbc (default)
    Stream #0:1: Audio: ac3, 48000 Hz, stereo, s16, 224 kb/s (default)
    Stream #0:2(eng): Audio: ac3, 48000 Hz, stereo, s16, 224 kb/s
Frame Rate set to 90000.000 f/s
Format changed to [1918 : 1078]
Frame: 1        Ratio: 1.80     MinY: 1 MaxY: 1078 MinX: 1 MaxX: 1918

... so the 90k framerate is still there, but comskip seems to then proceed without the memory failure due to your memory management changes.

As an aside, though, pointing this version at a couple of H.264 HD .ts files from last night is causing a segfault. STDOUT and STDERR here. Interestingly, while VLC tells me that this is a 50fps sample, comskip (ffmpeg) is detecting it initially as 63.61fps:

Code:
Input #0, mpegts, from '/home/xbmc/Network/Videos/Recordings/The-Hurt-Locker.2013-01-26.22-00.ts':
  Duration: 02:43:59.74, start: 50938.324733, bitrate: 9600 kb/s
  Program 1
    Stream #0:0[0x901]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 63.61 fps, 50 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x903](nar): Audio: mp2 ([4][0][0][0] / 0x0004), 48000 Hz, stereo, s16, 192 kb/s
    Stream #0:2[0x904](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
    Stream #0:3[0x902](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), s16, 384 kb/s
  No Program
    Stream #0:4[0x905]: Audio: mp1, 0 channels, s16

... before finally deciding it's actually 25fps before shooting itself:

Code:
Frame Rate set to 25.000 f/s
Format changed to [1920 : 1080]
Frame: 1        Ratio: 1.79     MinY: 58 MaxY: 1080 MinX: 106 MaxX: 1920
Frame Rate set to 25.000 f/s
Audio PTS jumped -21 frames at frame 2
Frame Rate set to 25.000 f/s
Frame Rate set to 25.000 f/s
Segmentation fault
Reply
I just put up 0.92p with additional bounds checking and a potential indexing error fix (although I haven't experienced the problem myself).
Reply
Same issue, I'm afraid - still segfaults. Happy to hack the code with printfs or do any debugging if you need me to, it doesn't take long to rebuild and test.

A quick gdb view:

Code:
0:00:00 - 21 frames in 4.09 sec(5.13 fps), 1.06 sec(4.72 fps), 0%
Program received signal SIGSEGV, Segmentation fault.
0x080932af in CS::CommercialSkipper::edgeDetect (this=0xbffff0cc)
    at comskip.cpp:8436
8436                                            if ( TEST_VEDGE0(buf, x, y) )

(gdb) backtrace
#0  0x080932af in CS::CommercialSkipper::edgeDetect (this=0xbffff0cc)
    at comskip.cpp:8436
#1  0x080975b6 in CS::CommercialSkipper::fillLogoBuffer (this=0xbffff0cc)
    at comskip.cpp:8754
#2  0x080a9c13 in CS::CommercialSkipper::detectCommercials (this=0xbffff0cc,
    frameIndex=24, pts=1.8000000000000007) at comskip.cpp:2911
#3  0x0808b575 in (anonymous namespace)::SubmitFrame (is=0xb6fa3020)
    at mpeg2dec.cpp:955
#4  0x08089907 in video_packet_process (packet=0xb6fe9558, is=0xb6fa3020)
    at mpeg2dec.cpp:1294
#5  main (argc=2, argv=0xbffff764) at mpeg2dec.cpp:1982

(gdb) frame 0
#0  0x080932af in CS::CommercialSkipper::edgeDetect (this=0xbffff0cc)
    at comskip.cpp:8436
8436                                            if ( TEST_VEDGE0(buf, x, y) )

(gdb) print buf
$1 = (
    const CS::U8Vec &) @0x906384c: {<std::_Vector_base<unsigned char, std::allocator<unsigned char> >> = {
    _M_impl = {<std::allocator<unsigned char>> = {<__gnu_cxx::new_allocator<unsigned char>> = {<No data fields>}, <No data fields>},
      _M_start = 0xb6bf5008 "\031\031\031\031\032\032\032\032\032\032\032\032\032\031\032\034\035\036\037\036\035\035\036\036\037  !###$$%%$$$$##\"! \037 !\036\035\035\035\034\034\034\034\034\034\034\034\036\036\035\036 !\"\"#$###\"!!\037\037\036\036\036\035\036\036\036\037\037\037\037\036\035\035\035\035\034\034\034\033\034\034\035\035\035\035\035\036\036\036\036\036\037\037\036\036\036\036\037\037\036\036\036\036\037\036\035\036\035\035\034\034\034\033\034\034\034\035\036\036\037\036\037\037\037\037\035\036\037\037\037\036\036\036\036\036\036\036\036\037\037\037 \037\037\037\037\037\037   \037\036\037\037  \037\037\035\036\037   \"\"\"$##\"### \"\037\036\034\033\033"..., _M_finish = 0xb6def408 "",
      _M_end_of_storage = 0xb6def408 ""}}, <No data fields>}
(gdb) print x
$2 = 12
(gdb) print y
$3 = 1062
(gdb)

(PS don't assume I really know what I'm doing :-) )
Reply
I've just put up 0.92q. I'm not able to duplicate the errors that you're having. With that said, the code in question had used macros which are problematic to debug. 0.92q replaces the questionable code with inline template code with pretty thorough bounds checking (which is enabled by default). So give that a try.

Theoretically if you have a bounds error it should throw an exception rather than cause a segfault.

I just had a new though, it's possible that somehow (maybe corrupt video) caused an abnormally small frame to be copied (i'll check tomorrow) in the meantime if you run gdb on it you should be able to "p frame.size()" to show how large the U8Vec is. It should be 1080*1920 for HD video.
Reply
Hi

I have just sucessfully built and installed 0.92q (tho the link to the file still says 0.92p - just changed it to q)

Everything went fine without error, but am now stuck as to what to do next.

There is no folder in /etc called comskip

Also would like to know how I add the script to tvheadend so that it automatically checks all recorded programs.

Thanks
Reply
@diggadave - you can test if it's installed by simply typing 'comskip' (or 'which comskip', if you prefer) - you should have a binary in /usr/bin/comskip and config files in /usr/etc/comskip (on my 'buntu system, anyway). To post-process in tvheadend, look on Configuration -> Digital Video Recorder, "Post-processor command". You can write a script (or plagiarise the one given in the starting post) and then call it as a recording completes, passing the name of the recording and any other parameters via this command entry.

@cbxbiker61 - okay, no frame.size defined in 0.92p, but I'll try 0.92q shortly. I did look at the code and found a couple of likely-looking variables instead, though:

Code:
(gdb) p _height
$6 = 1080
(gdb) p _width
$7 = 1952

... slightly narrow (no idea why, but within limits of what I'd guess you're allocating, since it's smaller). VLC identifies it as 1920x1080 @ 50fps.

Let me look at 0.92q now.
Reply
0.92q segfaults as well, but a different place...

Code:
0:00:00 - 23 frames in 4.33 sec(5.31 fps), 1.01 sec(4.95 fps), 0%
Program received signal SIGSEGV, Segmentation fault.
0x080935ef in testVer0<std::vector<unsigned char> > (f=..., width=1952,
    y=1062, x=<optimized out>, this=<optimized out>) at CsEdges.h:65
65                              || (std::abs(f[yPlus * width + x] - f[y * width + x]) >= _threshold);
(gdb) backtrace
#0  0x080935ef in testVer0<std::vector<unsigned char> > (f=..., width=1952,
    y=1062, x=<optimized out>, this=<optimized out>) at CsEdges.h:65
#1  testVer0 (width=1952, y=1062, x=<optimized out>, f=...,
    this=<optimized out>) at CsEdges.h:70
#2  CS::CommercialSkipper::edgeDetect (this=0xbffff0ac) at comskip.cpp:8371
#3  0x08098416 in CS::CommercialSkipper::fillLogoBuffer (this=0xbffff0ac)
    at comskip.cpp:8699
#4  0x080ab583 in CS::CommercialSkipper::detectCommercials (this=0xbffff0ac,
    frameIndex=24, pts=1.8000000000000007) at comskip.cpp:2874
#5  0x0808b6b5 in (anonymous namespace)::SubmitFrame (is=0xb6fa3020)
    at mpeg2dec.cpp:947
#6  0x08089a33 in video_packet_process (packet=0xb6fe9558, is=0xb6fa3020)
    at mpeg2dec.cpp:1286
#7  main (argc=2, argv=0xbffff764) at mpeg2dec.cpp:1974
(gdb) frame 0
#0  0x080935ef in testVer0<std::vector<unsigned char> > (f=..., width=1952,
    y=1062, x=<optimized out>, this=<optimized out>) at CsEdges.h:65
65                              || (std::abs(f[yPlus * width + x] - f[y * width + x]) >= _threshold);
(gdb) p  frame.size
No symbol "frame" in current context.
(gdb) p x
$1 = <optimized out>
(gdb) p y
$2 = 1062
(gdb) p yPlus
$3 = 1064
(gdb) p width
$4 = 1952
(gdb) p height
No symbol "height" in current context.
(gdb) p f
$5 = (
    const std::vector<unsigned char, std::allocator<unsigned char> > &) @0x906584c: {<std::_Vector_base<unsigned char, std::allocator<unsigned char> >> = {
    _M_impl = {<std::allocator<unsigned char>> = {<__gnu_cxx::new_allocator<unsigned char>> = {<No data fields>}, <No data fields>},
      _M_start = 0xb6bf5008 "\031\031\031\031\032\032\032\032\032\032\032\032\032\031\032\034\035\036\037\036\035\035\036\036\037  !###$$%%$$$$##\"! \037 !\036\035\035\035\034\034\034\034\034\034\034\034\036\036\035\036 !\"\"#$###\"!!\037\037\036\036\036\035\036\036\036\037\037\037\037\036\035\035\035\035\034\034\034\033\034\034\035\035\035\035\035\036\036\036\036\036\037\037\036\036\036\036\037\037\036\036\036\036\037\036\035\036\035\035\034\034\034\033\034\034\034\035\036\036\037\036\037\037\037\037\035\036\037\037\037\036\036\036\036\036\036\036\036\037\037\037 \037\037\037\037\037\037   \037\036\037\037  \037\037\035\036\037   \"\"\"$##\"### \"\037\036\034\033\033"..., _M_finish = 0xb6def408 "",
      _M_end_of_storage = 0xb6def408 ""}}, <No data fields>}
Reply
OK, _width at 1952 is more than 1920, that should be the problem, now I need to look at the code and figure out how it got set to a value greater than the screen width.

For now, you can work around the problem with a more forgiving buffer setting.
Or you could do me a favor and change MAXWIDTH 1920 to MAXWIDTH 1952. I'd really like to figure out what the safest low-end setting is, since there are 50 buffers allocates at MAXWIDTH*MAXHEIGHT. It really makes a difference to the runtime memory requirement.

--- comskip.h.orig 2013-01-28 03:11:04.005242872 -0700
+++ comskip.h 2013-01-28 14:23:15.111397267 -0700
@@ -31,7 +31,7 @@
#include "CcPacket.h"
#include "CsExceptions.h"

-#if 1
+#if 0
#define MAXWIDTH 1920
#define MAXHEIGHT 1080
#else
Reply
Sigh. What kind of an arse am I to claim that 1952 is "slightly narrow" in comparison with 1920... muppet.

MAXWIDTH hard coded to 1952, and there's been no segfault thus far, though after ten minutes of processing it clearly hasn't made much progress on this little system. But it's running.
Reply
0.92r is available with a quick fix for the bounds problem.

I have already started on 0.93 with a much more elegant solution that makes no assumptions on what the max frame sizes are. This means that when processing 720p video comskip will use approximately 1/2 of what it does processing 1080p video. Some of my previous changes had already cut memory use in half, so i'm making real progress.

An interesting note is that 0.93 should be able to handle 4K video as easily as it handles 1080p. I'm sure it will be slower and use 4 times the memory (should work out to about 600M of active ram). It will probably be a long time before we have 4K video with commercials included, but it is nice to have the code sorted out well in advance.
Reply
(2013-01-25, 11:49)cbxbiker61 Wrote:
(2013-01-25, 10:53)Marx1 Wrote: In Debian (experimental) I have (0.92g):
Requested 'libavcodec >= 53.42' but version of libavcodec is 53.35.0
Requested 'libavformat >= 53.24' but version of libavformat is 53.21.1
Requested 'libavutil >= 51.32' but version of libavutil is 51.22.1
I lowered needed version in "configure" and "automake.ac" (no necessary?) in hope it will works anyway, configure finished succesfully, but compiling failed with
missing aclocal-1.13
I have only automake 1.12 available in repository and as I see aclocal is part of it.
Is it really needed to have the newest available software to compile comskip? Can you provide precompiled binary for x86?

Edit: new version, nice Smile

Just change it in configure, if you touch configure.ac it will force a reconfig and that is not necessary. If it works for you, I'll go ahead and change the lowest versions allowed, I'm pretty sure I set it to the versions that ship with ffmpeg 0.9 and I haven't tested it with anything lower (although some people were missing essential functionality in some lower versions).
I've tried 0.92r with lowered versions but no luck. Can somebody provide precompiled binary for i386?

Code:
g++ -DHAVE_CONFIG_H -I.     -g -O2 -std=gnu++11 -MT comskip-LoadSettings.o -MD -MP -MF .deps/comskip-LoadSettings.Tpo -c -o comskip-LoadSettings.o `test -f 'LoadSettings.cpp' || echo './'`LoadSettings.cpp
mv -f .deps/comskip-BlackFrame.Tpo .deps/comskip-BlackFrame.Po
mv -f .deps/comskip-CsEdges.Tpo .deps/comskip-CsEdges.Po
mpeg2dec.cpp: In function ‘bool {anonymous}::video_packet_process({anonymous}::VideoState*, AVPacket*)’:
mpeg2dec.cpp:1189:74: error: ‘avcodec_get_frame_class’ was not declared in this scope
mpeg2dec.cpp:1189:112: error: ‘av_opt_ptr’ was not declared in this scope
mpeg2dec.cpp: In function ‘void {anonymous}::file_close()’:
mpeg2dec.cpp:1623:4: warning: ‘void av_close_input_file(AVFormatContext*)’ is deprecated (declared at /usr/include/libavformat/avformat.h:1580) [-Wdeprecated-declarations]
mpeg2dec.cpp:1623:38: warning: ‘void av_close_input_file(AVFormatContext*)’ is deprecated (declared at /usr/include/libavformat/avformat.h:1580) [-Wdeprecated-declarations]
mv -f .deps/comskip-ProcessArInfo.Tpo .deps/comskip-ProcessArInfo.Po
make[1]: *** [comskip-mpeg2dec.o] Błąd 1
make[1]: *** Oczekiwanie na niezakończone zadania....
mv -f .deps/comskip-ProcessCsv.Tpo .deps/comskip-ProcessCsv.Po
mv -f .deps/comskip-LoadSettings.Tpo .deps/comskip-LoadSettings.Po
mv -f .deps/comskip-comskip.Tpo .deps/comskip-comskip.Po
make[1]: Opuszczenie katalogu `/home/marx/xbmc/comskip-0.92r'
make: *** [all] Błąd 2
Reply
(2013-02-01, 21:22)Marx1 Wrote: I've tried 0.92r with lowered versions but no luck. Can somebody provide precompiled binary for i386?

Follow the instructions in post 1 for a static ffmpeg build. I'm using ffmpeg 1.1.1.
Reply
ok it works now. Time to learn how to configure it properly
Reply
  • 1
  • 6
  • 7
  • 8(current)
  • 9
  • 10
  • 23

Logout Mark Read Team Forum Stats Members Help
Comskip for Linux released6