[FFmpeg-devel] pts/dts generation and index for mpegts (vob)

Erik Van Grunderbeeck erik
Thu Apr 30 06:05:01 CEST 2009


> its on topic here and welcome
> support of chapter/menu/... is definitly nice
> 
> [...]
> 
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
I got this working: angle handling, menu/button handling, vob transitions,
the whole 9 yards (except for seeking). An added advantage is that with
using libdvdread region encoded disc's can be transcoded/played from ffmpeg
(not eegrrmm that anyone want to do something like that), if libccs is
present. 

I need to figure out a way to send the data back to the client (ege ffplay).


One way is to extend the handler for navigation packets in mpeg.c (code
chunk below). The idea is basically to form a nav block, and build a packet
from that. That packet is pushed into a codec stream (DATA?), and then send
back to the client. The client gets packet, checks the type and does his/her
action. Clients that don't understand/know the stream (-id) will just
discard the packets as before. Note that the mechanism could also be
extended to other container's, ege asf scripts.

For this mpeg-ps case, I would add a string token ("EXTNAVDATA") in the
navigation packet (id 1bf) at the private/reserved data offset at 0x349, and
set the substream id to 0x01. 

I picked the string to be generic enough. It also serves as a data block id
for the data I want to send back.

Question is: would a code extension like this be accepted? If not, anyone
has a better idea? 

(Note that there are some other possible issues too, like skipping enough
data in the beginning for the auto container/codec identifiers to work, or
select a button. They all fall under "how to get data back into the protocol
handler").

Code mode:

    if (startcode == 0x1bf) {	//	private stream 2
        len = get_be16(s->pb);

		//	check for ext at offset 0x349 (we are at 0x2c).
could also check len, 
		//	but that makes a messy if clause
		url_fseek(s->pb, 797, 1);
		uint8_t buf[10];
		//	get data identifier
		get_buffer(s->pb, buf, 10);	
		if(memcmp(buf, "EXTNAVDATA", 10) == 0)
		{
			//	its us, we want len (2), EXTNAVDATA (10) and
(0x349-0x2c) bytes == 785 bytes
			url_fseek(s->pb, -785, 1);
			//	pass through now
		}
		else
		{
			//	seek back, we want EXTNAVDATA (10) and
(0x349-0x2c) bytes == 787 bytes
			url_fseek(s->pb, -787, 1);
		
			//	extra 
			if (!m->sofdec) {
				while (len-- >= 6) {
					if (get_byte(s->pb) == 'S') {
						get_buffer(s->pb, buf, 5);
						m->sofdec = !memcmp(buf,
"ofdec", 5);
						len -= sizeof(buf);
						break;
					}
				}
				m->sofdec -= !m->sofdec;
			}
			url_fskip(s->pb, len);
			goto redo;
		}
    }

Example data send would be

typedef struct {
	uint8		m_Def[10];	//	EXTNAVDATAID
	uint16_t	m_Type;
} ffdvd_io_packet;

typedef struct {
	ffdvd_io_packet	m_Header;
	uint32_t	m_Time;	/* in seconds */ 
} ffdvd_wait_packet;

typedef struct {
	ffdvd_io_packet	m_Header;
	uint16_t	m_X;
	uint16_t	m_Y;
	uint16_t	m_Width;
	uint16_t	m_Height;
} ffdvd_button;

> I do not agree with what you have to say, but I'll defend to the death
> your right to say it. -- Voltaire

Prejudice is opinion without judgement.

Erik




More information about the ffmpeg-devel mailing list