psparser.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. /*
  2. * AMLOGIC Audio/Video streaming port driver.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the named License,
  7. * or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  17. *
  18. * Author: Tim Yao <timyao@amlogic.com>
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/types.h>
  23. #include <linux/errno.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/wait.h>
  26. #include <linux/sched.h>
  27. #include <linux/fs.h>
  28. #include <linux/slab.h>
  29. #include <linux/amports/ptsserv.h>
  30. #include <linux/amports/amstream.h>
  31. #include <asm/uaccess.h>
  32. #include <mach/am_regs.h>
  33. #include "vdec_reg.h"
  34. #include "streambuf_reg.h"
  35. #include "streambuf.h"
  36. #include "psparser.h"
  37. #define TIMESTAMP_IONLY 1
  38. #define SAVE_SCR 0
  39. #define MPEG_START_CODE_PATTERN (0x00000100L)
  40. #define MPEG_START_CODE_MASK (0xffffff00L)
  41. #define MAX_MPG_AUDIOPK_SIZE 0x1000
  42. #define SUB_INSERT_START_CODE_HIGH 0x414d4c55
  43. #define SUB_INSERT_START_CODE_LOW 0xaa000000
  44. #define PARSER_WRITE (ES_WRITE | ES_PARSER_START)
  45. #define PARSER_VIDEO (ES_TYPE_VIDEO)
  46. #define PARSER_AUDIO (ES_TYPE_AUDIO)
  47. #define PARSER_SUBPIC (ES_TYPE_SUBTITLE)
  48. #define PARSER_PASSTHROUGH (ES_PASSTHROUGH | ES_PARSER_START)
  49. #define PARSER_AUTOSEARCH (ES_SEARCH | ES_PARSER_START)
  50. #define PARSER_DISCARD (ES_DISCARD | ES_PARSER_START)
  51. #define PARSER_BUSY (ES_PARSER_BUSY)
  52. #define PARSER_PARAMETER_LENGTH_BIT 16
  53. #define PARSER_POP READ_MPEG_REG(PFIFO_DATA)
  54. #define SET_BLOCK(size) \
  55. WRITE_MPEG_REG_BITS(PARSER_CONTROL, size, ES_PACK_SIZE_BIT, ES_PACK_SIZE_WID)
  56. #define SET_DISCARD_SIZE(size) WRITE_MPEG_REG(PARSER_PARAMETER, size)
  57. enum {
  58. SEARCH_START_CODE = 0,
  59. SEND_VIDEO_SEARCH,
  60. SEND_AUDIO_SEARCH,
  61. SEND_SUBPIC_SEARCH,
  62. DISCARD_SEARCH,
  63. DISCARD_ONLY
  64. };
  65. enum {
  66. AUDIO_FIRST_ACCESS_ARM = 0,
  67. AUDIO_FIRST_ACCESS_POPING,
  68. AUDIO_FIRST_ACCESS_DONE
  69. };
  70. const static char psparser_id[] = "psparser-id";
  71. static DECLARE_WAIT_QUEUE_HEAD(wq);
  72. static struct tasklet_struct psparser_tasklet;
  73. static u32 fetch_done;
  74. static u8 audio_id, video_id, sub_id, sub_id_max;
  75. static u32 audio_first_access;
  76. static u32 packet_remaining;
  77. static u32 video_data_parsed;
  78. static u32 audio_data_parsed;
  79. static u32 pts_equ_dts_flag;
  80. static unsigned first_apts, first_vpts;
  81. static unsigned audio_got_first_pts, video_got_first_dts, sub_got_first_pts;
  82. atomic_t sub_block_found = ATOMIC_INIT(0);
  83. #define DEBUG_VOB_SUB
  84. #ifdef DEBUG_VOB_SUB
  85. static u8 sub_found_num;
  86. static struct subtitle_info *sub_info[MAX_SUB_NUM];
  87. #endif
  88. static bool ptsmgr_first_vpts_ready(void)
  89. {
  90. return (video_got_first_dts != 0);
  91. }
  92. static bool ptsmgr_first_apts_ready(void)
  93. {
  94. return (audio_got_first_pts != 0);
  95. }
  96. static void ptsmgr_vpts_checkin(u32 pts)
  97. {
  98. if (video_got_first_dts == 0) {
  99. video_got_first_dts = 1;
  100. first_vpts = pts;
  101. }
  102. // vpts_checkin(pts);
  103. pts_checkin_offset(PTS_TYPE_VIDEO, video_data_parsed, pts);
  104. }
  105. static void ptsmgr_apts_checkin(u32 pts)
  106. {
  107. if (audio_got_first_pts == 0) {
  108. audio_got_first_pts = 1;
  109. first_apts = pts;
  110. }
  111. // apts_checkin(pts);
  112. pts_checkin_offset(PTS_TYPE_AUDIO, audio_data_parsed, pts);
  113. }
  114. static u32 parser_process(s32 type, s32 packet_len)
  115. {
  116. s16 temp, header_len, misc_flags, i;
  117. u32 pts = 0, dts = 0;
  118. u32 pts_dts_flag = 0;
  119. temp = PARSER_POP;
  120. packet_len--;
  121. if ((temp >> 6) == 0x02) {
  122. /* mpeg-2 system */
  123. misc_flags = PARSER_POP;
  124. header_len = PARSER_POP;
  125. packet_len -= 2;
  126. packet_len -= header_len;
  127. if ((misc_flags >> 6) > 1) {
  128. /* PTS exist */
  129. pts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */
  130. pts |= PARSER_POP << 22; /* bit 29-22 */
  131. pts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */
  132. pts |= (PARSER_POP << 7); /* bit 14-07 */
  133. pts |= (PARSER_POP >> 1); /* bit 06-00 */
  134. header_len -= 5;
  135. pts_dts_flag |= 2;
  136. }
  137. if ((misc_flags >> 6) > 2) {
  138. /* DTS exist */
  139. dts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */
  140. dts |= PARSER_POP << 22; /* bit 29-22 */
  141. dts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */
  142. dts |= (PARSER_POP << 7); /* bit 14-07 */
  143. dts |= (PARSER_POP >> 1); /* bit 06-00 */
  144. header_len -= 5;
  145. pts_dts_flag |= 1;
  146. }
  147. if (misc_flags & 0x20) {
  148. /* ESCR_flag */
  149. PARSER_POP;
  150. PARSER_POP;
  151. PARSER_POP;
  152. PARSER_POP;
  153. PARSER_POP;
  154. PARSER_POP;
  155. header_len -= 5;
  156. }
  157. if (misc_flags & 0x10) {
  158. /* ES_rate_flag */
  159. PARSER_POP;
  160. PARSER_POP;
  161. PARSER_POP;
  162. header_len -= 3;
  163. }
  164. if (misc_flags & 0x08) {
  165. /* DSM_trick_mode_flag */
  166. PARSER_POP;
  167. header_len -= 1;
  168. }
  169. if (misc_flags & 0x04) {
  170. /* additional_copy_info_flag */
  171. PARSER_POP;
  172. header_len -= 1;
  173. }
  174. if (misc_flags & 0x02) {
  175. /* PES_CRC_flag */
  176. PARSER_POP;
  177. PARSER_POP;
  178. header_len -= 2;
  179. }
  180. if (misc_flags & 0x01) {
  181. /* PES_extension_flag */
  182. misc_flags = PARSER_POP;
  183. header_len--;
  184. if (misc_flags & 0x80) {
  185. /* PES_private_data_flag */
  186. for (i = 0; i < 128; i++) {
  187. PARSER_POP;
  188. }
  189. header_len -= 128;
  190. }
  191. #if 0
  192. if (misc_flags & 0x40) {
  193. /* pack_header_field_flag */
  194. /* Invalid case */
  195. }
  196. #endif
  197. if (misc_flags & 0x20) {
  198. /* program_packet_sequence_counter_flag */
  199. PARSER_POP;
  200. PARSER_POP;
  201. header_len -= 2;
  202. }
  203. if (misc_flags & 0x10) {
  204. /* PSTD_buffer_flag */
  205. PARSER_POP;
  206. PARSER_POP;
  207. header_len -= 2;
  208. }
  209. if (misc_flags & 1) {
  210. /* PES_extension_flag_2 */
  211. temp = PARSER_POP & 0x7f;
  212. while (temp) {
  213. PARSER_POP;
  214. temp--;
  215. header_len--;
  216. }
  217. }
  218. while (header_len) {
  219. PARSER_POP;
  220. header_len--;
  221. }
  222. }
  223. while (header_len) {
  224. PARSER_POP;
  225. header_len--;
  226. }
  227. } else {
  228. /* mpeg-1 system */
  229. while (temp == 0xff) {
  230. temp = PARSER_POP;
  231. packet_len--;
  232. }
  233. if ((temp >> 6) == 1) {
  234. PARSER_POP; /* STD buffer size */
  235. temp = PARSER_POP;
  236. packet_len -= 2;
  237. }
  238. if (((temp >> 4) == 2) || ((temp >> 4) == 3)) {
  239. pts = ((temp >> 1) & 7) << 30; /* bit 32-30 */
  240. pts |= PARSER_POP << 22; /* bit 29-22 */
  241. pts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */
  242. pts |= (PARSER_POP << 7); /* bit 14-07 */
  243. pts |= (PARSER_POP >> 1); /* bit 06-00 */
  244. packet_len -= 4;
  245. pts_dts_flag |= 2;
  246. }
  247. if ((temp >> 4) == 3) {
  248. dts = ((PARSER_POP >> 1) & 7) << 30; /* bit 32-30 */
  249. dts |= PARSER_POP << 22; /* bit 29-22 */
  250. dts |= (PARSER_POP >> 1) << 15; /* bit 21-15 */
  251. dts |= (PARSER_POP << 7); /* bit 14-07 */
  252. dts |= (PARSER_POP >> 1); /* bit 06-00 */
  253. packet_len -= 5;
  254. pts_dts_flag |= 1;
  255. }
  256. }
  257. if (!packet_len) {
  258. return SEARCH_START_CODE;
  259. } else if (type == 0) {
  260. if (pts_dts_flag) {
  261. #if TIMESTAMP_IONLY
  262. if (!ptsmgr_first_vpts_ready()) {
  263. if (pts_dts_flag & 2) {
  264. ptsmgr_vpts_checkin(pts);
  265. } else {
  266. ptsmgr_vpts_checkin(dts);
  267. }
  268. } else if ((pts_dts_flag & 3) == 3) {
  269. if (pts_equ_dts_flag) {
  270. if (dts == pts) {
  271. ptsmgr_vpts_checkin(pts);
  272. }
  273. }
  274. else {
  275. if (dts == pts) {
  276. pts_equ_dts_flag = 1;
  277. }
  278. ptsmgr_vpts_checkin(pts);
  279. }
  280. }
  281. #else
  282. if (!ptsmgr_first_vpts_ready()) {
  283. if (pts_dts_flag & 2) {
  284. ptsmgr_vpts_checkin(pts);
  285. } else {
  286. ptsmgr_vpts_checkin(dts);
  287. }
  288. } else if (pts_dts_flag & 2) {
  289. ptsmgr_vpts_checkin(pts);
  290. }
  291. #endif
  292. }
  293. if (ptsmgr_first_vpts_ready()) {
  294. SET_BLOCK(packet_len);
  295. video_data_parsed += packet_len;
  296. return SEND_VIDEO_SEARCH;
  297. } else {
  298. SET_DISCARD_SIZE(packet_len);
  299. return DISCARD_SEARCH;
  300. }
  301. } else if (type == 1) {
  302. /* mpeg audio */
  303. if (pts_dts_flag & 2) {
  304. ptsmgr_apts_checkin(pts);
  305. }
  306. if (ptsmgr_first_apts_ready()) {
  307. SET_BLOCK(packet_len);
  308. audio_data_parsed += packet_len;
  309. return SEND_AUDIO_SEARCH;
  310. } else {
  311. SET_DISCARD_SIZE(packet_len);
  312. return DISCARD_SEARCH;
  313. }
  314. } else if (type == 2) {
  315. /* Private stream */
  316. temp = PARSER_POP; /* sub_stream_id */
  317. packet_len--;
  318. if (((temp & 0xf8) == 0xa0) && (temp == audio_id)) {
  319. /* DVD_VIDEO Audio LPCM data */
  320. PARSER_POP;
  321. temp = (PARSER_POP << 8) | PARSER_POP;
  322. if(temp == 0) {
  323. temp = 4;
  324. }
  325. temp--;
  326. packet_len -= 3;
  327. if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) {
  328. if (temp) {
  329. packet_remaining = packet_len - temp;
  330. SET_DISCARD_SIZE(temp);
  331. audio_first_access = AUDIO_FIRST_ACCESS_POPING;
  332. return DISCARD_ONLY;
  333. }
  334. audio_first_access = AUDIO_FIRST_ACCESS_DONE;
  335. if (packet_len) {
  336. SET_BLOCK(packet_len);
  337. audio_data_parsed += packet_len;
  338. return SEND_AUDIO_SEARCH;
  339. } else {
  340. return SEARCH_START_CODE;
  341. }
  342. } else {
  343. PARSER_POP;
  344. PARSER_POP;
  345. PARSER_POP;
  346. packet_len -= 3;
  347. }
  348. if (pts_dts_flag & 2) {
  349. ptsmgr_apts_checkin(pts);
  350. }
  351. if (ptsmgr_first_apts_ready()) {
  352. SET_BLOCK(packet_len);
  353. audio_data_parsed += packet_len;
  354. return SEND_AUDIO_SEARCH;
  355. } else {
  356. SET_DISCARD_SIZE(packet_len);
  357. return DISCARD_SEARCH;
  358. }
  359. } else if (((temp & 0xf8) == 0x80) && (temp == audio_id)) {
  360. /* Audio AC3 data */
  361. PARSER_POP;
  362. temp = (PARSER_POP << 8) | PARSER_POP;
  363. packet_len -= 3;
  364. if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) {
  365. if (pts_dts_flag & 2) {
  366. ptsmgr_apts_checkin(pts);
  367. }
  368. if ((temp > 2) && (packet_len > (temp - 2))) {
  369. temp -= 2;
  370. packet_remaining = packet_len - temp;
  371. SET_DISCARD_SIZE(temp);
  372. audio_first_access = AUDIO_FIRST_ACCESS_POPING;
  373. return DISCARD_ONLY;
  374. }
  375. audio_first_access = AUDIO_FIRST_ACCESS_DONE;
  376. if (packet_len) {
  377. SET_BLOCK(packet_len);
  378. audio_data_parsed += packet_len;
  379. return SEND_AUDIO_SEARCH;
  380. } else {
  381. return SEARCH_START_CODE;
  382. }
  383. }
  384. if (pts_dts_flag & 2) {
  385. ptsmgr_apts_checkin(pts);
  386. }
  387. if (ptsmgr_first_apts_ready()) {
  388. SET_BLOCK(packet_len);
  389. audio_data_parsed += packet_len;
  390. return SEND_AUDIO_SEARCH;
  391. } else {
  392. SET_DISCARD_SIZE(packet_len);
  393. return DISCARD_SEARCH;
  394. }
  395. } else if (((temp & 0xf8) == 0x88) && (temp == audio_id)) {
  396. /* Audio DTS data */
  397. PARSER_POP;
  398. PARSER_POP;
  399. PARSER_POP;
  400. packet_len -= 3;
  401. if (audio_first_access == AUDIO_FIRST_ACCESS_ARM) {
  402. audio_first_access = AUDIO_FIRST_ACCESS_DONE;
  403. }
  404. if (pts_dts_flag & 2) {
  405. ptsmgr_apts_checkin(pts);
  406. }
  407. if (ptsmgr_first_apts_ready()) {
  408. SET_BLOCK(packet_len);
  409. audio_data_parsed += packet_len;
  410. return SEND_AUDIO_SEARCH;
  411. } else {
  412. SET_DISCARD_SIZE(packet_len);
  413. return DISCARD_SEARCH;
  414. }
  415. } else if ((temp & 0xe0) == 0x20) {
  416. if (temp > sub_id_max) {
  417. sub_id_max = temp;
  418. }
  419. #ifdef DEBUG_VOB_SUB
  420. for (i = 0; i < sub_found_num; i ++) {
  421. if(!sub_info[i])
  422. break;
  423. if(temp == sub_info[i]->id)
  424. break;
  425. }
  426. if (i == sub_found_num && i < MAX_SUB_NUM) {
  427. if (sub_info[sub_found_num]) {
  428. sub_info[sub_found_num]->id = temp;
  429. sub_found_num ++;
  430. printk("[psparser_process]found new sub_id=0x%x (num %d)\n", temp, sub_found_num);
  431. } else {
  432. printk("[psparser_process]sub info NULL!\n");
  433. }
  434. }
  435. #endif
  436. if (temp == sub_id) {
  437. /* DVD sub-picture data */
  438. if (!packet_len) {
  439. return SEARCH_START_CODE;
  440. } else {
  441. #if 0
  442. if (pts_dts_flag & 2) {
  443. ptsmgr_spts_checkin(pts);
  444. }
  445. if (ptsmgr_first_spts_ready()) {
  446. SET_BLOCK(packet_len);
  447. return SEND_SUBPIC_SEARCH;
  448. } else {
  449. SET_DISCARD_SIZE(packet_len);
  450. return DISCARD_SEARCH;
  451. }
  452. #else
  453. if (pts_dts_flag & 2) {
  454. sub_got_first_pts = 1;
  455. }
  456. if (sub_got_first_pts) {
  457. printk("sub pts 0x%x, len %d\n", pts, packet_len);
  458. SET_BLOCK(packet_len);
  459. WRITE_MPEG_REG(PARSER_PARAMETER, 16 << PARSER_PARAMETER_LENGTH_BIT);
  460. WRITE_MPEG_REG(PARSER_INSERT_DATA, SUB_INSERT_START_CODE_HIGH);
  461. WRITE_MPEG_REG(PARSER_INSERT_DATA, SUB_INSERT_START_CODE_LOW | get_sub_type());
  462. WRITE_MPEG_REG(PARSER_INSERT_DATA, packet_len);
  463. WRITE_MPEG_REG(PARSER_INSERT_DATA, pts);
  464. atomic_set(&sub_block_found, 1);
  465. return SEND_SUBPIC_SEARCH;
  466. } else {
  467. SET_DISCARD_SIZE(packet_len);
  468. return DISCARD_SEARCH;
  469. }
  470. #endif
  471. }
  472. } else {
  473. SET_DISCARD_SIZE(packet_len);
  474. return DISCARD_SEARCH;
  475. }
  476. } else {
  477. SET_DISCARD_SIZE(packet_len);
  478. return DISCARD_SEARCH;
  479. }
  480. if (!packet_len) {
  481. return SEARCH_START_CODE;
  482. } else {
  483. SET_BLOCK(packet_len);
  484. audio_data_parsed += packet_len;
  485. return SEND_AUDIO_SEARCH;
  486. }
  487. }
  488. return SEARCH_START_CODE;
  489. }
  490. static void on_start_code_found(int start_code)
  491. {
  492. unsigned short packet_len;
  493. unsigned short temp;
  494. unsigned next_action;
  495. #if SAVE_SCR
  496. unsigned scr;
  497. #endif
  498. if (atomic_read(&sub_block_found)) {
  499. wakeup_sub_poll();
  500. atomic_set(&sub_block_found, 0);
  501. }
  502. if (audio_first_access == AUDIO_FIRST_ACCESS_POPING) {
  503. /* we are in the procedure of poping data for audio first access, continue with last packet */
  504. audio_first_access = AUDIO_FIRST_ACCESS_DONE;
  505. if (packet_remaining) {
  506. next_action = SEND_AUDIO_SEARCH;
  507. SET_BLOCK(packet_remaining);
  508. } else {
  509. next_action = SEARCH_START_CODE;
  510. }
  511. } else if (start_code == 0xba) { /* PACK_START_CODE */
  512. temp = PARSER_POP;
  513. if ((temp >> 6) == 0x01) {
  514. #if SAVE_SCR
  515. scr = ((temp >> 3) & 0x3) << 30; /* bit 31-30 */
  516. scr |= (temp & 0x3) << 28; /* bit 29-28 */
  517. scr |= (PARSER_POP) << 20; /* bit 27-20 */
  518. temp = PARSER_POP;
  519. scr |= (temp >> 4) << 16; /* bit 19-16 */
  520. scr |= (temp & 7) << 13; /* bit 15-13 */
  521. scr |= (PARSER_POP) << 5; /* bit 12-05 */
  522. scr |= (PARSER_POP) >> 3; /* bit 04-00 */
  523. #else
  524. PARSER_POP;
  525. PARSER_POP;
  526. PARSER_POP;
  527. PARSER_POP;
  528. #endif
  529. PARSER_POP;
  530. PARSER_POP;
  531. PARSER_POP;
  532. PARSER_POP;
  533. temp = PARSER_POP & 7;
  534. while (temp) { /* stuff byte */
  535. PARSER_POP;
  536. temp--;
  537. }
  538. } else {
  539. /* mpeg-1 Pack Header */
  540. #if SAVE_SCR
  541. scr = ((temp >> 1) & 0x3) << 30; /* bit 31-30 */
  542. scr |= (PARSER_POP) << 22; /* bit 29-22 */
  543. scr |= (PARSER_POP >> 1) << 15; /* bit 21-15 */
  544. scr |= (PARSER_POP) << 7; /* bit 14-07 */
  545. scr |= (PARSER_POP >> 1); /* bit 06-00 */
  546. #else
  547. PARSER_POP;
  548. PARSER_POP;
  549. PARSER_POP;
  550. PARSER_POP;
  551. #endif
  552. }
  553. next_action = SEARCH_START_CODE;
  554. } else {
  555. packet_len = (PARSER_POP << 8) | PARSER_POP;
  556. if (start_code == video_id) {
  557. next_action = parser_process(0, packet_len);
  558. } else if (start_code == audio_id) {
  559. /* add mpeg audio packet length check */
  560. if (packet_len > MAX_MPG_AUDIOPK_SIZE) {
  561. next_action = SEARCH_START_CODE;
  562. } else {
  563. next_action = parser_process(1, packet_len);
  564. }
  565. } else if (start_code == 0xbb) {
  566. SET_DISCARD_SIZE(packet_len);
  567. next_action = DISCARD_SEARCH;
  568. } else if (start_code == 0xbd) {
  569. next_action = parser_process(2, packet_len);
  570. } else if (start_code == 0xbf) {
  571. SET_DISCARD_SIZE(packet_len);
  572. next_action = DISCARD_SEARCH;
  573. } else if ((start_code < 0xc0) || (start_code > 0xc8)) {
  574. next_action = SEARCH_START_CODE;
  575. } else if (packet_len) {
  576. SET_DISCARD_SIZE(packet_len);
  577. next_action = DISCARD_SEARCH;
  578. } else {
  579. next_action = SEARCH_START_CODE;
  580. }
  581. }
  582. switch (next_action) {
  583. case SEARCH_START_CODE:
  584. WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH);
  585. break;
  586. case SEND_VIDEO_SEARCH:
  587. WRITE_MPEG_REG_BITS(PARSER_CONTROL, PARSER_AUTOSEARCH | PARSER_VIDEO | PARSER_WRITE, ES_CTRL_BIT, ES_CTRL_WID);
  588. break;
  589. case SEND_AUDIO_SEARCH:
  590. WRITE_MPEG_REG_BITS(PARSER_CONTROL, PARSER_AUTOSEARCH | PARSER_AUDIO | PARSER_WRITE, ES_CTRL_BIT, ES_CTRL_WID);
  591. break;
  592. case SEND_SUBPIC_SEARCH:
  593. WRITE_MPEG_REG_BITS(PARSER_CONTROL, PARSER_AUTOSEARCH | PARSER_SUBPIC | PARSER_WRITE | ES_INSERT_BEFORE_ES_WRITE, ES_CTRL_BIT, ES_CTRL_WID);
  594. break;
  595. case DISCARD_SEARCH:
  596. WRITE_MPEG_REG_BITS(PARSER_CONTROL, PARSER_AUTOSEARCH | PARSER_DISCARD, ES_CTRL_BIT, ES_CTRL_WID);
  597. break;
  598. case DISCARD_ONLY:
  599. WRITE_MPEG_REG_BITS(PARSER_CONTROL, PARSER_DISCARD, ES_CTRL_BIT, ES_CTRL_WID);
  600. break;
  601. }
  602. }
  603. static void parser_tasklet(ulong data)
  604. {
  605. s32 sc;
  606. u32 int_status = READ_MPEG_REG(PARSER_INT_STATUS);
  607. WRITE_MPEG_REG(PARSER_INT_STATUS, int_status);
  608. if (int_status & PARSER_INTSTAT_FETCH_CMD) {
  609. fetch_done = 1;
  610. wake_up_interruptible(&wq);
  611. }
  612. if (int_status & PARSER_INTSTAT_SC_FOUND) {
  613. sc = PARSER_POP;
  614. on_start_code_found(sc);
  615. } else if (int_status & PARSER_INTSTAT_DISCARD) {
  616. on_start_code_found(0);
  617. }
  618. }
  619. static irqreturn_t parser_isr(int irq, void *dev_id)
  620. {
  621. tasklet_schedule(&psparser_tasklet);
  622. return IRQ_HANDLED;
  623. }
  624. static ssize_t _psparser_write(const char __user *buf, size_t count)
  625. {
  626. size_t r = count;
  627. const char __user *p = buf;
  628. u32 len;
  629. int ret;
  630. if (r > 0) {
  631. len = min(r, (size_t)FETCHBUF_SIZE);
  632. if (copy_from_user(fetchbuf_remap, p, len)) {
  633. return -EFAULT;
  634. }
  635. fetch_done = 0;
  636. wmb();
  637. WRITE_MPEG_REG(PARSER_FETCH_ADDR, fetchbuf);
  638. WRITE_MPEG_REG(PARSER_FETCH_CMD,
  639. (7 << FETCH_ENDIAN) | len);
  640. ret = wait_event_interruptible_timeout(wq, fetch_done != 0, HZ/10);
  641. if (ret == 0) {
  642. WRITE_MPEG_REG(PARSER_FETCH_CMD, 0);
  643. printk("write timeout, retry\n");
  644. return -EAGAIN;
  645. } else if (ret < 0) {
  646. return -ERESTARTSYS;
  647. }
  648. p += len;
  649. r -= len;
  650. }
  651. return count - r;
  652. }
  653. #ifdef CONFIG_AM_DVB
  654. extern int tsdemux_set_reset_flag(void);
  655. #endif
  656. s32 psparser_init(u32 vid, u32 aid, u32 sid)
  657. {
  658. s32 r;
  659. u32 parser_sub_start_ptr;
  660. u32 parser_sub_end_ptr;
  661. u32 parser_sub_rp;
  662. #ifdef DEBUG_VOB_SUB
  663. u8 i;
  664. for(i = 0; i < MAX_SUB_NUM; i ++) {
  665. sub_info[i] = kzalloc(sizeof(struct subtitle_info), GFP_KERNEL);
  666. if (!sub_info[i]) {
  667. printk("[psparser_init]alloc for subtitle info failed\n");
  668. } else {
  669. sub_info[i]->id = -1;
  670. }
  671. }
  672. sub_found_num = 0;
  673. #endif
  674. parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
  675. parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
  676. parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP);
  677. video_id = vid;
  678. audio_id = aid;
  679. sub_id = sid;
  680. audio_got_first_pts = 0;
  681. video_got_first_dts = 0;
  682. sub_got_first_pts = 0;
  683. first_apts = 0;
  684. first_vpts = 0;
  685. pts_equ_dts_flag = 0;
  686. printk("video 0x%x, audio 0x%x, sub 0x%x\n", video_id, audio_id, sub_id);
  687. if (fetchbuf == 0) {
  688. printk("%s: no fetchbuf\n", __FUNCTION__);
  689. return -ENOMEM;
  690. }
  691. WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER);
  692. /* TS data path */
  693. #ifndef CONFIG_AM_DVB
  694. WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0);
  695. #else
  696. tsdemux_set_reset_flag();
  697. #endif
  698. CLEAR_MPEG_REG_MASK(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE);
  699. CLEAR_MPEG_REG_MASK(TS_HIU_CTL_2, 1 << USE_HI_BSF_INTERFACE);
  700. CLEAR_MPEG_REG_MASK(TS_HIU_CTL_3, 1 << USE_HI_BSF_INTERFACE);
  701. CLEAR_MPEG_REG_MASK(TS_FILE_CONFIG, (1 << TS_HIU_ENABLE));
  702. /* hook stream buffer with PARSER */
  703. WRITE_MPEG_REG(PARSER_VIDEO_START_PTR,
  704. READ_VREG(VLD_MEM_VIFIFO_START_PTR));
  705. WRITE_MPEG_REG(PARSER_VIDEO_END_PTR,
  706. READ_VREG(VLD_MEM_VIFIFO_END_PTR));
  707. CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);
  708. WRITE_MPEG_REG(PARSER_AUDIO_START_PTR,
  709. READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
  710. WRITE_MPEG_REG(PARSER_AUDIO_END_PTR,
  711. READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR));
  712. CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);
  713. WRITE_MPEG_REG(PARSER_CONFIG,
  714. (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
  715. (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
  716. (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));
  717. WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  718. CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  719. WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  720. CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  721. WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
  722. WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
  723. WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr);
  724. WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr);
  725. SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);
  726. WRITE_MPEG_REG(PFIFO_RD_PTR, 0);
  727. WRITE_MPEG_REG(PFIFO_WR_PTR, 0);
  728. WRITE_MPEG_REG(PARSER_SEARCH_PATTERN, MPEG_START_CODE_PATTERN);
  729. WRITE_MPEG_REG(PARSER_SEARCH_MASK, MPEG_START_CODE_MASK);
  730. WRITE_MPEG_REG(PARSER_CONFIG,
  731. (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
  732. (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
  733. PS_CFG_STARTCODE_WID_24 |
  734. PS_CFG_PFIFO_ACCESS_WID_8 | /* single byte pop */
  735. (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));
  736. WRITE_MPEG_REG(PARSER_CONTROL, PARSER_AUTOSEARCH);
  737. tasklet_init(&psparser_tasklet, parser_tasklet, 0);
  738. if ((r = pts_start(PTS_TYPE_VIDEO)) < 0) {
  739. goto Err_1;
  740. }
  741. if ((r = pts_start(PTS_TYPE_AUDIO)) < 0) {
  742. goto Err_2;
  743. }
  744. video_data_parsed = 0;
  745. audio_data_parsed = 0;
  746. r = request_irq(INT_PARSER, parser_isr,
  747. IRQF_SHARED, "psparser", (void *)psparser_id);
  748. if (r) {
  749. printk("PS Demux irq register failed.\n");
  750. r = -ENOENT;
  751. goto Err_3;
  752. }
  753. WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff);
  754. WRITE_MPEG_REG(PARSER_INT_ENABLE,
  755. PARSER_INT_ALL << PARSER_INT_HOST_EN_BIT);
  756. return 0;
  757. Err_3:
  758. pts_stop(PTS_TYPE_AUDIO);
  759. Err_2:
  760. pts_stop(PTS_TYPE_VIDEO);
  761. Err_1:
  762. return r;
  763. }
  764. void psparser_release(void)
  765. {
  766. u8 i;
  767. printk("psparser_release\n");
  768. WRITE_MPEG_REG(PARSER_INT_ENABLE, 0);
  769. free_irq(INT_PARSER, (void *)psparser_id);
  770. pts_stop(PTS_TYPE_VIDEO);
  771. pts_stop(PTS_TYPE_AUDIO);
  772. #ifdef DEBUG_VOB_SUB
  773. for(i = 0; i < MAX_SUB_NUM; i ++) {
  774. if (sub_info[i]) {
  775. kfree(sub_info[i]);
  776. }
  777. }
  778. printk("psparser release subtitle info\n");
  779. #endif
  780. }
  781. ssize_t psparser_write(struct file *file,
  782. struct stream_buf_s *vbuf,
  783. struct stream_buf_s *abuf,
  784. const char __user *buf, size_t count)
  785. {
  786. s32 r;
  787. stream_port_t *port = (stream_port_t *)file->private_data;
  788. if ((stbuf_space(vbuf) < count) ||
  789. (stbuf_space(abuf) < count)) {
  790. if (file->f_flags & O_NONBLOCK) {
  791. return -EAGAIN;
  792. }
  793. if ((port->flag & PORT_FLAG_VID)
  794. && (stbuf_space(vbuf) < count)) {
  795. r = stbuf_wait_space(vbuf, count);
  796. if (r < 0) {
  797. return r;
  798. }
  799. }
  800. if ((port->flag & PORT_FLAG_AID)
  801. && (stbuf_space(abuf) < count)) {
  802. r = stbuf_wait_space(abuf, count);
  803. if (r < 0) {
  804. return r;
  805. }
  806. }
  807. }
  808. return _psparser_write(buf, count);
  809. }
  810. void psparser_change_avid(unsigned int vid, unsigned int aid)
  811. {
  812. video_id = vid;
  813. audio_id = aid;
  814. return;
  815. }
  816. void psparser_change_sid(unsigned int sid)
  817. {
  818. sub_id = sid;
  819. return;
  820. }
  821. void psparser_audio_reset(void)
  822. {
  823. ulong flags;
  824. DEFINE_SPINLOCK(lock);
  825. spin_lock_irqsave(&lock, flags);
  826. WRITE_MPEG_REG(PARSER_AUDIO_WP,
  827. READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
  828. WRITE_MPEG_REG(PARSER_AUDIO_RP,
  829. READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
  830. WRITE_MPEG_REG(PARSER_AUDIO_START_PTR,
  831. READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
  832. WRITE_MPEG_REG(PARSER_AUDIO_END_PTR,
  833. READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR));
  834. CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);
  835. WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  836. CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
  837. audio_data_parsed = 0;
  838. spin_unlock_irqrestore(&lock, flags);
  839. return;
  840. }
  841. void psparser_sub_reset(void)
  842. {
  843. ulong flags;
  844. DEFINE_SPINLOCK(lock);
  845. u32 parser_sub_start_ptr;
  846. u32 parser_sub_end_ptr;
  847. spin_lock_irqsave(&lock, flags);
  848. parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
  849. parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
  850. WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
  851. WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
  852. WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr);
  853. WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr);
  854. SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);
  855. spin_unlock_irqrestore(&lock, flags);
  856. return;
  857. }
  858. u8 psparser_get_sub_found_num(void)
  859. {
  860. #ifdef DEBUG_VOB_SUB
  861. return sub_found_num;
  862. #else
  863. return 0;
  864. #endif
  865. }
  866. u8 psparser_get_sub_info(struct subtitle_info **sub_infos)
  867. {
  868. #ifdef DEBUG_VOB_SUB
  869. u8 i = 0;
  870. int ret = 0;
  871. u8 size = sizeof(struct subtitle_info);
  872. for (i = 0; i < sub_found_num; i ++) {
  873. if (!sub_info[i]){
  874. printk("[psparser_get_sub_info:%d] sub_info[%d] NULL\n", __LINE__, i);
  875. ret = -1;
  876. break;
  877. }
  878. if (!sub_infos[i]){
  879. printk("[psparser_get_sub_info:%d] sub_infos[%d] NULL\n", __LINE__, i);
  880. ret = -2;
  881. break;
  882. }
  883. memcpy(sub_infos[i], sub_info[i], size);
  884. }
  885. return ret;
  886. #else
  887. return 0;
  888. #endif
  889. }