Guest User

Untitled

a guest
Jan 7th, 2015
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.36 KB | None | 0 0
  1. commit babd94ed5c6f806d3aff53f27f4da676866bcce4
  2. Author: Eejya Singh <[email protected]>
  3. Date: Sun Dec 28 22:44:09 2014 +0530
  4.  
  5. lavf: add DVD reader protocol
  6.  
  7. Based on the work of Erik Van Grunderbeeck <[email protected]>.
  8.  
  9. Signed-off-by: Clément Bœsch <[email protected]>
  10.  
  11. Conflicts:
  12. configure
  13.  
  14. diff --git a/configure b/configure
  15. index 05d5b34..8a88853 100755
  16. --- a/configure
  17. +++ b/configure
  18. @@ -210,6 +210,7 @@ External library support:
  19. --enable-libcdio enable audio CD grabbing with libcdio [no]
  20. --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
  21. and libraw1394 [no]
  22. + --enable-libdvdnav enable DVD reading through libdvdnav [no]
  23. --enable-libfaac enable AAC encoding via libfaac [no]
  24. --enable-libfdk-aac enable AAC de/encoding via libfdk-aac [no]
  25. --enable-libflite enable flite (voice synthesis) support via libflite [no]
  26. @@ -2524,6 +2525,7 @@ x11grab_xcb_indev_deps="libxcb"
  27.  
  28. # protocols
  29. bluray_protocol_deps="libbluray"
  30. +dvd_protocol_deps="libdvdnav"
  31. ffrtmpcrypt_protocol_deps="!librtmp_protocol"
  32. ffrtmpcrypt_protocol_deps_any="gcrypt nettle openssl"
  33. ffrtmpcrypt_protocol_select="tcp_protocol"
  34. diff --git a/libavformat/Makefile b/libavformat/Makefile
  35. index 7e4beac..b1761bc 100644
  36. --- a/libavformat/Makefile
  37. +++ b/libavformat/Makefile
  38. @@ -130,6 +130,7 @@ OBJS-$(CONFIG_DTS_DEMUXER) += dtsdec.o rawdec.o
  39. OBJS-$(CONFIG_DTS_MUXER) += rawenc.o
  40. OBJS-$(CONFIG_DV_DEMUXER) += dv.o
  41. OBJS-$(CONFIG_DV_MUXER) += dvenc.o
  42. +OBJS-$(CONFIG_DVD_PROTOCOL) += dvdproto.o
  43. OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o
  44. OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o
  45. OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o
  46. diff --git a/libavformat/allformats.c b/libavformat/allformats.c
  47. index a55e209..12bc552 100644
  48. --- a/libavformat/allformats.c
  49. +++ b/libavformat/allformats.c
  50. @@ -347,6 +347,7 @@ void av_register_all(void)
  51. REGISTER_PROTOCOL(CONCAT, concat);
  52. REGISTER_PROTOCOL(CRYPTO, crypto);
  53. REGISTER_PROTOCOL(DATA, data);
  54. + REGISTER_PROTOCOL(DVD, dvd);
  55. REGISTER_PROTOCOL(FFRTMPCRYPT, ffrtmpcrypt);
  56. REGISTER_PROTOCOL(FFRTMPHTTP, ffrtmphttp);
  57. REGISTER_PROTOCOL(FILE, file);
  58. diff --git a/libavformat/dvdproto.c b/libavformat/dvdproto.c
  59. new file mode 100644
  60. index 0000000..c86f344
  61. --- /dev/null
  62. +++ b/libavformat/dvdproto.c
  63. @@ -0,0 +1,655 @@
  64. +/*
  65. + * Copyright (c) 2009 Erik Van Grunderbeeck <erik <at> arawix.com>
  66. + * Copyright (c) 2012 Stefano Sabatini
  67. + *
  68. + * This file is part of FFmpeg.
  69. + *
  70. + * FFmpeg is free software; you can redistribute it and/or
  71. + * modify it under the terms of the GNU Lesser General Public
  72. + * License as published by the Free Software Foundation; either
  73. + * version 2.1 of the License, or (at your option) any later version.
  74. + *
  75. + * FFmpeg is distributed in the hope that it will be useful,
  76. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  77. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  78. + * Lesser General Public License for more details.
  79. + *
  80. + * You should have received a copy of the GNU Lesser General Public
  81. + * License along with FFmpeg; if not, write to the Free Software
  82. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  83. + */
  84. +
  85. +#include <dvdnav/dvdnav.h>
  86. +#include <dvdnav/dvd_types.h>
  87. +#include "libavutil/avstring.h"
  88. +#include "libavformat/avformat.h"
  89. +#include "libavformat/avio.h"
  90. +#include "libavformat/url.h"
  91. +
  92. +#define DVD_PROTO_PREFIX "dvd:"
  93. +
  94. +#define MAX_ATTACH_BUTTONS 36
  95. +#define MAX_ATTACH_AUDIO_LANGUAGES 8
  96. +#define MAX_ATTACH_SUB_LANGUAGES 32
  97. +
  98. +typedef enum {
  99. + DVDEffectUnknown,
  100. + DVDEffectButtons,
  101. + DVDEffectButtonsHighlight,
  102. + DVDEffectWait,
  103. + DVDEffectCLUT,
  104. + DVDEffectClearQueue,
  105. + DVDEffectResetIFO,
  106. + DVDEffectClearNOP,
  107. +} DVDEffectType;
  108. +
  109. +/* contains the map the dvd, buffer and event data */
  110. +typedef struct {
  111. + dvdnav_t *nav_data;
  112. + uint8_t cache_buf[DVD_VIDEO_LB_LEN];
  113. + uint8_t *read_buf;
  114. + uint8_t *next_buf;
  115. + int read_buf_left;
  116. + char *language;
  117. +} DVDContext;
  118. +
  119. +typedef struct {
  120. + uint16_t x, y, w, h;
  121. +} DVDAttachmentButton;
  122. +
  123. +typedef struct {
  124. + int64_t pts; ///< pts of this context
  125. + uint16_t type;
  126. + uint16_t wait;
  127. +
  128. + // when buttons
  129. + uint16_t highlight_index;
  130. + uint16_t button_count;
  131. + DVDAttachmentButton buttons[MAX_ATTACH_BUTTONS];
  132. +
  133. + // when color-palette
  134. + uint32_t rgba_palette[16];
  135. +
  136. + // expected size of the video pictures (allows for skip of scan-stream)
  137. + uint16_t video_width, video_height;
  138. +
  139. + // aspect ratio (0 = 4:3 , 3 = 16:9)
  140. + uint8_t aspect_ratio : 4;
  141. + // video format (0 = ntsc, 1 = pal)
  142. + uint8_t video_format : 4;
  143. +
  144. + uint8_t current_vts;
  145. + uint8_t nb_audio_languages;
  146. + uint8_t nb_subtitle_languages;
  147. +
  148. + uint16_t audio_languages [MAX_ATTACH_AUDIO_LANGUAGES];
  149. + uint16_t audio_flags [MAX_ATTACH_AUDIO_LANGUAGES];
  150. + uint8_t audio_channels [MAX_ATTACH_AUDIO_LANGUAGES];
  151. + uint8_t audio_mode [MAX_ATTACH_AUDIO_LANGUAGES];
  152. + uint16_t subtitle_languages[MAX_ATTACH_SUB_LANGUAGES];
  153. + uint16_t subtitle_flags [MAX_ATTACH_SUB_LANGUAGES];
  154. +
  155. + // when angle change
  156. + uint8_t current_angle;
  157. + uint8_t max_angle;
  158. +
  159. + // size of current title in pts ticks. divide by 90000 to get time in seconds
  160. + uint64_t duration;
  161. +
  162. + // flags that describe actions allowed for current chapter
  163. + uint32_t flags;
  164. +} DVDParseContext;
  165. +
  166. +/* use libdvdnav's read ahead cache? */
  167. +#define DVD_READ_CACHE 1
  168. +
  169. +/* which is the default language for menus/audio/subpictures? */
  170. +#define DVD_LANGUAGE "en"
  171. +
  172. +static uint16_t bswap_16(uint16_t bswap)
  173. +{
  174. + uint16_t a = bswap & 0xff;
  175. + uint16_t b = (bswap >> 8) & 0xff;
  176. + return ((a << 8) | b);
  177. +}
  178. +
  179. +static void dvd_protocol_send(URLContext *h, DVDParseContext *pctx)
  180. +{
  181. + /* If there is a user-supplied mutex locking routine, call it. */
  182. + /* if (ff_dvd_lockmgr_cb) { */
  183. + /* if ((*ff_dvd_lockmgr_cb)(&codec_dvd_mutex, AV_LOCK_OBTAIN)) */
  184. + /* return; */
  185. + /* } */
  186. +
  187. + /* if (h->ff_protocol_cb) { */
  188. + /* (h->ff_protocol_cb)(pctx, h->ff_cb_userdata); */
  189. + /* } */
  190. +
  191. + /* /\* If there is a user-supplied mutex locking routine, call it. *\/ */
  192. + /* if (ff_dvd_lockmgr_cb) { */
  193. + /* if ((*ff_dvd_lockmgr_cb)(&codec_dvd_mutex, AV_LOCK_RELEASE)) */
  194. + /* return; */
  195. + /* } */
  196. +}
  197. +
  198. +
  199. +static int dvd_protocol_build_packet_reset(URLContext *h, DVDContext *dvd,
  200. + dvdnav_vts_change_event_t *event)
  201. +{
  202. + int i, iCount;
  203. + int32_t ititle, ipart;
  204. + uint64_t *times;
  205. + uint32_t i_width, i_height;
  206. + dvdnav_status_t eStatus;
  207. + audio_attr_t iAudioAttr;
  208. + subp_attr_t iSubAttr;
  209. + av_unused video_attr_t iVidAttr;
  210. + DVDParseContext *pctx;
  211. + int32_t current_angle, max_angle;
  212. +
  213. + // check the type
  214. + if (event->new_domain == DVD_READ_TITLE_VOBS) {
  215. + /* in general, this signals that we should re-read the
  216. + * language and sub-title information from the dvd
  217. + * this is the best method I could find, since not all
  218. + * dvd's send a ifo change domain (usually just send at
  219. + * beginning)
  220. + */
  221. +
  222. + pctx = (DVDParseContext *)av_mallocz(sizeof(DVDParseContext));
  223. + if (!pctx)
  224. + return AVERROR(ENOMEM);
  225. +
  226. + pctx->type = DVDEffectResetIFO;
  227. + pctx->pts = dvdnav_get_current_time(dvd->nav_data);
  228. +
  229. + // set width and height
  230. + /* if (dvdnav_get_video_attributes(dvd->nav_data, &iVidAttr) == DVDNAV_STATUS_OK) { */
  231. + /* pctx->video_format = iVidAttr.video_format; */
  232. + /* pctx->aspect_ratio = iVidAttr.display_aspect_ratio; */
  233. + /* pctx->video_width = 640; */
  234. + /* pctx->video_height = 480; */
  235. + /* if (iVidAttr.video_format) { */
  236. + /* pctx->video_height = 576; */
  237. + /* switch (iVidAttr.picture_size) { */
  238. + /* case 0: pctx->video_width = 720; break; */
  239. + /* case 1: pctx->video_width = 704; break; */
  240. + /* case 2: pctx->video_width = 352; break; */
  241. + /* case 3: */
  242. + /* pctx->video_width = 352; */
  243. + /* pctx->video_height /= 2; */
  244. + /* break; */
  245. + /* } */
  246. + /* } */
  247. + /* } */
  248. +
  249. + if( dvdnav_get_video_resolution(dvd->nav_data,&i_width, &i_height ) )
  250. + i_width = i_height = 0;
  251. + switch( dvdnav_get_video_aspect(dvd->nav_data) )
  252. + {
  253. + case 0:
  254. + pctx->video_height = 4 * i_height;
  255. + pctx->video_width = 3 * i_width;
  256. + break;
  257. + case 3:
  258. + pctx->video_height = 16 * i_height;
  259. + pctx->video_width = 9 * i_width;
  260. + break;
  261. + default:
  262. + pctx->video_height = 0;
  263. + pctx->video_width = 0;
  264. + break;
  265. + }
  266. + // store vts index
  267. + pctx->current_vts = (uint8_t)event->new_vtsN;
  268. +
  269. + // get all audio languages, theres always max 8
  270. + eStatus = DVDNAV_STATUS_OK;
  271. + memset(&pctx->audio_languages, 0, sizeof(uint16_t)*MAX_ATTACH_AUDIO_LANGUAGES);
  272. + memset(&pctx->audio_flags, 0, sizeof(uint16_t)*MAX_ATTACH_AUDIO_LANGUAGES);
  273. + for (i = 0; i < MAX_ATTACH_AUDIO_LANGUAGES && eStatus == DVDNAV_STATUS_OK; i++) {
  274. + eStatus = dvdnav_get_audio_attr(dvd->nav_data, i, &iAudioAttr);
  275. +
  276. + pctx->audio_languages[i] = bswap_16(iAudioAttr.lang_code);
  277. + pctx->audio_flags [i] = iAudioAttr.code_extension;
  278. + pctx->audio_channels [i] = iAudioAttr.channels;
  279. + pctx->audio_mode [i] = iAudioAttr.application_mode;
  280. +
  281. + // stop when language empty
  282. + if (iAudioAttr.lang_code == 0x0000)
  283. + break;
  284. + }
  285. + pctx->nb_audio_languages = i;
  286. +
  287. + //get information for subtitle languages
  288. + iCount = 0;
  289. + eStatus = DVDNAV_STATUS_OK;
  290. + memset(&pctx->subtitle_languages, 0, sizeof(uint16_t)*MAX_ATTACH_SUB_LANGUAGES);
  291. + memset(&pctx->subtitle_languages, 0, sizeof(uint16_t)*MAX_ATTACH_SUB_LANGUAGES);
  292. + int spu = dvdnav_get_active_spu_stream(dvd->nav_data);
  293. + av_log(h,0,"Active SPU stream %d\n",spu);
  294. + for (i = 0; i < MAX_ATTACH_SUB_LANGUAGES && eStatus == DVDNAV_STATUS_OK; i++) {
  295. + // get the attributes, make sure we dont get the same stuff twice (seen that happen)
  296. + eStatus = dvdnav_get_spu_attr(dvd->nav_data, i, &iSubAttr);
  297. +
  298. + pctx->subtitle_languages[iCount] = bswap_16(iSubAttr.lang_code);
  299. + /* from the documentation at http://dvd.sourceforge.net/dvdinfo/sprm.html
  300. + 1=normal, 2=large, 3=children, 5=normal captions, 6=large captions, 7=childrens captions,
  301. + 9=forced, 13=director comments, 14=large director comments, 15=director comments for children */
  302. + pctx->subtitle_flags[i] = iSubAttr.code_extension;
  303. +
  304. + // stop when language empty
  305. + if (iSubAttr.lang_code == 0x0000)
  306. + break;
  307. +
  308. + ++iCount;
  309. + }
  310. + pctx->nb_subtitle_languages = iCount;
  311. +
  312. + // get time of vobs. might be a better way?
  313. + ititle = 0;
  314. + ipart = 0;
  315. + times = NULL;
  316. + if (dvdnav_current_title_info(dvd->nav_data, &ititle, &ipart) == DVDNAV_STATUS_OK) {
  317. + dvdnav_describe_title_chapters(dvd->nav_data, ititle, &times, &pctx->duration);
  318. + if (times) {
  319. + /* note that I can't use av_free here (since the memory isnt libav's) */
  320. + av_free(times);
  321. + }
  322. + }
  323. +
  324. + // get angle info
  325. + current_angle = max_angle = 0;
  326. + if (dvdnav_get_angle_info(dvd->nav_data, &current_angle, &max_angle) == DVDNAV_STATUS_OK) {
  327. + pctx->current_angle = (uint8_t)current_angle;
  328. + pctx->max_angle = (uint8_t)max_angle;
  329. + }
  330. +
  331. + dvd_protocol_send(h, pctx);
  332. + return 1;
  333. + }
  334. +
  335. + return 0;
  336. +}
  337. +
  338. +/**
  339. + * Build a navigation packet signaling new button selection data.
  340. + */
  341. +static int dvd_protocol_build_packet_nav(URLContext *h, DVDContext *dvd)
  342. +{
  343. + DVDParseContext *pctx;
  344. + pci_t *pci = dvdnav_get_current_nav_pci(dvd->nav_data);
  345. + int i;
  346. + int iButtonCount = pci->hli.hl_gi.btn_ns;
  347. + if (iButtonCount == 0)
  348. + return 0;
  349. +
  350. + pctx = (DVDParseContext *)av_mallocz(sizeof(DVDParseContext));
  351. + if (!pctx)
  352. + return AVERROR(ENOMEM);
  353. +
  354. + pctx->type = DVDEffectButtons;
  355. + pctx->pts = dvdnav_get_current_time(dvd->nav_data);
  356. + pctx->button_count = (uint16_t)iButtonCount;
  357. + pctx->button_count = FFMIN(pctx->button_count, MAX_ATTACH_BUTTONS);
  358. +
  359. + for (i = 0; i < iButtonCount; i++) {
  360. + btni_t *btni = &(pci->hli.btnit[i]);
  361. + pctx->buttons[i].x = btni->x_start;
  362. + pctx->buttons[i].y = btni->y_start;
  363. + pctx->buttons[i].w = btni->x_end - btni->x_start;
  364. + pctx->buttons[i].h = btni->y_end - btni->y_start;
  365. + }
  366. +
  367. + dvd_protocol_send(h, pctx);
  368. + return 1;
  369. +}
  370. +
  371. +/**
  372. + * Build a navigation packet signaling new button highlight data.
  373. + */
  374. +static int dvd_protocol_build_packet_highlight(URLContext *h, DVDContext *dvd,
  375. + uint32_t index)
  376. +{
  377. + DVDParseContext *pctx = (DVDParseContext *)av_mallocz(sizeof(DVDParseContext));
  378. + if (!pctx)
  379. + return AVERROR(ENOMEM);
  380. +
  381. + pctx->type = DVDEffectButtonsHighlight;
  382. + pctx->pts = dvdnav_get_current_time(dvd->nav_data);
  383. + pctx->highlight_index = index > 0 ? index-1 : 0;
  384. +
  385. + pctx->buttons[0] = (DVDAttachmentButton){0};
  386. + dvd_protocol_send(h, pctx);
  387. +
  388. + return 1;
  389. +}
  390. +
  391. +/**
  392. + * Build a navigation packet signaling a new color table.
  393. + */
  394. +static int dvd_protocol_build_packet_clut(URLContext *h, DVDContext *dvd, uint32_t *data_color)
  395. +{
  396. + DVDParseContext *pctx = (DVDParseContext *)av_mallocz(sizeof(DVDParseContext));
  397. + if (!pctx)
  398. + return AVERROR(ENOMEM);
  399. +
  400. + pctx->type = DVDEffectCLUT;
  401. + pctx->pts = dvdnav_get_current_time(dvd->nav_data);
  402. + memcpy(pctx->rgba_palette, data_color, 16 * sizeof(uint32_t));
  403. + dvd_protocol_send(h, pctx);
  404. +
  405. + return 1;
  406. +}
  407. +
  408. +/**
  409. + * Build a navigation packet signaling a wait (e.g. on still).
  410. + */
  411. +static int dvd_protocol_build_packet_wait(URLContext *h, DVDContext *dvd, uint32_t time)
  412. +{
  413. + DVDParseContext *pctx = (DVDParseContext *)av_mallocz(sizeof(DVDParseContext));
  414. + if (!pctx)
  415. + return AVERROR(ENOMEM);
  416. +
  417. + pctx->type = DVDEffectWait;
  418. + pctx->pts = dvdnav_get_current_time(dvd->nav_data);
  419. + pctx->wait = time;
  420. + dvd_protocol_send(h, pctx);
  421. + return 1;
  422. +}
  423. +
  424. +/**
  425. + * Take part of the buffer and send it back.
  426. + */
  427. +static int dvd_protocol_read_build(URLContext *h, DVDContext *dvd, unsigned char *buf_out, int size)
  428. +{
  429. +
  430. + int min_len_read = FFMIN(dvd->read_buf_left, size);
  431. +
  432. +
  433. + memcpy(buf_out, dvd->next_buf, min_len_read);
  434. + dvd->read_buf_left -= min_len_read;
  435. + dvd->next_buf += min_len_read;
  436. + return min_len_read;
  437. +}
  438. +
  439. +static int dvd_open(URLContext *h, const char *filename, int flags)
  440. +{
  441. + DVDContext *dvd = h->priv_data;
  442. + const char *diskname = filename;
  443. + int i = 1;
  444. + int32_t titles;
  445. + uint64_t *times,duration,max_duration,max_duration_title = 1;
  446. +
  447. + av_strstart(filename, DVD_PROTO_PREFIX, &diskname);
  448. +
  449. + dvd->language = av_strdup(DVD_LANGUAGE);
  450. + dvd->read_buf = dvd->cache_buf;
  451. +
  452. + if (dvdnav_open(&dvd->nav_data, diskname) != DVDNAV_STATUS_OK) {
  453. + av_freep(&dvd);
  454. + return AVERROR(EIO);
  455. + }
  456. +
  457. + /* set read ahead cache usage */
  458. + if (dvdnav_set_readahead_flag(dvd->nav_data, DVD_READ_CACHE) != DVDNAV_STATUS_OK) {
  459. + dvdnav_close(dvd->nav_data);
  460. + av_freep(&dvd);
  461. + return AVERROR(EACCES);
  462. + }
  463. +
  464. + /* set the language */
  465. + if ((dvdnav_menu_language_select (dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK) ||
  466. + (dvdnav_audio_language_select(dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK) ||
  467. + (dvdnav_spu_language_select (dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK)) {
  468. + av_log(h, AV_LOG_ERROR, "Error selecting language\n");
  469. + dvdnav_close(dvd->nav_data);
  470. + av_freep(&dvd);
  471. + return AVERROR(EACCES);
  472. + }
  473. +
  474. + /* set the PGC positioning flag to have position information relatively to the
  475. + * current chapter (seek will seek in the chapter) */
  476. + if (dvdnav_set_PGC_positioning_flag(dvd->nav_data, 0) != DVDNAV_STATUS_OK) {
  477. + av_log(h, AV_LOG_ERROR, "Error setting PGC positioning flags\n");
  478. + dvdnav_close(dvd->nav_data);
  479. + av_freep(&dvd);
  480. + return AVERROR(EACCES);
  481. + }
  482. +
  483. + h->priv_data = dvd;
  484. +
  485. + if(dvdnav_get_number_of_titles(dvd->nav_data , &titles) != DVDNAV_STATUS_OK)
  486. + av_log( h, 0,"Error Getting No. of Titles");
  487. +
  488. + /*Selecting the title with the with the longest duration and playing it*/
  489. + while(i <= titles)
  490. + {
  491. + dvdnav_describe_title_chapters(dvd->nav_data , i , &times, &duration);
  492. + av_log( h, 0,"The duration of the chapter no. %d is %d\n", i, duration);
  493. + if(duration > max_duration){
  494. + max_duration = duration;
  495. + max_duration_title = i;
  496. + }
  497. + i++;
  498. + }
  499. + av_log( h, 0,"Title with maximum duration is %d\n",max_duration_title);
  500. + dvdnav_title_play(dvd->nav_data , max_duration_title);
  501. +
  502. +
  503. + return 0;
  504. +}
  505. +
  506. +static int dvd_close(URLContext *h)
  507. +{
  508. + DVDContext *dvd = (DVDContext *)h->priv_data;
  509. + av_freep(&dvd->language);
  510. + dvdnav_close(dvd->nav_data);
  511. + return 0;
  512. +}
  513. +
  514. +static int dvd_read(URLContext *h, unsigned char *buf_out, int size)
  515. +{
  516. + DVDContext *dvd = (DVDContext *)h->priv_data;
  517. + int i=0,res, event, read_len,finished=0;
  518. +
  519. + if (!dvd)
  520. + return AVERROR(EFAULT);
  521. +
  522. +while(!finished)
  523. +{
  524. + #ifdef DVD_READ_CACHE
  525. + res = dvdnav_get_next_cache_block(dvd->nav_data, &dvd->read_buf , &event, &read_len);
  526. + #else
  527. + res = dvdnav_get_next_block(dvd->nav_data, &dvd->read_buf, &event, &read_len);
  528. + #endif
  529. + if (res == DVDNAV_STATUS_ERR)
  530. + return AVERROR(EIO);
  531. + switch(event)
  532. + {
  533. + case DVDNAV_BLOCK_OK:
  534. + memcpy(buf_out,dvd->read_buf,read_len);
  535. + av_log(h,0,"Copied the buffer value to buf_out\n");
  536. + return read_len;
  537. + break;
  538. +
  539. + case DVDNAV_NAV_PACKET:
  540. + av_log(h,0,"Nav Packet\n");
  541. + break;
  542. +
  543. + case DVDNAV_HIGHLIGHT:
  544. + av_log(h,0,"Highlight Packet\n");
  545. + break;
  546. +
  547. + case DVDNAV_SPU_CLUT_CHANGE:
  548. + av_log(h,0,"SPU CLUT Packet\n");
  549. + break;
  550. +
  551. + case DVDNAV_STILL_FRAME:
  552. + av_log(h,0,"Still Frame\n");
  553. + break;
  554. +
  555. + case DVDNAV_WAIT:
  556. + av_log(h,0,"Wait Packet\n");
  557. + break;
  558. +
  559. + case DVDNAV_VTS_CHANGE:
  560. + av_log(h,0,"VTS Change Packet\n");
  561. + break;
  562. +
  563. + case DVDNAV_CELL_CHANGE:
  564. + av_log(h,0,"Cell Change Packet\n");
  565. + break;
  566. +
  567. + case DVDNAV_HOP_CHANNEL:
  568. + av_log(h,0,"Hop Channel Packet\n");
  569. + break;
  570. +
  571. + case DVDNAV_SPU_STREAM_CHANGE:
  572. + av_log(h,0,"SPU Stream Change\n");
  573. + break;
  574. +
  575. + case DVDNAV_AUDIO_STREAM_CHANGE:
  576. + av_log(h,0,"Audio Stream Change\n");
  577. + break;
  578. +
  579. + case DVDNAV_NOP:
  580. + av_log(h,0,"NOP Nothing to do");
  581. + break;
  582. +
  583. + case DVDNAV_STOP:
  584. + default:
  585. + finished=1;
  586. + /* Playback should end here. */
  587. + break;
  588. + }
  589. +
  590. +}
  591. +// we stop
  592. + if (dvd->next_buf) {
  593. + #ifdef DVD_READ_CACHE
  594. + dvdnav_free_cache_block(dvd->nav_data, dvd->read_buf);
  595. + #endif
  596. + dvd->next_buf = NULL;
  597. + }
  598. +
  599. + return 0;
  600. +}
  601. +
  602. +/**
  603. + * Seek in the DVD. Only used for chapters seek, not seeking in the
  604. + * VOB (PTS seek) itself.
  605. + */
  606. +/*
  607. +static int64_t dvd_read_seek(URLContext *h, int stream_index, int64_t pos, int flags)
  608. +{
  609. + av_unused dvdnav_status_t res;
  610. + av_unused int64_t loop;
  611. + DVDContext *dvd = (DVDContext *)h->priv_data;
  612. +
  613. + if (!dvd)
  614. + return AVERROR(EFAULT);
  615. +
  616. + if ((flags & (AVSEEK_FLAG_CHAPTER|AVSEEK_FLAG_BACKWARD)) == (AVSEEK_FLAG_CHAPTER|AVSEEK_FLAG_BACKWARD)) {
  617. + for (loop = 0; loop < pos; loop++)
  618. + res = dvdnav_prev_pg_search(dvd->nav_data);
  619. + } else if ((flags & AVSEEK_FLAG_CHAPTER) == AVSEEK_FLAG_CHAPTER) {
  620. + for (loop = 0; loop < pos; loop++)
  621. + res = dvdnav_next_pg_search(dvd->nav_data);
  622. + } else if (flags & AVSEEK_FLAG_DIRECT) {
  623. + // time 90000 to dvd time
  624. + res = dvdnav_time_search(dvd->nav_data, pos * 90000);
  625. + }
  626. +
  627. + return 0;
  628. +
  629. +}
  630. +*/
  631. +/* Seek in the dvd. Used for seeking in the vob (pts seek) itself */
  632. +static int64_t dvd_seek(URLContext *h, int64_t pos, int whence)
  633. +{
  634. + dvdnav_status_t res;
  635. + uint32_t pos2 = pos, len;
  636. +
  637. + /* get our data */
  638. + DVDContext *dvd = (DVDContext *)h->priv_data;
  639. + if (!dvd)
  640. + return AVERROR(EFAULT);
  641. +
  642. + /* get current position */
  643. + res = dvdnav_get_position(dvd->nav_data, &pos2, &len);
  644. + av_log(h,0,"The length of the current block is %d\n",len);
  645. + if (res != DVDNAV_STATUS_OK)
  646. + return -1;
  647. +
  648. + switch (whence) {
  649. + case SEEK_SET:
  650. + case SEEK_CUR:
  651. + case SEEK_END:
  652. + if (whence == SEEK_END && pos2 == -1)
  653. + return len * 2048;
  654. + res = dvdnav_sector_search(dvd->nav_data, pos2 / 2048, whence);
  655. + return pos2;
  656. + break;
  657. +
  658. + case AVSEEK_SIZE:
  659. + return len * 2048;
  660. +/*
  661. + case AVSEEK_CHAPTER:
  662. + /* /\* set the PGC positioning flag to have position information */
  663. + /* * relatively to whole dvd *\/ */
  664. +/* if (dvdnav_set_PGC_positioning_flag(dvd->nav_data, 1) != DVDNAV_STATUS_OK)
  665. + return -1;
  666. +
  667. + res = dvdnav_sector_search(dvd->nav_data, pos, SEEK_CUR);
  668. + */
  669. + /* /\* set the PGC positioning flag to have position information */
  670. + /* * relatively to whole chapter *\/ */
  671. + /* if (dvdnav_set_PGC_positioning_flag(dvd->nav_data, 0) != DVDNAV_STATUS_OK)
  672. + return -1;
  673. + */
  674. + }
  675. +
  676. + return -1;
  677. +}
  678. +
  679. +/* Select a button */
  680. +static void dvd_protocol_select_button(AVFormatContext *ctx, uint32_t index)
  681. +{
  682. + URLContext *h = (ctx->pb)->opaque;
  683. + DVDContext *dvd;
  684. + pci_t *pci;
  685. +
  686. + if (!h || !h->priv_data)
  687. + return;
  688. + dvd = (DVDContext *)(h->priv_data);
  689. +
  690. + pci = dvdnav_get_current_nav_pci(dvd->nav_data);
  691. + if (pci)
  692. + dvdnav_button_select_and_activate(dvd->nav_data, pci, index+1);
  693. +}
  694. +
  695. +/**
  696. + * Say if the queue is empty.
  697. + */
  698. +static void dvd_protocol_signal_queue(AVFormatContext *ctx)
  699. +{
  700. + DVDContext *dvd;
  701. + URLContext *h = (ctx->pb)->opaque;
  702. +
  703. + if (!h || !h->priv_data)
  704. + return;
  705. +
  706. + dvd = (DVDContext *)h->priv_data;
  707. + dvdnav_wait_skip(dvd->nav_data);
  708. +}
  709. +
  710. +
  711. +URLProtocol ff_dvd_protocol = {
  712. + .name = "dvd",
  713. + .url_close = dvd_close,
  714. + .url_open = dvd_open,
  715. + .url_read = dvd_read,
  716. + .url_seek = dvd_seek,
  717. + .priv_data_size = sizeof(DVDContext),
  718. +};
Advertisement
Add Comment
Please, Sign In to add comment