avi_plugin.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "vp_engine.h"
  5. #include "avi_demuxer.h"
  6. #include "adpcm.h"
  7. #include "video_mem.h"
  8. int read_data(void *stream, void *buf, unsigned int len)
  9. {
  10. int rdnum;
  11. rdnum = stream_read(stream, buf, len);
  12. return rdnum;
  13. }
  14. int read_skip(void *stream, int len)
  15. {
  16. stream_seek(stream, len, SEEK_DIR_CUR);
  17. return 0;
  18. }
  19. int file_seek(void *stream, int len, int orig)
  20. {
  21. stream_seek(stream, len, orig);
  22. return 0;
  23. }
  24. int file_seek_back(void *stream, int len)
  25. {
  26. stream_seek(stream, len, SEEK_DIR_CUR);
  27. return 0;
  28. }
  29. int file_seek_set(void *stream, int len)
  30. {
  31. stream_seek(stream, len, SEEK_DIR_BEG);
  32. return 0;
  33. }
  34. int file_tell(void *stream)
  35. {
  36. return stream_tell(stream);
  37. }
  38. static int set_app_info(void *fhandle, void *media_info)
  39. {
  40. avi_contex_t *avi_handle;
  41. ve_media_info_t *ve_info;
  42. if ((fhandle == NULL)||(media_info == NULL))
  43. {
  44. return MEMERROR;
  45. }
  46. avi_handle = (avi_contex_t *)fhandle;
  47. ve_info = (ve_media_info_t *)media_info;
  48. ve_info->video_info.width = avi_handle->bmpheader.biWidth;
  49. ve_info->video_info.height = avi_handle->bmpheader.biHeight;
  50. ve_info->index_flag = avi_handle->index_flag;
  51. if (avi_handle->dwScale == 0)
  52. ve_info->video_info.frame_rate = 15;
  53. else
  54. ve_info->video_info.frame_rate = avi_handle->dwRate / avi_handle->dwScale;
  55. avi_handle->framerate = ve_info->video_info.frame_rate;
  56. //printf("video framerate: %ld, dwRate: %ld, dwScale: %ld\n", avi_handle->framerate, avi_handle->dwRate, avi_handle->dwScale);
  57. ve_info->video_info.vtotal_time = ((avi_handle->TotalFrames * TIMESCALE * 10) / avi_handle->framerate )/10;
  58. //avi_handle->framenum = 0;
  59. //app.type =
  60. //if (avi_handle->filetype == formtypeAVI)
  61. // app.type = VIDEO_AVI;
  62. //if (avi_handle->filetype == formtypeAMV)
  63. // app.type = VIDEO_AMV;
  64. //file_seek(avi_handle->io, avi_handle->movitagpos, IDSEEK_SET);
  65. return NORMAL;
  66. }
  67. static void *open(io_stream_t stream, ve_media_info_t *file_info)
  68. {
  69. avi_contex_t *avi_handle;
  70. ve_media_info_t *ve_m_info;
  71. int rtvl;
  72. ve_m_info = (ve_media_info_t *)file_info;
  73. avi_handle = video_mem_malloc(sizeof(avi_contex_t));
  74. if (avi_handle == NULL)
  75. {
  76. return NULL;
  77. }
  78. memset(avi_handle, 0, sizeof(avi_contex_t));
  79. avi_handle->stream = stream;
  80. rtvl = read_header(avi_handle);
  81. if (rtvl != NORMAL)
  82. {
  83. video_mem_free(avi_handle);
  84. return NULL;
  85. }
  86. set_app_info(avi_handle, ve_m_info);
  87. //default to amv
  88. //avi_handle->amvformat = 1;
  89. /*
  90. ve_m_info->video_info.frame_rate
  91. ve_m_info->video_info.width
  92. ve_m_info->video_info.height
  93. ve_m_info->video_info.video
  94. ve_m_info->video_info.video_bitrate
  95. ve_m_info->video_info.vtotal_time
  96. ve_m_info->audio_info.atotal_time
  97. ve_m_info->audio_info.audio
  98. ve_m_info->audio_info.audio_bitrate
  99. ve_m_info->audio_info.channels
  100. ve_m_info->audio_info.sample_rate
  101. */
  102. return avi_handle;
  103. }
  104. static int getframe(void *fhandle, demuxer_packet_t *de_pac)
  105. {
  106. avi_packet_t packet_val;
  107. avi_packet_t *packet;
  108. int rdnum;
  109. avi_contex_t *avi_handle;
  110. int rtval;
  111. int padding;
  112. wave_head_t *wave_h;
  113. if ((fhandle == NULL)||(de_pac == NULL))
  114. {
  115. //PRINT_LOG_ERROR("getframe err_1!", 0, 0);
  116. return EN_MEMERR;
  117. }
  118. if (de_pac->data == NULL)
  119. {
  120. //PRINT_LOG_ERROR("getframe err_2!", 0, 0);
  121. return EN_MEMERR;
  122. }
  123. packet = &packet_val;
  124. packet->data = de_pac->data;
  125. avi_handle = (avi_contex_t *)fhandle;
  126. rtval = get_es_chunk(avi_handle, packet);
  127. if (rtval == MEMERROR)
  128. {
  129. return EN_MEMERR;
  130. }
  131. if (packet->data_len == 0 || rtval == STREAMEND)
  132. {
  133. return EN_FILEISEND;
  134. }
  135. de_pac->packet_type = UNKOWN_ES;
  136. if (packet->es_type == streamtypeVIDEO)
  137. {
  138. de_pac->packet_type = VIDEO_ES;
  139. avi_handle->framecounter++;
  140. }
  141. if (packet->es_type == streamtypeAUDIO)
  142. {
  143. de_pac->packet_type = AUDIO_ES;
  144. }
  145. if ((packet->es_type == ckidAVINEWINDEX)||(packet->es_type == ckidAMVEND))
  146. {
  147. return EN_FILEISEND;
  148. }
  149. if (de_pac->packet_type == UNKOWN_ES)
  150. {
  151. return EN_MEMERR;
  152. }
  153. padding = CHUNKPADD(packet->data_len, avi_handle->amvformat);
  154. if (de_pac->packet_type == AUDIO_ES)
  155. {
  156. if ((packet->data_len + padding + sizeof(wave_head_t) > MAX_PACKET_LEN))
  157. {
  158. printf("audio pkt too long!\n");
  159. return EN_MEMERR;
  160. }
  161. }
  162. if (de_pac->packet_type == AUDIO_ES)
  163. {
  164. wave_h = (wave_head_t *)(packet->data);
  165. wave_h->dwSamples_per_sec = avi_handle->dwSamples_per_sec;//avi_handle->waveheader.nSamplesPerSec;
  166. wave_h->wChannels = avi_handle->wChannels;//avi_handle->waveheader.nChannels;
  167. packet->data += sizeof(wave_head_t);
  168. if(avi_handle->amvformat == 0)
  169. {
  170. // avi audio stream
  171. rdnum = read_data(avi_handle->stream, packet->data, 4);
  172. if (rdnum != 4)
  173. {
  174. return EN_FILEISEND;
  175. }
  176. packet->data += 4;
  177. *((unsigned int *)packet->data) = (packet->data_len - 4)*2;
  178. packet->data += 4;
  179. rdnum = read_data(avi_handle->stream, packet->data, packet->data_len + padding - 4);
  180. if (rdnum != (packet->data_len + padding - 4))
  181. {
  182. return EN_FILEISEND;
  183. }
  184. packet->data_len += 4;
  185. }
  186. else
  187. {
  188. // amv audio stream
  189. rdnum = read_data(avi_handle->stream, packet->data, packet->data_len + padding);
  190. if (rdnum != (packet->data_len + padding))
  191. {
  192. return EN_FILEISEND;
  193. }
  194. }
  195. }
  196. de_pac->pts = packet->pts;
  197. if (de_pac->packet_type == AUDIO_ES)
  198. {
  199. packet->data_len += sizeof(wave_head_t);
  200. }
  201. de_pac->data_len = packet->data_len;
  202. return EN_NORMAL;
  203. }
  204. static int dispose(void *fhandle)
  205. {
  206. if (fhandle)
  207. {
  208. video_mem_free(fhandle);
  209. }
  210. return 0;
  211. }
  212. static int dem_seek(void *fhandle, seek_info_t *seek_info)
  213. {
  214. avi_contex_t *avi_handle;
  215. avi_packet_t packet;
  216. int rtval;
  217. int padding;
  218. int curr_index_offset;
  219. int relation_offset;
  220. int data_offset;
  221. unsigned int frame_num;
  222. if ((fhandle == NULL)||(seek_info == NULL))
  223. {
  224. return EN_MEMERR;
  225. }
  226. avi_handle = (avi_contex_t *)fhandle;
  227. #if 0
  228. seek_info.seek_cmd = GET_CONT_INFO;
  229. seek_info.curpos = puserparam->pbreakinfor->bpbyte;
  230. seek_info.curframes = puserparam->pbreakinfor->framecnt;
  231. seek_info.curtime = puserparam->pbreakinfor->time;
  232. #endif
  233. switch(seek_info->seek_cmd)
  234. {
  235. case GET_CONT_INFO:
  236. avi_handle->framecounter = seek_info->curframes;
  237. if (seek_info->curpos != 0)
  238. {
  239. file_seek(avi_handle->stream, seek_info->curpos, SEEK_DIR_BEG);
  240. }
  241. break;
  242. case FAST_FORWORD:
  243. if(avi_handle->index_flag ||(avi_handle->amvformat == 0))
  244. {
  245. if((seek_info->curframes+avi_handle->framecounter) >= avi_handle->TotalFrames)
  246. {
  247. return EN_FILEISEND;
  248. // seek_info->curframes = avi_handle->TotalFrames - avi_handle->framecounter;
  249. }
  250. curr_index_offset = avi_handle->index_offset +8+((seek_info->curframes+avi_handle->framecounter)<<5);
  251. file_seek_set(avi_handle->stream, (curr_index_offset+8));
  252. relation_offset = read4bytes(avi_handle->stream);
  253. data_offset = relation_offset + avi_handle->movitagpos;
  254. file_seek_set(avi_handle->stream, data_offset-4);
  255. avi_handle->framecounter += seek_info->curframes;
  256. packet.pts = ((avi_handle->framecounter * TIMESCALE * 10) / avi_handle->framerate)/10;
  257. }
  258. else
  259. {
  260. packet.data_len = 0;
  261. packet.es_type = -1;
  262. for(;;)
  263. {
  264. rtval = get_es_chunk(avi_handle, &packet);
  265. if (rtval == STREAMEND)
  266. {
  267. return EN_FILEISEND;
  268. }
  269. padding = CHUNKPADD(packet.data_len, avi_handle->amvformat);
  270. read_skip(avi_handle->stream, packet.data_len + padding);
  271. if (packet.es_type == streamtypeVIDEO)
  272. break;
  273. }
  274. avi_handle->framecounter++;
  275. //skip audio chunck
  276. rtval = get_es_chunk(avi_handle, &packet);
  277. if (rtval == STREAMEND)
  278. {
  279. return EN_FILEISEND;
  280. }
  281. padding = CHUNKPADD(packet.data_len, avi_handle->amvformat);
  282. read_skip(avi_handle->stream, packet.data_len + padding);
  283. //printf("f ts: %d\n", packet.pts);
  284. }
  285. break;
  286. case FAST_BACK:
  287. if(avi_handle->index_flag ||(avi_handle->amvformat == 0))
  288. {
  289. if(avi_handle->framecounter <= seek_info->curframes)
  290. {
  291. return EN_FILESTARTPOS;
  292. }
  293. curr_index_offset = avi_handle->index_offset +8+((avi_handle->framecounter - seek_info->curframes )<<5);
  294. file_seek_set(avi_handle->stream, (curr_index_offset+8));
  295. relation_offset = read4bytes(avi_handle->stream);
  296. data_offset = relation_offset + avi_handle->movitagpos;
  297. file_seek_set(avi_handle->stream, data_offset-4);
  298. avi_handle->framecounter -= seek_info->curframes;
  299. packet.pts = ((avi_handle->framecounter * TIMESCALE * 10) / avi_handle->framerate)/10;
  300. }
  301. else
  302. {
  303. packet.data = seek_info->searchbuf;
  304. rtval = search_es_chunk(avi_handle, &packet);
  305. if (rtval == STREAMSTART)
  306. {
  307. return EN_FILESTARTPOS;
  308. }
  309. }
  310. //printf("b ts: %d\n", packet.pts);
  311. break;
  312. case SEEK_TIME:
  313. frame_num = (seek_info->curtime *avi_handle->framerate*10/TIMESCALE)/10;
  314. printf("frame_num: %d, counter: %lu\n", frame_num, avi_handle->TotalFrames);
  315. if(frame_num > avi_handle->TotalFrames)
  316. {
  317. frame_num = avi_handle->TotalFrames;
  318. }
  319. curr_index_offset = avi_handle->index_offset +8+(frame_num<<5);
  320. file_seek_set(avi_handle->stream, (curr_index_offset+8));
  321. relation_offset = read4bytes(avi_handle->stream);
  322. data_offset = relation_offset + avi_handle->movitagpos;
  323. file_seek_set(avi_handle->stream, data_offset-4);
  324. avi_handle->framecounter = frame_num;
  325. printf("seek: %d, tell: %d\n", data_offset-4, file_tell(avi_handle->stream));
  326. break;
  327. //search_es_chunk
  328. default:
  329. break;
  330. }
  331. return 0;
  332. }
  333. //support amv/avi
  334. demuxer_plugin_t demuxer_plugin = {
  335. "avi",
  336. open,
  337. dem_seek,
  338. getframe,
  339. dispose
  340. };
  341. demuxer_plugin_t * avi_api(void)
  342. {
  343. return &demuxer_plugin;
  344. }