Mailing List Archive

V4L2_CID_MPEG_VIDEO_ASPECT vs. Wide-screen signaling
The pvrinput plugin for vdr reads a PES stream from an mpeg encoder card and
converts it into a Transport stream, which is needed by vdr.

The PES stream should include all available vbi data, because we embedd vbi
into the mpeg stream using

vbifmt.fmt.sliced.service_set = V4L2_SLICED_VBI_625;
vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;

The plugin also sets V4L2_CID_MPEG_VIDEO_ASPECT to a fix value, which results
for example in a 4:3 format.

Since some time I recognize that analogue broadcastings (for example RTL) have
a 16:9 anarmorphic format, so the TV needs to stretch it. Unfortunately the
TV does not detect the anarmorphic format. It seems that the 4:3 setting from
V4L2_CID_MPEG_VIDEO_ASPECT overrides any wss data.

What is the relation between this mpeg control and the wss vbi data? Should I
really change V4L2_CID_MPEG_VIDEO_ASPECT every time the wss data bit
switches?

Furthermore, I am not sure if the PES to TS conversion handles the vbi data
properly. It works for Teletext, but maybe something is missing to make sure
that also the wss vbi data gets inserted into the transport stream.

This is the current code (I shortend it so that it contains only the vbi
stuff):

void cPvrReadThread::PesToTs(uint8_t * Data, uint32_t Length) {
uint8_t stream_id;
bool first = true;
uint32_t i;
const short PayloadSize = TS_SIZE - 4;
uint32_t Payload_Count = Length / PayloadSize;
uint32_t Payload_Rest = Length % PayloadSize;
stream_id = Data[3];
switch (stream_id) {
case 0xBD: {
uint8_t * payload_data;
uint16_t payload_length;
uint32_t pos = 0;
uint32_t ts_pos = 0;
memset(ts_buffer, 0, TS_SIZE);
ts_buffer[0] = TS_SYNC_BYTE;
ts_buffer[1] = kTeletextPid >> 8;
ts_buffer[2] = kTeletextPid & 0xFF;
ts_buffer[3] = 0x10 | text_counter;

payload_length = Length - 9 - Data[8];
payload_data = Data + 9 + Data[8];
if (memcmp(payload_data, "itv0", 4) == 0)
pos = 12;
else
if (memcmp(payload_data, "ITV0", 4) == 0)
pos = 4;
else
return;
while (pos + 43 <= payload_length) {
if ((payload_data[pos] & 0x0F) == 0x01) {
ts_buffer[4+ts_pos*46] = 0x02; // data_unit_id
ts_buffer[5+ts_pos*46] = 0x2C; // data_unit_length
ts_buffer[6+ts_pos*46] = 0x00; // field_parity, line_offset
ts_buffer[7+ts_pos*46] = 0xE4; // framing_code
for (int j = 0; j < 42; j++) {
ts_buffer[8 + ts_pos * 46 + j] = kInvTab[payload_data[pos + 1 +
j]];
}
ts_pos++;
if (ts_pos == 4) {
ts_pos = 0;
PutData(ts_buffer, TS_SIZE);
text_counter = (text_counter + 1) & 15;
memset(ts_buffer, 0, TS_SIZE);
ts_buffer[0] = TS_SYNC_BYTE;
ts_buffer[1] = kTeletextPid >> 8;
ts_buffer[2] = kTeletextPid & 0xFF;
ts_buffer[3] = 0x10 | text_counter;
}
}
pos += 43;
}
if (ts_pos > 0) {
PutData(ts_buffer, TS_SIZE);
text_counter = (text_counter + 1) & 15;
}
break; // end: case 0xBD:
}
} // end: switch (stream_id)
}

Any help is welcome.

Greets,
Martin

_______________________________________________
ivtv-devel mailing list
ivtv-devel@ivtvdriver.org
http://ivtvdriver.org/mailman/listinfo/ivtv-devel
Re: V4L2_CID_MPEG_VIDEO_ASPECT vs. Wide-screen signaling [ In reply to ]
On Sunday 07 June 2009 09:40:14 Martin Dauskardt wrote:
> The pvrinput plugin for vdr reads a PES stream from an mpeg encoder card
> and converts it into a Transport stream, which is needed by vdr.
>
> The PES stream should include all available vbi data, because we embedd
> vbi into the mpeg stream using
>
> vbifmt.fmt.sliced.service_set = V4L2_SLICED_VBI_625;
> vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
>
> The plugin also sets V4L2_CID_MPEG_VIDEO_ASPECT to a fix value, which
> results for example in a 4:3 format.
>
> Since some time I recognize that analogue broadcastings (for example RTL)
> have a 16:9 anarmorphic format, so the TV needs to stretch it.
> Unfortunately the TV does not detect the anarmorphic format. It seems
> that the 4:3 setting from V4L2_CID_MPEG_VIDEO_ASPECT overrides any wss
> data.
>
> What is the relation between this mpeg control and the wss vbi data?

