On Wed, 12 Jan 2005 09:15 am, Mark Anderson wrote:
I fixed the audio in trandsport.c, unfortunatley I screwed up the video.
Attached is the diff as it stands, anyone see anything obvious causing the
video screw up?
The diff is applied againts the original transport.c and no mpeg.c hack is
needed.
Cheers,
Mark.
> Folks,
>
> After a number of hours starting at hex dumps and trying. to learn a bit
> about mpeg/dvb protocols I have finally found the problem with transport.c,
> unfortunately I haven't been able to craft some code that actually fixes
> it.
>
> The problem: The 9th byte of the mpeg2 data is the header length, in
> australia for AC3 payload this is always set to 7 bytes. The code in
> transport.c only ever puts 4 of the 7 bytes into the transformed stream.
> mpeg.c looks at the header length and makes sure it pulls out that many
> bytes:
>
> The code in mpegps_read_pes_header is:
>
> len -= header_len;
> while (header_len > 0) {
> get_byte(&s->pb);
> header_len--;
> }
>
>
> Because transform has not put the last three bytes of the header in, mpeg.c
> pulls out the wrong bytes and everything goes downhill from there. I have
> confirmed that if transport puts the full 7 bytes in the it all works fine.
>
> I added the following code to write_ipack in transport.c to try to fix
> this:
>
> /*write in the rest of the header as specified by p->hlength*/
> if ((p->cid == PRIVATE_STREAM1) && (p->count == 13))
> {
> while (p->count < (p->hlength + 9))
> {
> p->buf[p->count++] = data[p->count - 13];
> }
> }
>
> This almost does it except there are 3 additonal bytes after the four byte
> streamid/ac3_off header. If I hack mpeg.c to pull the extras out it
> produces perfect audio. The reason the extra three bytes are added due to
> the above code is that it adds the reast of the header, but since
> write_ipack has no way of telling the caller that it has used up some bytes
> out of its source buffer, the bytes are re-added in the next call to
> write_ipack.
>
> Marcus, since you are much more familiar with this code, maybe you could
> work out how to get the proper header bytes added?
>
> Cheers,
> Mark Anderson
--- ../mythtv-bdvb-35.orig/libs/libmythtv/dvbdev/transform.c 2005-01-10 08:59:18.000000000 +1100
+++ libs/libmythtv/dvbdev/transform.c 2005-01-13 09:15:15.340491174 +1100
@@ -40,6 +40,7 @@ static unsigned int bitrates[3][16] =
static uint32_t freq[4] = {441, 480, 320, 0};
+
uint64_t trans_pts_dts(uint8_t *pts)
{
uint64_t wts;
@@ -328,7 +329,6 @@ int get_ac3info(uint8_t *mbuf, int count
int c = 0;
uint8_t frame;
int fr = 0;
-
while ( !found && c < count){
uint8_t *b = mbuf+c;
if ( b[0] == 0x0b && b[1] == 0x77 )
@@ -380,7 +380,6 @@ void send_ipack(ipack *p)
AudioInfo ai;
int nframes= 0;
int f=0;
-
if (p->count < 10) return;
p->buf[3] = p->cid;
p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8);
@@ -390,9 +389,9 @@ void send_ipack(ipack *p)
if (p->cid == PRIVATE_STREAM1){
off = 9+p->buf[8];
+
streamid = p->buf[off];
switch (streamid & 0xF8){
-
case 0x80:
ai.off = 0;
ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]);
@@ -426,7 +425,7 @@ void send_ipack(ipack *p)
p->buf[6] = 0x80;
p->buf[7] = 0x00;
- p->buf[8] = 0x00;
+ p->buf[8] = p->hlength;
p->count = 9;
if (p->cid == PRIVATE_STREAM1){
@@ -440,7 +439,6 @@ void send_ipack(ipack *p)
p->buf[11] = (ac3_off >> 8)& 0xFF;
p->buf[12] = (ac3_off)& 0xFF;
break;
-
case 0x20:
p->count += 2;
p->buf[9] = 0x20;
@@ -464,7 +462,6 @@ static void write_ipack(ipack *p, uint8_
AudioInfo ai;
uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
int diff =0;
-
if (p->count < 6){
if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts))
memcpy(p->last_pts, p->pts, 5);
@@ -479,7 +476,6 @@ static void write_ipack(ipack *p, uint8_
p->size = diff/2;
// fprintf(stderr,"size: %d \n",p->size);
}
-
if (p->cid == PRIVATE_STREAM1 && p->count == p->hlength+9){
switch (p->priv_type){
case PRIV_DVD_AC3:
@@ -490,23 +486,21 @@ static void write_ipack(ipack *p, uint8_
case PRIV_TS_AC3: /* keep this as default */
default:
{
- int ac3_off;
- ac3_off = get_ac3info(data, count, &ai,0);
- if (ac3_off>=0 && ai.framesize){
+ /*
+ add in a dummy 4 byte audio header
+ to match mpeg dvd standard. The values
+ will be filled in later (in send_ipack)
+ when it can work out the ac3_off correctly
+ */
p->buf[p->count] = 0x80;
- p->buf[p->count+1] = (p->size - p->count
- - 4 - ac3_off)/
- ai.framesize + 1;
- p->buf[p->count+2] = (ac3_off >> 8)& 0xFF;
- p->buf[p->count+3] = (ac3_off)& 0xFF;
+ p->buf[p->count+1] = 0;
+ p->buf[p->count+2] = 0;
+ p->buf[p->count+3] = 0;
p->count+=4;
-
- }
}
break;
}
}
-
if (p->count + count < p->size){
memcpy(p->buf+p->count, data, count);
p->count += count;
@@ -518,8 +512,23 @@ static void write_ipack(ipack *p, uint8_
// fprintf(stderr,"count: %d \n",p->count);
send_ipack(p);
if (rest > 0 && count - rest > 0)
+ {
+ if ((p->mpeg == 2) &&
+ (p->flag2 & PTS_ONLY) &&
+ (p->cid == PRIVATE_STREAM1) &&
+ (p->count == 13))
+ {
+ int c = 8;
+ while (p->count < p->hlength + 9)
+ {
+ write_ipack(p, data+rest+c, 1);
+ c++;
+ }
+ rest+=c;
+ }
write_ipack(p, data+rest, count-rest);
}
+ }
}
void instant_repack (uint8_t *buf, int count, ipack *p)
@@ -667,9 +676,18 @@ void instant_repack (uint8_t *buf, int c
c++;
p->found++;
}
+
if (c == count) return;
+ if (p->cid == PRIVATE_STREAM1)
+ {
+ while (p->count < p->hlength + 9)
+ {
+ write_ipack(p, buf+c, 1);
+ c++;
+ p->found++;
+ }
+ }
}
-
while (c < count && p->found < p->plength+6){
l = count -c;
@@ -695,6 +713,7 @@ void instant_repack (uint8_t *buf, int c
}
if (p->plength && p->found == p->plength+6) {
+
send_ipack(p);
reset_ipack(p);
if (c < count)
_______________________________________________
mythtv-dev mailing list
[email protected]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev