There is an mplayer patch for detecting groups of black frames, wich can
be used to auto skip commercials but it's for mplayer-pre5.
It requires also hacking mplayer.py for playback option.
I played with it in the past and does work on some channels, maybe the
idea is useable for future versions of freevo.
-- 
Groetjes Japie
http://www.japie.deserver.nl

2.6.18.1-ck1 GNU/Linux

Welcome to Hell! Here's your copy of Windows 98!
;^)
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpcodecs/dec_video.c MPlayer-1.0pre5-commercial_detect/libmpcodecs/dec_video.c
--- MPlayer-1.0pre5/libmpcodecs/dec_video.c	2004-02-18 16:23:41.000000000 +0100
+++ MPlayer-1.0pre5-commercial_detect/libmpcodecs/dec_video.c	2004-11-02 17:19:35.000000000 +0100
@@ -36,6 +36,7 @@
 
 extern double video_time_usage;
 extern double vout_time_usage;
+extern float framepts;
 
 #include "cpudetect.h"
 
@@ -327,6 +328,10 @@
 
 if(!mpi || drop_frame) return 0; // error / skipped frame
 
+// Noursy
+framepts = sh_video->pts;
+
+
 //vo_draw_image(video_out,mpi);
 vf=sh_video->vfilter;
 ret = vf->put_image(vf,mpi); // apply video filters and call the leaf vo/ve
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpcodecs/Makefile MPlayer-1.0pre5-commercial_detect/libmpcodecs/Makefile
--- MPlayer-1.0pre5/libmpcodecs/Makefile	2004-06-24 15:54:07.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/libmpcodecs/Makefile	2004-11-02 17:19:35.000000000 +0100
@@ -14,7 +14,7 @@
 VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c vd_odivx.c vd_divx4.c vd_zrmjpeg.c vd_xanim.c vd_xvid.c vd_xvid4.c vd_libdv.c vd_qtvideo.c vd_theora.c
 VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
 
-VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c vf_phase.c vf_divtc.c vf_harddup.c vf_softskip.c
+VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_scale.c vf_format.c vf_noformat.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_bfdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c vf_down3dright.c vf_field.c vf_denoise3d.c vf_hqdn3d.c vf_detc.c vf_telecine.c vf_tfields.c vf_ivtc.c vf_ilpack.c vf_dsize.c vf_decimate.c vf_softpulldown.c vf_tinterlace.c vf_pullup.c pullup.c vf_framestep.c vf_tile.c vf_delogo.c vf_fil.c vf_hue.c vf_spp.c vf_yuvcsp.c vf_filmdint.c vf_kerndeint.c vf_rgbtest.c vf_qp.c vf_phase.c vf_divtc.c vf_harddup.c vf_softskip.c
 ifeq ($(HAVE_FFPOSTPROCESS),yes)
 VFILTER_SRCS += vf_pp.c
 endif
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpcodecs/vf_bfdetect.c MPlayer-1.0pre5-commercial_detect/libmpcodecs/vf_bfdetect.c
--- MPlayer-1.0pre5/libmpcodecs/vf_bfdetect.c	1970-01-01 01:00:00.000000000 +0100
+++ MPlayer-1.0pre5-commercial_detect/libmpcodecs/vf_bfdetect.c	2004-11-02 17:19:35.000000000 +0100
@@ -0,0 +1,269 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "../libvo/fastmemcpy.h"
+#include "../postproc/rgb2rgb.h"
+
+struct vf_priv_s {
+    int ad_max_len;
+    char edl_filename[256];
+    FILE * edl_file;
+    int avg_limit;
+    int max_limit;
+    float f_pts;
+    float max_f_pts, prev_f_pts; // for PTS reset
+    int prev_is_black;
+    float current_black_begin, current_black_length;
+    float prev_black_begin, prev_black_length;
+    float ad_begin;
+};
+
+extern float framepts;
+
+/*static int checkline(unsigned char* src,int stride,int len,int bpp){
+    int total=0;
+    int div=len;
+    switch(bpp){
+    case 1:
+        while(--len>=0){
+            total+=src[0]; src+=stride;
+        }
+        break;
+    case 3:
+    case 4:
+        while(--len>=0){
+            total+=src[0]+src[1]+src[2]; src+=stride;
+        }
+        div*=3;
+        break;
+    }
+    total/=div;
+    //printf("total=%d\n",total);
+    return total;
+}*/
+
+static int calcimg(unsigned char* src,int stride,int width, int height, int bpp, int avg_limit, int max_limit){
+    int total=0;
+    int avg = 0;
+    int max = 0;
+    int y;
+    int max_limit_bpp = max_limit * bpp;
+
+    for(y=8; y < height - 8; y+=4){
+        unsigned char * s = src + stride * y;
+        int len = width - 8;
+        switch(bpp){
+        case 1:
+            while(--len>=0){
+                int sum = s[0];
+                if (sum > max) max = sum;
+                // shortcut
+                if (max > max_limit_bpp) return 0;
+                total+=sum; s+=bpp;
+            }
+            break;
+        case 3:
+        case 4:
+            while(--len>=0){
+                int sum = s[0]+s[1]+s[2];
+                if (sum > max) max = sum;
+                // shortcut
+                if (max > max_limit_bpp) return 0;
+                total+=sum; s+=bpp;
+            }
+            break;
+        }
+    }
+    avg = 4 * total / (width * height * bpp);
+    max /= bpp;
+    //printf(" avg=%d, max = %d                \n", avg, max);
+    return (avg < avg_limit && max < max_limit);
+}
+
+
+
+//===========================================================================//
+
+static int config(struct vf_instance_s* vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+    vf->priv->f_pts=0;
+    vf->priv->prev_is_black=0;
+    vf->priv->current_black_begin = -1;
+    vf->priv->current_black_length = 0;
+    vf->priv->prev_black_begin = -1;
+    vf->priv->prev_black_length = 0;
+    vf->priv->ad_begin = -1;
+    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
+    mp_image_t *dmpi;
+    int bpp=mpi->bpp/8;
+    int y;
+    int is_black = 1;
+    struct vf_priv_s * fp = vf->priv;
+
+    // hope we'll get DR buffer:
+    dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_EXPORT, 0,
+        mpi->w, mpi->h);
+
+    dmpi->planes[0]=mpi->planes[0];
+    dmpi->planes[1]=mpi->planes[1];
+    dmpi->planes[2]=mpi->planes[2];
+    dmpi->stride[0]=mpi->stride[0];
+    dmpi->stride[1]=mpi->stride[1];
+    dmpi->stride[2]=mpi->stride[2];
+    dmpi->width=mpi->width;
+    dmpi->height=mpi->height;
+
+fp->f_pts = framepts;
+if (fp->f_pts < fp->prev_f_pts) {
+  fp->max_f_pts = fp->prev_f_pts;
+  printf("\nPTS reset %f %f\n", fp->prev_f_pts, fp->f_pts);
+}
+fp->prev_f_pts = fp->f_pts;
+
+{
+    /*int val; 
+    int total = 0;
+    for(y=0; y<mpi->h; y++){
+        val = checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp);
+        total += val;
+        if(val > fp->limit){
+            is_black = 0;
+            //break;
+        }
+    }*/
+  
+    //printf("f_pts=%f pic type=%d\n", fp->f_pts, mpi->pict_type);
+    is_black = calcimg(mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, bpp, fp->avg_limit, fp->max_limit);
+    if (is_black == 1) {
+      if (fp->prev_is_black == 1) {
+        // Black-Black
+        // Continue sequence of black frames
+        fp->current_black_length = fp->f_pts - fp->current_black_begin;
+        if (fp->f_pts < fp->current_black_begin)
+          fp->current_black_length += fp->max_f_pts;
+      }
+      else {
+        // NonBlack-Black
+        // End of a sequence of non-black frames
+        fp->current_black_begin = fp->f_pts;
+        printf("\nNonBlack-Black %f\n", fp->f_pts);
+      }
+    }
+    else {
+      if (fp->prev_is_black == 1) {
+        // Black-NonBlack
+        // End of a sequence of black frames
+        fp->prev_black_begin = fp->current_black_begin;
+        fp->prev_black_length = fp->current_black_length;
+        fp->current_black_begin = -1;
+        fp->current_black_length = 0;
+        printf("\nBlack-NonBlack %f\n", fp->f_pts);
+      }
+      else {
+        // NonBlack-NonBlack
+        // Continue sequence of non-black frames
+        float length = fp->f_pts - (fp->prev_black_begin + fp->prev_black_length) + 1;
+        if (fp->f_pts < fp->prev_black_begin + fp->prev_black_length)
+          length += fp->max_f_pts;
+        if (fp->ad_begin != -1 && length > fp->ad_max_len) {
+          // the non-black sequence is longer than max_ad_length => not in ad
+          // anymore
+          float ad_end = fp->prev_black_begin + fp->prev_black_length;
+          if (fp->ad_begin > ad_end)
+            ad_end += fp->max_f_pts;
+          if (ad_end - fp->ad_begin > 1) {
+            // If the interval to be written is actually larger than 1 second
+            fprintf(fp->edl_file, "%3.2f %3.2f 0\n", fp->ad_begin, ad_end);
+            fflush(fp->edl_file);
+            printf("\nframepts = %f, begin=%f end=%f 0\n", fp->f_pts, fp->ad_begin, ad_end);
+          }
+          fp->ad_begin = -1;
+          fp->prev_black_begin = -1;
+          fp->prev_black_length = 0;
+        }
+        else {
+          // we are in an ad sequence (between two sets of black frames,
+          // separated by less than max_ad_length
+          if (fp->ad_begin == -1 && fp->prev_black_begin != -1) {
+            //printf(" In the first ad of a sequence\n");
+            // If we are in the first ad of the sequence
+            fp->ad_begin = fp->prev_black_begin;
+          }
+        }
+      }
+
+    }
+    fp->prev_is_black = is_black;
+}
+
+    return vf_next_put_image(vf,dmpi);
+}
+
+//===========================================================================//
+
+static void uninit(vf_instance_t *vf) {
+    struct vf_priv_s * fp = vf->priv;
+    //if (fp->ad_begin != -1 && fp->fno - (fp->prev_black_begin + fp->prev_black_length) + 1 > fp->ad_max_len) {
+    if (fp->ad_begin != -1) {
+      float ad_end = fp->f_pts;
+      if (fp->ad_begin > ad_end)
+        ad_end += fp->max_f_pts;
+      fprintf(fp->edl_file, "%3.2f %3.2f 0\n", fp->ad_begin, ad_end);
+      fflush(fp->edl_file);
+    }
+    fclose(fp->edl_file);
+}
+
+static int open(vf_instance_t *vf, char* args){
+    vf->config=config;
+    vf->uninit=uninit;
+    vf->put_image=put_image;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    strcpy(vf->priv->edl_filename, "test.edl");
+    vf->priv->ad_max_len=-1;
+    vf->priv->avg_limit=-1;
+    vf->priv->max_limit=-1;
+    if(args) sscanf(args, "%d:%d:%d:%s",
+        &vf->priv->ad_max_len,
+        &vf->priv->avg_limit,
+        &vf->priv->max_limit,
+        vf->priv->edl_filename);
+    if (vf->priv->ad_max_len == -1) vf->priv->ad_max_len = 64;
+    if (vf->priv->avg_limit == -1) vf->priv->avg_limit = 20;
+    if (vf->priv->max_limit == -1) vf->priv->max_limit = 35;
+    mp_msg(MSGT_VFILTER, MSGL_INFO, "Black frames detect: ad max length=%d, avg limit=%d, max limit=%d, outfile=%s\n",
+        vf->priv->ad_max_len,
+        vf->priv->avg_limit,
+        vf->priv->max_limit,
+        vf->priv->edl_filename);
+    vf->priv->edl_file=fopen(vf->priv->edl_filename, "w");
+    if (vf->priv->edl_file == NULL) {
+        return 0;
+    }
+    return 1;
+}
+
+vf_info_t vf_info_bfdetect = {
+    "autodetect black frames",
+    "bfdetect",
+    "Noursy",
+    "",
+    open,
+    NULL
+};
+
+//===========================================================================//
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpcodecs/vf.c MPlayer-1.0pre5-commercial_detect/libmpcodecs/vf.c
--- MPlayer-1.0pre5/libmpcodecs/vf.c	2004-05-31 17:07:58.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/libmpcodecs/vf.c	2004-11-02 17:19:35.000000000 +0100
@@ -45,6 +45,7 @@
 extern vf_info_t vf_info_zrmjpeg;
 extern vf_info_t vf_info_dvbscale;
 extern vf_info_t vf_info_cropdetect;