wss tells you what the video looks like: a full 4x3 image, or a letterboxed
image (black bars above and below). In the latter case a 16x9 TV will
remove the bars and only show the actual video. But in both cases the
transmitted frames are still 4x3.

However, if wss signals anamorphic, then the MPEG aspect should be set to
16x9, since that is the actual video aspect ratio.

> Should I really change V4L2_CID_MPEG_VIDEO_ASPECT every time the wss data
> bit switches?

If it goes to anamorphic, then yes. The other formats are still 4x3.

Note that I have never tested this!

> Furthermore, I am not sure if the PES to TS conversion handles the vbi
> data properly. It works for Teletext, but maybe something is missing to
> make sure that also the wss vbi data gets inserted into the transport
> stream.
>
> This is the current code (I shortend it so that it contains only the vbi
> stuff):
>
> void cPvrReadThread::PesToTs(uint8_t * Data, uint32_t Length) {
> uint8_t stream_id;
> bool first = true;
> uint32_t i;
> const short PayloadSize = TS_SIZE - 4;
> uint32_t Payload_Count = Length / PayloadSize;
> uint32_t Payload_Rest = Length % PayloadSize;
> stream_id = Data[3];
> switch (stream_id) {
> case 0xBD: {
> uint8_t * payload_data;
> uint16_t payload_length;
> uint32_t pos = 0;
> uint32_t ts_pos = 0;
> memset(ts_buffer, 0, TS_SIZE);
> ts_buffer[0] = TS_SYNC_BYTE;
> ts_buffer[1] = kTeletextPid >> 8;
> ts_buffer[2] = kTeletextPid & 0xFF;
> ts_buffer[3] = 0x10 | text_counter;
>
> payload_length = Length - 9 - Data[8];
> payload_data = Data + 9 + Data[8];
> if (memcmp(payload_data, "itv0", 4) == 0)
> pos = 12;
> else
> if (memcmp(payload_data, "ITV0", 4) == 0)
> pos = 4;
> else
> return;
> while (pos + 43 <= payload_length) {
> if ((payload_data[pos] & 0x0F) == 0x01) {

This is the teletext type.

> ts_buffer[4+ts_pos*46] = 0x02; // data_unit_id
> ts_buffer[5+ts_pos*46] = 0x2C; // data_unit_length
> ts_buffer[6+ts_pos*46] = 0x00; // field_parity, line_offset
> ts_buffer[7+ts_pos*46] = 0xE4; // framing_code
> for (int j = 0; j < 42; j++) {
> ts_buffer[8 + ts_pos * 46 + j] = kInvTab[payload_data[pos + 1
> + j]];
> }
> ts_pos++;
> if (ts_pos == 4) {
> ts_pos = 0;
> PutData(ts_buffer, TS_SIZE);
> text_counter = (text_counter + 1) & 15;
> memset(ts_buffer, 0, TS_SIZE);
> ts_buffer[0] = TS_SYNC_BYTE;
> ts_buffer[1] = kTeletextPid >> 8;
> ts_buffer[2] = kTeletextPid & 0xFF;
> ts_buffer[3] = 0x10 | text_counter;
> }
> }
> pos += 43;
> }

And it clearly only handles that format and not wss lines since wss lines
have payload type 5.

The test/vbi.c tool in ivtv-utils contains code that shows how to parse the
wss data from the VBI payload. I have no idea how that should be encoded
into the transport stream, though.

> if (ts_pos > 0) {
> PutData(ts_buffer, TS_SIZE);
> text_counter = (text_counter + 1) & 15;
> }
> break; // end: case 0xBD:
> }
> } // end: switch (stream_id)
> }
>
> Any help is welcome.

I hope this helps,

Hans

--
Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom

_______________________________________________
ivtv-devel mailing list
ivtv-devel@ivtvdriver.org
http://ivtvdriver.org/mailman/listinfo/ivtv-devel