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