[vlc-devel] commit: avformat: Support for AVChapters. (Derk-Jan Hartman )
git version control
git at videolan.org
Tue Sep 23 17:01:35 CEST 2008
vlc | branch: master | Derk-Jan Hartman <hartman at videolan.org> | Tue Sep 23 17:01:54 2008 +0200| [be3f9e2d910a61ae87d79f4fb0481848331dc950] | committer: Derk-Jan Hartman
avformat: Support for AVChapters.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=be3f9e2d910a61ae87d79f4fb0481848331dc950
---
modules/demux/avformat/demux.c | 121 +++++++++++++++++++++++++++++++++++++--
1 files changed, 114 insertions(+), 7 deletions(-)
diff --git a/modules/demux/avformat/demux.c b/modules/demux/avformat/demux.c
index 683c184..3c17ac4 100644
--- a/modules/demux/avformat/demux.c
+++ b/modules/demux/avformat/demux.c
@@ -35,6 +35,7 @@
#include <vlc_stream.h>
#include <vlc_meta.h>
#include <vlc_input.h>
+#include <vlc_charset.h>
/* ffmpeg header */
#if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
@@ -56,6 +57,10 @@
# define HAVE_FFMPEG_CODEC_ATTACHMENT 1
#endif
+#if (LIBAVFORMAT_VERSION_INT >= ((52<<16)+(15<<8)+0) )
+# define HAVE_FFMPEG_CHAPTERS 1
+#endif
+
/*****************************************************************************
* demux_sys_t: demux descriptor
*****************************************************************************/
@@ -79,6 +84,9 @@ struct demux_sys_t
int i_attachments;
input_attachment_t **attachments;
+
+ /* Only one title with seekpoints possible atm. */
+ input_title_t *p_title;
};
/*****************************************************************************
@@ -90,6 +98,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args );
static int IORead( void *opaque, uint8_t *buf, int buf_size );
static offset_t IOSeek( void *opaque, offset_t offset, int whence );
+static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time );
+
/*****************************************************************************
* Open
*****************************************************************************/
@@ -99,8 +109,9 @@ int OpenDemux( vlc_object_t *p_this )
demux_sys_t *p_sys;
AVProbeData pd;
AVInputFormat *fmt;
- unsigned int i;
- bool b_avfmt_nofile;
+ unsigned int i;
+ bool b_avfmt_nofile;
+ int64_t i_start_time = -1;
/* Init Probe data */
pd.filename = p_demux->psz_path;
@@ -163,6 +174,7 @@ int OpenDemux( vlc_object_t *p_this )
p_sys->i_pcr_tk = -1;
p_sys->i_pcr = -1;
TAB_INIT( p_sys->i_attachments, p_sys->attachments);
+ p_sys->p_title = NULL;
/* Create I/O wrapper */
p_sys->io_buffer_size = 32768; /* FIXME */
@@ -298,17 +310,37 @@ int OpenDemux( vlc_object_t *p_this )
psz_type, (char*)&fcc );
TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
}
+ if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
+ i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;
msg_Dbg( p_demux, "AVFormat supported stream" );
msg_Dbg( p_demux, " - format = %s (%s)",
p_sys->fmt->name, p_sys->fmt->long_name );
- msg_Dbg( p_demux, " - start time = %"PRId64,
- ( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE ) ?
- p_sys->ic->start_time * 1000000 / AV_TIME_BASE : -1 );
+ msg_Dbg( p_demux, " - start time = %"PRId64, i_start_time );
msg_Dbg( p_demux, " - duration = %"PRId64,
( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
+#if HAVE_FFMPEG_CHAPTERS
+ p_sys->p_title = vlc_input_title_New();
+ for( i = 0; i < p_sys->ic->nb_chapters; i++ )
+ {
+ seekpoint_t *s = vlc_seekpoint_New();
+
+ if( p_sys->ic->chapters[i]->title )
+ {
+ s->psz_name = strdup( p_sys->ic->chapters[i]->title );
+ EnsureUTF8( s->psz_name );
+ msg_Dbg( p_demux, " - chapter %d: %s", i, s->psz_name );
+ }
+ s->i_time_offset = p_sys->ic->chapters[i]->start * 1000000 *
+ p_sys->ic->chapters[i]->time_base.num /
+ p_sys->ic->chapters[i]->time_base.den -
+ (i_start_time != -1 ? i_start_time : 0 );
+ TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
+ }
+#endif
+
return VLC_SUCCESS;
}
@@ -332,6 +364,9 @@ void CloseDemux( vlc_object_t *p_this )
free( p_sys->attachments[i] );
TAB_CLEAN( p_sys->i_attachments, p_sys->attachments);
+ if( p_sys->p_title )
+ vlc_input_title_Delete( p_sys->p_title );
+
free( p_sys->io_buffer );
free( p_sys );
}
@@ -397,10 +432,34 @@ static int Demux( demux_t *p_demux )
}
es_out_Send( p_demux->out, p_sys->tk[pkt.stream_index], p_frame );
+
+ UpdateSeekPoint( p_demux, p_sys->i_pcr);
av_free_packet( &pkt );
return 1;
}
+static void UpdateSeekPoint( demux_t *p_demux, int64_t i_time )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ int i;
+
+ if( !p_sys->p_title )
+ return;
+
+ for( i = 0; i < p_sys->p_title->i_seekpoint; i++ )
+ {
+ if( i_time < p_sys->p_title->seekpoint[i]->i_time_offset )
+ break;
+ }
+ i--;
+
+ if( i != p_demux->info.i_seekpoint && i >= 0 )
+ {
+ p_demux->info.i_seekpoint = i;
+ p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
+ }
+}
+
/*****************************************************************************
* Control:
*****************************************************************************/
@@ -444,12 +503,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
(av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0) )
{
int64_t i_size = stream_Size( p_demux->s );
- i64 = (int64_t)i_size * f;
msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
- if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
+ if( av_seek_frame( p_sys->ic, -1, (i_size * f), AVSEEK_FLAG_BYTE ) < 0 )
return VLC_EGENERIC;
}
+ UpdateSeekPoint( p_demux, i64 );
es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
p_sys->i_pcr = -1; /* Invalidate time display */
}
@@ -483,6 +542,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
}
es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
p_sys->i_pcr = -1; /* Invalidate time display */
+ UpdateSeekPoint( p_demux, i64 );
return VLC_SUCCESS;
case DEMUX_GET_META:
@@ -526,6 +586,53 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return VLC_SUCCESS;
}
+ case DEMUX_GET_TITLE_INFO:
+ {
+ input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
+ int *pi_int = (int*)va_arg( args, int* );
+ int *pi_title_offset = (int*)va_arg( args, int* );
+ int *pi_seekpoint_offset = (int*)va_arg( args, int* );
+
+ if( !p_sys->p_title )
+ return VLC_EGENERIC;
+
+ *pi_int = 1;
+ *ppp_title = malloc( sizeof( input_title_t**) );
+ (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->p_title );
+ *pi_title_offset = 0;
+ *pi_seekpoint_offset = 0;
+ return VLC_SUCCESS;
+ }
+ case DEMUX_SET_TITLE:
+ {
+ const int i_title = (int)va_arg( args, int );
+ if( !p_sys->p_title || i_title != 0 )
+ return VLC_EGENERIC;
+ return VLC_SUCCESS;
+ }
+ case DEMUX_SET_SEEKPOINT:
+ {
+ const int i_seekpoint = (int)va_arg( args, int );
+ if( !p_sys->p_title )
+ return VLC_EGENERIC;
+
+ i64 = p_sys->p_title->seekpoint[i_seekpoint]->i_time_offset *AV_TIME_BASE / 1000000;
+ if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
+ i64 += p_sys->ic->start_time;
+
+ msg_Warn( p_demux, "DEMUX_SET_TIME: %"PRId64, i64 );
+
+ if( av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0 )
+ {
+ return VLC_EGENERIC;
+ }
+ es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
+ p_sys->i_pcr = -1; /* Invalidate time display */
+ UpdateSeekPoint( p_demux, i64 );
+ return VLC_SUCCESS;
+ }
+
+
default:
return VLC_EGENERIC;
}
More information about the vlc-devel
mailing list