[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