11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dvb_filter.h" 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "av7110_ipack.h" 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> /* for memcpy() */ 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/vmalloc.h> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_ipack_reset(struct ipack *p) 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 0; 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->cid = 0; 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plength = 0; 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag1 = 0; 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag2 = 0; 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength = 0; 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->mpeg = 0; 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = 0; 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 0; 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->done = 0; 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count = 0; 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_ipack_init(struct ipack *p, int size, 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void (*func)(u8 *buf, int size, void *priv)) 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(p->buf = vmalloc(size*sizeof(u8)))) { 2780887a59c255f4a6c348dfc679501b3679d1070fChristophe Lucas printk(KERN_WARNING "Couldn't allocate memory for ipack\n"); 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->size = size; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->func = func; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->repack_subids = 0; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(p); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_ipack_free(struct ipack *p) 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vfree(p->buf); 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void send_ipack(struct ipack *p) 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int off; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_audio_info ai; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ac3_off = 0; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int streamid = 0; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nframes = 0; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int f = 0; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (p->mpeg) { 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->count < 10) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[3] = p->cid; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[5] = (u8)((p->count - 6) & 0x00ff); 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->repack_subids && p->cid == PRIVATE_STREAM1) { 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off = 9 + p->buf[8]; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds streamid = p->buf[off]; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((streamid & 0xf8) == 0x80) { 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ai.off = 0; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ac3_off = ((p->buf[off + 2] << 8)| 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[off + 3]); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ac3_off < p->count) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count - ac3_off, &ai, 0); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!f) { 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nframes = (p->count - off - 3 - ac3_off) / 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ai.framesize + 1; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[off + 2] = (ac3_off >> 8) & 0xff; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[off + 3] = (ac3_off) & 0xff; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[off + 1] = nframes; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ac3_off += nframes * ai.framesize - p->count; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->func(p->buf, p->count, p->data); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[6] = 0x80; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[7] = 0x00; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[8] = 0x00; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count = 9; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->repack_subids && p->cid == PRIVATE_STREAM1 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (streamid & 0xf8) == 0x80) { 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count += 4; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[9] = streamid; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[10] = (ac3_off >> 8) & 0xff; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[11] = (ac3_off) & 0xff; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[12] = 0; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->count < 8) 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[3] = p->cid; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[5] = (u8)((p->count - 6) & 0x00ff); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->func(p->buf, p->count, p->data); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->buf[6] = 0x0f; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count = 7; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid av7110_ipack_flush(struct ipack *p) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6) 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plength = p->found - 6; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 0; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_ipack(p); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(p); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_ipack(struct ipack *p, const u8 *data, int count) 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 headr[3] = { 0x00, 0x00, 0x01 }; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->count < 6) { 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->buf, headr, 3); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count = 6; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->count + count < p->size){ 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->buf+p->count, data, count); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count += count; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rest = p->size - p->count; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(p->buf+p->count, data, rest); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->count += rest; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_ipack(p); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count - rest > 0) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, data + rest, count - rest); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p) 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int l; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < count && (p->mpeg == 0 || 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (p->mpeg == 1 && p->found < 7) || 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (p->mpeg == 2 && p->found < 9)) 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (p->found < 5 || !p->done)) { 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (p->found) { 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x00) 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 0; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf[c] == 0x01) 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (buf[c] == 0) 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 2; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 0; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->cid = 0; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (buf[c]) { 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_MAP: 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM2: 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PROG_STREAM_DIR: 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ECM_STREAM : 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EMM_STREAM : 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PADDING_STREAM : 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DSM_CC_STREAM : 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ISO13522_STREAM: 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->done = 1; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fall through */ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->cid = buf[c]; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = 0; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count-c > 1) { 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plen[0] = buf[c]; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plen[1] = buf[c]; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found += 2; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plength = (p->plen[0] << 8) | p->plen[1]; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plen[0] = buf[c]; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 5: 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plen[1] = buf[c]; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plength = (p->plen[0] << 8) | p->plen[1]; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 6: 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!p->done) { 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag1 = buf[c]; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->flag1 & 0xc0) == 0x80) 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->mpeg = 2; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength = 0; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 0; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->mpeg = 1; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag2 = 0; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 7: 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!p->done && p->mpeg == 2) { 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag2 = buf[c]; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!p->done && p->mpeg == 2) { 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength = buf[c]; 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!p->plength) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->plength = MMAX_PLENGTH - 6; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->done || ((p->mpeg == 2 && p->found >= 9) || 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (p->mpeg == 1 && p->found >= 7))) { 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (p->cid) { 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case AUDIO_STREAM_S ... AUDIO_STREAM_E: 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case VIDEO_STREAM_S ... VIDEO_STREAM_E: 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case PRIVATE_STREAM1: 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->mpeg == 2 && p->found == 9) { 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, &p->flag1, 1); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, &p->flag2, 1); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, &p->hlength, 1); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->mpeg == 1 && p->found == 7) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, &p->flag1, 1); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found < 14) { 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < count && p->found < 14) { 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pts[p->found - 9] = buf[c]; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->mpeg == 1 && p->which < 2000) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->found == 7) { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = p->flag1; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength = 1; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!p->which && c < count && 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check == 0xff){ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = buf[c]; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->check & 0xc0) == 0x40 && !p->which) { 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = buf[c]; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 1; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = buf[c]; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 2; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->which == 1) { 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->check = buf[c]; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 2; 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->check & 0x30) && p->check != 0xff) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->flag2 = (p->check & 0xf0) << 2; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pts[0] = p->check; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 3; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->which > 2){ 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) { 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < count && p->which < 7) { 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pts[p->which - 2] = buf[c]; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which++; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) { 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < count && p->which < 12) { 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->which < 7) 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->pts[p->which - 2] = buf[c]; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, 1); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c++; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found++; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which++; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->hlength++; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == count) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->which = 2000; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c < count && p->found < p->plength + 6) { 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = count - c; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l + p->found > p->plength + 6) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l = p->plength + 6 - p->found; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_ipack(p, buf + c, l); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found += l; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += l; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->done) { 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->found + count - c < p->plength + 6) { 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found += count - c; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = count; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c += p->plength + 6 - p->found; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->found = p->plength + 6; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p->plength && p->found == p->plength + 6) { 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_ipack(p); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_reset(p); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c < count) 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds av7110_ipack_instant_repack(buf + c, count - c, p); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 404