+extern vf_info_t vf_info_bfdetect;
 extern vf_info_t vf_info_test;
 extern vf_info_t vf_info_noise;
 extern vf_info_t vf_info_yvu9;
@@ -126,6 +127,7 @@
 #endif
     &vf_info_dvbscale,
     &vf_info_cropdetect,
+    &vf_info_bfdetect,
     &vf_info_test,
     &vf_info_noise,
     &vf_info_yvu9,
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpdemux/demuxer.h MPlayer-1.0pre5-commercial_detect/libmpdemux/demuxer.h
--- MPlayer-1.0pre5/libmpdemux/demuxer.h	2004-04-12 16:19:12.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/libmpdemux/demuxer.h	2004-11-02 17:19:35.000000000 +0100
@@ -77,6 +77,7 @@
 // Holds one packet/frame/whatever
 typedef struct demux_packet_st {
   int len;
+  int payload_size;
   float pts;
   off_t pos;  // position in index (AVI) or file (MPG)
   unsigned char* buffer;
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/libmpdemux/demux_ts.c MPlayer-1.0pre5-commercial_detect/libmpdemux/demux_ts.c
--- MPlayer-1.0pre5/libmpdemux/demux_ts.c	2004-06-18 22:02:05.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/libmpdemux/demux_ts.c	2004-11-02 17:22:01.000000000 +0100
@@ -880,7 +880,6 @@
 	if(es->payload_size)
 		es->payload_size -= header_len + 3;
 
-
 	if (stream_id == 0xbd)
 	{
 		mp_msg(MSGT_DEMUX, MSGL_DBG3, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X, 80: %d\n",
@@ -914,7 +913,10 @@
 			es->start = p;
 			es->size  = packet_len;
 			es->type  = SPU_DVB;
-			es->payload_size -= packet_len;
+			//es->payload_size -= packet_len;  // this is probably a mistake, I
+      //comment it out
+      //printf("PES PARSE 2, SPU_DVB, payload size = %d\n", es->payload_size);
+      //printf("PES PARSE 2, PTS=%f\n", es->pts); 
 
 			return 1;
 		}
@@ -1022,7 +1024,7 @@
 		else
 			es->type    = AUDIO_MP2;
 
-		es->payload_size -= packet_len;
+		//es->payload_size -= packet_len; // This is probably a mistake
 
 		return 1;
 	}
@@ -1614,7 +1616,7 @@
 static int fill_packet(demuxer_t *demuxer, demux_stream_t *ds, demux_packet_t **dp, int *dp_offset)
 {
 	int ret = 0;
-
+  int i;
 	if((*dp != NULL) && (*dp_offset > 0))
 	{
 			ret = *dp_offset;
@@ -1736,7 +1738,7 @@
 				buf_size -= c;
 				if(buf_size == 0)
 					continue;
-
+        
 				afc = c + 1;
 			}
 			else
@@ -1906,11 +1908,12 @@
 
 		if(is_start)
 		{
-			mp_msg(MSGT_DEMUX, MSGL_DBG2, "IS_START\n");
+			int i;
+      mp_msg(MSGT_DEMUX, MSGL_DBG2, "IS_START\n");
 
 			p = &packet[base];
 			stream_read(stream, p, buf_size);
-
+ 
 			len = pes_parse2(p, buf_size, es, pid_type);
 			es->pid = tss->pid;
 					
@@ -1974,6 +1977,10 @@
 						(*dp)->flags = 0;
 						(*dp)->pos = stream_tell(demuxer->stream);
 						(*dp)->pts = es->pts;
+            (*dp)->payload_size = es->payload_size;
+            //printf("[%s] ENQUEUED size=%d, expected length=%d\n", is_sub?"sub":is_video?"vid":"aud",*dp_offset, (*dp)->payload_size);
+            if (*dp_offset == (*dp)->payload_size)
+				      retv = fill_packet(demuxer, ds, dp, dp_offset, broken);
 
 				if(is_audio)
 				{
@@ -2039,6 +2046,7 @@
 				}
 
 				stream_read(stream, &((*dp)->buffer[*dp_offset]), sz);
+
 				*dp_offset += sz;
 
 				if(buf_size - sz > 0)
@@ -2053,6 +2061,12 @@
 					return 1;
 				}
 
+         //printf("[%s] ENQUEUED size=%d, expected length=%d\n", is_sub?"sub":is_video?"vid":"aud",*dp_offset, (*dp)->payload_size);
+         if (*dp_offset == (*dp)->payload_size)
+ 				  retv = fill_packet(demuxer, ds, dp, dp_offset, broken);
+         if (retv)
+           return retv;
+         else
 				continue;
 			}
 			else
@@ -2120,89 +2134,250 @@
 	sh_audio_t *sh_audio=d_audio->sh;
 	sh_video_t *sh_video=d_video->sh;
 	ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
-	int i, video_stats;
-	off_t newpos;
-
+	int i, video_stats, loop;
+	off_t newpos, begin_pos, prev_newpos, oldpos, largest_pts_pos;
+  int happy=0;
+  float begin_v_pts, target_v_pts, old_v_pts, old_old_v_pts, largest_pts;
+  float approx_bps;
+
+#define NORMAL 0
+#define SEARCH_TRANSITION 1
+#define REFINE_TRANSITION 2
+#define SECOND_PART_SEEK 3
+  int state = NORMAL;
+  
 	//================= seek in MPEG-TS ==========================
 
-	ts_dump_streams(demuxer->priv);
-	reset_fifos(priv, sh_audio != NULL, sh_video != NULL, demuxer->sub->id > 0);
-
-
-	if(sh_audio != NULL)
-		ds_free_packs(d_audio);
-	if(sh_video != NULL)
-		ds_free_packs(d_video);
-	if(demuxer->sub->id > 0)
-		ds_free_packs(d_sub);
-
+  begin_v_pts = old_v_pts = sh_video->pts;
+  target_v_pts = sh_video->pts + rel_seek_secs;
+  prev_newpos=0;
 
 	video_stats = (sh_video != NULL);
 	if(video_stats)
 		video_stats = sh_video->i_bps;
+  
+  begin_pos = oldpos = newpos = (flags & 1) ? demuxer->movi_start : demuxer->filepos;
 
-	newpos = (flags & 1) ? demuxer->movi_start : demuxer->filepos;
+  //printf("\nSEEK: rel_seek_secs = %f, begin_v_pts = %f, target_v_pts = %f, begin_pos = %lld\n", rel_seek_secs, begin_v_pts, target_v_pts, begin_pos);
 	if(flags & 2) // float seek 0..1
 		newpos+=(demuxer->movi_end-demuxer->movi_start)*rel_seek_secs;
-	else
-	{
+	else {
 		// time seek (secs)
-
 		if(! video_stats) // unspecified or VBR
 			newpos += 2324*75*rel_seek_secs; // 174.3 kbyte/sec
 		else
 			newpos += video_stats*rel_seek_secs;
 	}
 
+  loop = 0;
+  do {
+
+    ts_dump_streams(demuxer->priv);
+    reset_fifos(priv, sh_audio != NULL, sh_video != NULL, demuxer->sub->id > 0);
 
-	if(newpos < demuxer->movi_start)
-  		newpos = demuxer->movi_start;	//begininng of stream
+    if(sh_audio != NULL)
+      ds_free_packs(d_audio);
+    if(sh_video != NULL)
+      ds_free_packs(d_video);
+    if(demuxer->sub->id > 0)
+      ds_free_packs(d_sub);
+
+    if(newpos < demuxer->movi_start) {
+        newpos = demuxer->movi_start;	//begininng of stream
+     }
+    else if (newpos > demuxer->movi_end)
+        newpos = demuxer->movi_end - video_stats*10;
 
 #ifdef _LARGEFILE_SOURCE
-	newpos &= ~((long long) (STREAM_BUFFER_SIZE - 1));  /* sector boundary */
+    newpos &= ~((long long) (STREAM_BUFFER_SIZE - 1));  /* sector boundary */
 #else
-	newpos &= ~(STREAM_BUFFER_SIZE - 1);  /* sector boundary */
+    newpos &= ~(STREAM_BUFFER_SIZE - 1);  /* sector boundary */
 #endif
+    stream_seek(demuxer->stream, newpos);
 
-	stream_seek(demuxer->stream, newpos);
+    videobuf_code_len = 0;
 
-	videobuf_code_len = 0;
+    if(sh_video != NULL)
+      ds_fill_buffer(d_video);
 
-	if(sh_video != NULL)
-		ds_fill_buffer(d_video);
-
-	if(sh_audio != NULL)
-	{
-		ds_fill_buffer(d_audio);
-		resync_audio_stream(sh_audio);
-	}
-
-	while(sh_video != NULL)
-	{
-		if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts)
-		{
-			float a_pts=d_audio->pts;
-			a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
-			if(d_video->pts > a_pts)
-			{
-				skip_audio_frame(sh_audio);  // sync audio
-				continue;
-			}
-		}
-
-
-		i = sync_video_packet(d_video);
-		if((sh_video->format == VIDEO_MPEG1) || (sh_video->format == VIDEO_MPEG2))
-		{
-			if(i==0x1B3 || i==0x1B8) break; // found it!
-		}
-		else //MPEG4
-		{
-			if(i==0x1B6) break; // found it!
-		}
-
-		if(!i || !skip_video_packet(d_video)) break; // EOF?
-	}
+    if(sh_audio != NULL)
+    {
+      ds_fill_buffer(d_audio);
+      resync_audio_stream(sh_audio);
+    }
+
+    while(sh_video != NULL)
+    {
+      if(sh_audio && !d_audio->eof && d_video->pts && d_audio->pts)
+      {
+        float a_pts=d_audio->pts;
+        a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+        if(d_video->pts > a_pts)
+        {
+          skip_audio_frame(sh_audio);  // sync audio
+          continue;
+        }
+      }
+
+      //printf("loop\n");
+      i = sync_video_packet(d_video);
+      if((sh_video->format == VIDEO_MPEG1) || (sh_video->format == VIDEO_MPEG2))
+      {
+        float d_video_pts = d_video->pts;
+        long long curpos = stream_tell(demuxer->stream);
+        if (d_video_pts > largest_pts) {
+          largest_pts = d_video_pts;
+          largest_pts_pos = curpos;
+        }
+        //printf("\nd_video_pts=%f, stream pos=%lld\n", d_video_pts, curpos);
+        
+        if(i==0x1B3 || i==0x1B8) {
+          if (state == NORMAL) {
+            if ((d_video_pts < begin_v_pts && rel_seek_secs > 0) ||
+                (d_video_pts > begin_v_pts && rel_seek_secs < 0)) {
+              state = SEARCH_TRANSITION;
+              //printf("Passed PTS reset %s => state = SEARCH_TRANSITION\n", rel_seek_secs < 0? "backwards":"forwards");
+            }
+            else {
+              // Normal case
+              video_stats = abs((begin_pos - curpos) / (d_video_pts - begin_v_pts));
+              //printf("video_stats = %d, newpos = %lld\n", video_stats, newpos);
+              if (newpos == prev_newpos) {
+                //printf("newpos = %lld, prev_newpos = %lld\n", newpos, prev_newpos);
+                happy=1; break; // to avoid infinite loop
+              }
+              // Cannot sync better than 0.5 sec in MPEG 1/2 (GOP size = 0.5 sec)
+              //printf("d_video_pts = %f, target_v_pts = %f, delta = %f\n", d_video_pts, target_v_pts, d_video_pts - target_v_pts);
+              if (abs(d_video_pts - target_v_pts) >= .5 && newpos > demuxer->movi_start) {
+                prev_newpos = newpos;
+                newpos = newpos + video_stats * (target_v_pts - d_video_pts);
+                //printf("new newpos = %lld\n", newpos);
+                if (newpos < demuxer->movi_start || newpos > demuxer->movi_end)
+                  happy = 1;
+              }
+              else
+                happy = 1;
+            }
+          }
+          if (state == SEARCH_TRANSITION) {
+            if (abs(old_v_pts - d_video_pts) <= 0.5|| abs(old_old_v_pts - d_video_pts) <= 0.5) {
+              state = REFINE_TRANSITION;
+              newpos = largest_pts_pos + 1;
+              oldpos = largest_pts_pos;
+              old_v_pts = largest_pts;
+              //printf("Transition found: %f => state = REFINE_TRANSITION\n", largest_pts);
+            }
+            else {
+              // search the transition by dichotomy
+              //printf("SEARCH_TRANSITION => oldpos=%lld curpos=%lld, old_old_pts=%f, old_pts=%f, cur_pts=%f\n", oldpos, curpos, old_old_v_pts, old_v_pts, d_video_pts);
+              if (curpos < oldpos) {
+                //printf("dir=bw, ");
+                if (d_video_pts > old_v_pts) {
+                  //printf("go fw\n");
+                  // -----------C------------+-----------O-------------
+                  newpos = curpos + (oldpos-curpos)/2;
+                }
+                else {
+                  //printf("go bw\n");
+                  // ------------------------+---C-------O-------------
+                  newpos = curpos - (oldpos-curpos);
+                }
+              }
+              else {
+                //printf("dir=fw, ");
+                if (d_video_pts > old_v_pts) {
+                  //printf("go fw\n");
+                  // ----------O--------C----+------------------------
+                  newpos = curpos + (curpos - oldpos);
+                }
+                else {
+                  //printf("go bw\n");
+                  // ----------O------------+--------C---------------
+                  newpos = curpos + (oldpos-curpos)/2;
+                }
+              }
+              oldpos = curpos;
+              old_old_v_pts = old_v_pts;
+              old_v_pts = d_video_pts;
+              //printf("SEARCH_TRANSITION => newpos=%lld\n", newpos);
+            }
+          }
+          else if (state == REFINE_TRANSITION) {
+            if (d_video_pts < old_v_pts) {
+              state = SECOND_PART_SEEK;
+            }
+            else {
+              newpos = curpos +1;
+              oldpos = curpos;
+              old_v_pts = d_video_pts;
+            }
+
+          }
+          if (state == SECOND_PART_SEEK) {
+            //printf("state = SECOND_PART_SEEK. transition PTS = %f and %f\n", old_v_pts, d_video_pts);
+            //printf("target_v_pts = %f, rel_seek_secs = %f\n", target_v_pts, rel_seek_secs);
+            if (target_v_pts > old_v_pts) {
+              target_v_pts -= old_v_pts + d_video_pts;
+              //printf("[1] target_v_pts = %f, rel_seek_secs = %f\n", target_v_pts, rel_seek_secs);
+            }
+            else if (target_v_pts < d_video_pts) {
+              target_v_pts += old_v_pts;
+              //printf("[2] target_v_pts = %f, rel_seek_secs = %f\n", target_v_pts, rel_seek_secs);
+            }
+            if (abs(target_v_pts - old_v_pts) < abs(target_v_pts - d_video_pts)) {
+              //printf("Case 1\n");
+              // target is before the PTS reset
+              rel_seek_secs = target_v_pts - old_v_pts;
+              begin_v_pts = old_v_pts;
+              begin_pos = oldpos;
+            }
+            else {
+              //printf("Case 2\n");
+              // target is after the PTS reset
+              rel_seek_secs = target_v_pts - d_video_pts;
+              begin_v_pts = d_video_pts;
+              begin_pos = curpos;
+            }
+            newpos = begin_pos + rel_seek_secs * video_stats;
+            state = NORMAL;
+            //printf("Normal jump: rel_seek_secs = %f, newpos = %lld\n", rel_seek_secs, newpos);
+          }
+          break; // found it!
+        }
+      }
+      else //MPEG4
+      {
+        if(i==0x1B6) {
+          happy = 1; // Variable GOP size => headache, I give up
+          break; // found it!
+        }
+      }
+
+      if(!i || !skip_video_packet(d_video)) {
+        happy = 1;
+        break; // EOF?
+      }
+    }
+    loop ++;
+  } while (!happy && loop < 20);
+  if (loop == 20) {
+    printf("demux_seek_ts: loop went wild, emergency exit\n");
+    switch (state) {
+      case NORMAL: {
+        printf(" State=NORMAL: begin_pos=%lld, curpos=%lld, newpos=%lld, prev_newpos=%f, begin_v_pts=%f, d_video_pts=%f\n");
+        break;
+      }
+      case SEARCH_TRANSITION: {
+        printf("  State=SEARCH_TRANSITION: begin_pos=%lld, curpos=%lld, newpos=%lld, oldpos=%f, begin_v_pts=%f, d_video_pts=%f old_v_pts=%f\n");
+        break;
+      }
+      case REFINE_TRANSITION: {
+        printf("REFINE_TRANSITION: begin_pos=%lld, curpos=%lld, newpos=%lld, oldpos=%f, begin_v_pts=%f, d_video_pts=%f old_v_pts=%f\n");
+        break;
+      }
+    }
+  }
+  //printf("end seek\n");
 }
 
 
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/mencoder.c MPlayer-1.0pre5-commercial_detect/mencoder.c
--- MPlayer-1.0pre5/mencoder.c	2004-06-08 18:43:24.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/mencoder.c	2004-11-02 17:19:35.000000000 +0100
@@ -141,6 +141,7 @@
 double cur_video_time_usage=0;
 double cur_vout_time_usage=0;
 int benchmark=0;
+float framepts=0;
 
 // A-V sync:
 int delay_corrected=1;
diff -Naur -X mplayer_diff.excludes MPlayer-1.0pre5/mplayer.c MPlayer-1.0pre5-commercial_detect/mplayer.c
--- MPlayer-1.0pre5/mplayer.c	2004-07-14 11:25:47.000000000 +0200
+++ MPlayer-1.0pre5-commercial_detect/mplayer.c	2004-11-02 17:19:35.000000000 +0100
@@ -88,6 +88,8 @@
 int verbose=0;
 int identify=0;
 int quiet=0;
+float framepts = 0;
+
 
 #define ABS(x) (((x)>=0)?(x):(-(x)))
 #define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
@@ -971,11 +973,11 @@
 	 } else {
 	   if( next_edl_array_index > 0 ) {
 	     edl_records[ next_edl_array_index-1 ].next = &edl_records[ next_edl_array_index ];
-	     if( start <= edl_records[ next_edl_array_index-1 ].stop_sec ) {
+	     /*if( start <= edl_records[ next_edl_array_index-1 ].stop_sec ) {
 	       printf( "Invalid EDL line [%d]: [%s]\n", lineCount, line );
 	       printf( "Last stop position was [%f]; next start is [%f]. Entries must be in chronological order and cannot overlap. Discarding EDL entry.\n", edl_records[ next_edl_array_index-1 ].stop_sec, start );
 	       continue;
-	     }
+	     }*/
 	   }
 	   if( stop <= start ) {
 	     printf( "Invalid EDL line [%d]: [%s]\n", lineCount, line );
@@ -2484,7 +2486,7 @@
     mp_msg( MSGT_CPLAYER, MSGL_ERR, "Cannot use edit list without video. EDL disabled.\n" );
     next_edl_record->next = NULL;
   } else {
-   if( sh_video->pts >= next_edl_record->start_sec ) {
+   if( sh_video->pts >= next_edl_record->start_sec && sh_video->pts < next_edl_record->stop_sec) {
      if( next_edl_record->action == EDL_SKIP ) {
        osd_function = OSD_FFW;
        abs_seek_pos = 0;
@@ -3471,7 +3473,7 @@
 	if( !edl_decision ) {
 	  for( x = 0; x < num_edl_records; x++ ) { // FIXME: do binary search
 	    // Find first EDL entry where start follows current time
-	    if( edl_records[ x ].start_sec >= sh_video->pts && edl_records[ x ].action != EDL_MUTE ) {
+	    if( edl_records[ x ].start_sec >= sh_video->pts && edl_records[ x ].stop_sec < sh_video->pts && edl_records[ x ].action != EDL_MUTE ) {
 	      next_edl_record = &edl_records[ x ];
 	      break;
 	    }
diff -Naur freevo-1.5.2/ChangeLog freevo-1.5.2-comercials_patch/ChangeLog
--- freevo-1.5.2/ChangeLog	2004-10-31 16:11:18.000000000 +0100
+++ freevo-1.5.2-comercials_patch/ChangeLog	2004-11-09 10:38:12.026256784 +0100
@@ -3,6 +3,11 @@
 
 $Id: ChangeLog,v 1.119.2.4 2004/10/20 18:37:03 dischi Exp $
 
+Release 1.5.2 comercials patch (2004-11-08):
+---------------------------
+ * Added comercials option to the video fxd format. (patched Mplayer version needed, record tv with "-vf bfdetect=64:20:35:$1.edl" option...)
+
+
 Release 1.5.2 (2004-10-24):
 ---------------------------
  * Fix memory leak when running image viewer in slideshow mode
diff -Naur freevo-1.5.2/src/video/fxdhandler.py freevo-1.5.2-comercials_patch/src/video/fxdhandler.py
--- freevo-1.5.2/src/video/fxdhandler.py	2004-07-11 13:47:02.000000000 +0200
+++ freevo-1.5.2-comercials_patch/src/video/fxdhandler.py	2004-11-11 19:28:36.000000000 +0100
@@ -61,6 +61,7 @@
         <variants>
             <variant>
                 <part ref mplayer_options>
+                    <comercials media_id>file</comercials>
                     <subtitle media_id>file</subtitle>
                     <audio media_id>file</audio>
                 </part>+
@@ -166,6 +167,16 @@
                     subtitle = {}
                 v.subtitle_file = subtitle
 
+                comercials = fxd.get_children(parts[0], 'comercials')
+                if comercials:
+                    comercials = { 'media_id': fxd.getattr(comercials[0], 'media-id'),
+                                 'file'    : fxd.gettext(comercials[0]) }
+                    if not comercials['media_id']:
+                        comercials['file'] = os.path.join(dirname, comercials['file'])
+                else:
+                   comercials  = {}
+                v.comercials_file = comercials
+
                 # global <video> mplayer_options
                 if mplayer_options:
                     v.mplayer_options += mplayer_options
@@ -193,9 +204,18 @@
                     else:
                         subtitle = {}
 
+                    if comercials:
+                        comercials = { 'media_id': fxd.getattr(comercials[0], 'media-id'),
+                                     'file'    : fxd.gettext(comercials[0]) }
+                        if not comercials['media_id']:
+                            comercials['file'] = os.path.join(dirname, comercials['file'])
+                    else:
+                        comercials = {}
+
                     sub = VideoItem(id[ref][1], parent=v, info=item.info, parse=False)
                     sub.files = None
                     sub.media_id, sub.mplayer_options, player, is_playlist = id[ref][2:]
+                    sub.comercials_file = comercials
                     sub.subtitle_file = subtitle
                     sub.audio_file    = audio
                     # global <video> mplayer_options
diff -Naur freevo-1.5.2/src/video/plugins/mplayer.py freevo-1.5.2-comercials_patch/src/video/plugins/mplayer.py
--- freevo-1.5.2/src/video/plugins/mplayer.py	2004-09-11 18:25:34.000000000 +0200
+++ freevo-1.5.2-comercials_patch/src/video/plugins/mplayer.py	2004-11-08 16:30:16.000000000 +0100
@@ -324,6 +324,11 @@
             
             child.wait()
 
+        if item.comercials_file:
+            d, f = util.resolve_media_mountdir(item.comercials_file)
+            util.mount(d)
+            command += ['-edl', f]
+
         if item.subtitle_file:
             d, f = util.resolve_media_mountdir(item.subtitle_file)
             util.mount(d)
diff -Naur freevo-1.5.2/src/video/videoitem.py freevo-1.5.2-comercials_patch/src/video/videoitem.py
--- freevo-1.5.2/src/video/videoitem.py	2004-10-20 20:33:20.000000000 +0200
+++ freevo-1.5.2-comercials_patch/src/video/videoitem.py	2004-11-08 16:35:35.000000000 +0100
@@ -102,25 +102,27 @@
         if info:
             self.info.set_variables(info)
 
-        self.variants          = []         # if this item has variants
-        self.subitems          = []         # more than one file/track to play
-        self.current_subitem   = None
-        self.media_id          = ''
-
-        self.subtitle_file     = {}         # text subtitles
-        self.audio_file        = {}         # audio dubbing
-
-        self.mplayer_options   = ''
-        self.tv_show           = False
-
-        self.video_width       = 0
-        self.video_height      = 0
-
-        self.selected_subtitle = None
-        self.selected_audio    = None
-        self.elapsed           = 0
+        self.variants            = []         # if this item has variants
+        self.subitems            = []         # more than one file/track to play
+        self.current_subitem     = None
+        self.media_id            = ''
+
+        self.comercials_file     = {}         # comercials skipping
+        self.subtitle_file       = {}         # text subtitles
+        self.audio_file          = {}         # audio dubbing
+
+        self.mplayer_options     = ''
+        self.tv_show             = False
+
+        self.video_width         = 0
+        self.video_height        = 0
+
+        self.selected_comercials = None
+        self.selected_subtitle   = None
+        self.selected_audio      = None
+        self.elapsed             = 0
         
-        self.possible_player   = []
+        self.possible_player     = []
 
         # find image for tv show and build new title
         if config.VIDEO_SHOW_REGEXP_MATCH(self.name) and not self.network_play and \
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Freevo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-users

Reply via email to