[MPlayer-dev-eng] .TiVo file support

Nico Sabbi nicola_sabbi at fastwebnet.it
Wed Dec 13 23:11:04 CET 2006


Jeremy Drake wrote:
> On Tue, 12 Dec 2006, Jeremy Drake wrote:
> 
> 
>>On Sun, 10 Dec 2006, Nico Sabbi wrote:
>>
>>
>>>if the output of your processing is a valid mpeg-[pt]s file than writing a
>>>linked demuxer is the only sane way to proceed.
>>>It's quite easy:
>>>in the open() function, after having assigned demuxer->video->id appropriately
>>>(depending on your code), add this block
>>>
>>>
>>>{
>>>    extern int audio_id, video_id, dvdsub_id;
>>>    stream_t* s = new_ds_stream(demuxer->video);
>>>    demuxer_t* od = demux_open(s, DEMUXER_TYPE_UNKNOWN,
>>>                               audio_id, video_id, dvdsub_id, NULL);
>>>    demuxer = new_demuxers_demuxer(od, od, od);
>>>  }
>>>
>>>and in the fill_buffer() function you just have to add the newly
>>>created demux_packet() to demuxer->video with
>>>ds_add_packet(demuxer->video, dp);
>>
>>I tried this, and in trying to test it, it would end up calling my demuxer
>>again rather than the mpeg one.  I started the program with -demuxer
>>mydemuxer option to get it to use my demuxer.  Please help.  I don't know
>>what I'm doing ;)
> 
> 
> I fixed this by implementing a check_file function.  It now will play a
> file!!!
> 
> However, I cannot help but feel that my coding sucks.  Since I have a very
> weak understanding of how this stuff works, it does some stuff that seems
> quite daft.  I would very much appreciate someone taking a look at this
> file (trying to attach it) and help me make it nicer.  Such as my tendency
> to feed the data to the mpeg demuxer in one-byte packets if they are not
> what I am trying to deal with.  I could also use some help with seeking
> and knowing where I am in the file, I don't know how to go about that, but
> it should be able to work more or less like regular mpeg one at first, and
> I can special-case what I need to from there.  Is there some way to make
> use of the mpeg seeking code, or do I need to cut, paste, and hack?
> 
> Sorry I'm so much trouble, I don't have experience dealing with MPEG,
> video players, or anything like that.  All I know is what tivo changed in
> the stream, and I got that part working now... ;)
> 
> I should warn anyone looking at this that it is not sufficient to build by
> itself, it needs the current CVS head of the tivodecode project to link in
> via extralibs and extraincs, and also some hacks to some other files
> (quick check shows cfg-common.h, libmpdemux/Makefile,
> libmpdemux/demuxer.{c,h}
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> 
> 
> int tivo_check_file(demuxer_t* demuxer)
> {
> 	int id = stream_read_dword_le(demuxer->stream);
> 	stream_reset(demuxer->stream);
> 	stream_seek(demuxer->stream, demuxer->movi_start);
> 	if (id == mmioFOURCC('T', 'i', 'V', 'o'))
> 	{
> 		return DEMUXER_TYPE_TIVO;
> 	}
> 	return 0;
> }

too weak and prone to false positives

> 
> demuxer_t* demux_tivo_open(demuxer_t* demuxer)
> {
> 	turing_state *turing;
> 	size_t begin_at;
> 	turing = malloc(sizeof(turing_state));
> 	memset(turing, 0, sizeof(turing_state));
> 	demuxer->priv = (void *)turing;
> 	begin_at = setup_turing_key (turing, demuxer->stream, &mp_stream_read_wrapper, o_mak);
> 	fprintf(stderr, "begin_at = %lx\n", begin_at);
> 	stream_seek (demuxer->stream, begin_at);
> 	if (1)
> 	{
> 		extern int audio_id, video_id, dvdsub_id;
> 		stream_t* s = new_ds_stream(demuxer->video);
> 		demuxer_t* od = demux_open(s, DEMUXER_TYPE_UNKNOWN,
> 				audio_id, video_id, dvdsub_id, NULL);
> 		demuxer = new_demuxers_demuxer(od, od, od);
> 	}
> 	return demuxer;
> }
> 
> int demux_tivo_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds)
> {
> 	off_t pak_start = stream_tell(demuxer->stream);
> 	unsigned int marker;
> 	unsigned char byte;
> 	marker=0xFFFFFFFF;
> 	while (!demuxer->stream->eof)
> 	{
> 		demux_packet_t * dp = new_demux_packet (1);

rather than resizing the packet every time, create it at least 2048 
bytes long

> 		dp->pos = pak_start;
> 		if ((marker & 0xFFFFFF00) == 0x100)
> 		{
> 			int ret;
> 			ret = process_frame(byte, (turing_state *)(demuxer->priv), stream_tell(demuxer->stream), demuxer->stream, &mp_stream_read_wrapper, dp, &mp_packet_add_wrapper);

why do you need stream_tell()?

> 			if (ret == 1)
> 			{
> 				marker = 0xFFFFFFFF;
> 				ds_add_packet(ds, dp);
> 				return 1;
> 			}
> 			else if (ret == 0)
> 			{
> 				mp_packet_add_wrapper(&byte, 1, dp);
> 				ds_add_packet(ds, dp);
> 			}
> 			else if (ret < 0)
> 			{
> 				perror ("processing frame");
> 				return -1;
> 			}
> 		}
> 		else
> 		{
> 			mp_packet_add_wrapper(&byte, 1, dp);
> 			ds_add_packet(ds, dp);
> 		}
> 		marker <<= 8;
> 		if (stream_read(demuxer->stream, &byte, 1) == 0)

byte=stream_read_char(demuxer->stream)

> 		{
> 			fprintf(stderr, "End of File\n");
> 			demuxer->stream->eof = 1;
> 		}
> 		else
> 			marker |= byte;
> 	}
> 	return 0;
> }
> 

The rest looks pretty good


-- 
"Without a frontend, mplayer is useless" - someone in mplayer-users



More information about the MPlayer-dev-eng mailing list