Guest User

Untitled

a guest
Dec 28th, 2014
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.80 KB | None | 0 0
  1. commit 71d92eb59d043fddbf1255194c01b0ff277f8c6c
  2. Author: Eejya Singh <[email protected]>
  3. Date: Mon Dec 15 18:57:31 2014 +0530
  4.  
  5. DVD input device
  6.  
  7. diff --git a/configure b/configure
  8. index 40d5428..6e7ffbd 100755
  9. --- a/configure
  10. +++ b/configure
  11. @@ -1350,6 +1350,7 @@ EXTERNAL_LIBRARY_LIST="
  12. libcdio
  13. libcelt
  14. libdc1394
  15. + libdvdnav
  16. libfaac
  17. libfdk_aac
  18. libflite
  19. @@ -2485,6 +2486,7 @@ dshow_indev_deps="IBaseFilter"
  20. dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid"
  21. dv1394_indev_deps="dv1394"
  22. dv1394_indev_select="dv_demuxer"
  23. +dvd_indev_deps="libdvdnav"
  24. fbdev_indev_deps="linux_fb_h"
  25. fbdev_outdev_deps="linux_fb_h"
  26. gdigrab_indev_deps="CreateDIBSection"
  27. @@ -4858,6 +4860,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
  28. { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 ||
  29. die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
  30. enabled libcaca && require_pkg_config caca caca.h caca_create_canvas
  31. +enabled libdvdnav && require_pkg_config dvdnav dvdnav/dvdnav.h dvdnav_open -ldvdnav -lpthread
  32. enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
  33. enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
  34. flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
  35. diff --git a/libavdevice/Makefile b/libavdevice/Makefile
  36. index 6b8ab2e..ef0ce60 100644
  37. --- a/libavdevice/Makefile
  38. +++ b/libavdevice/Makefile
  39. @@ -22,6 +22,7 @@ OBJS-$(CONFIG_DSHOW_INDEV) += dshow.o dshow_enummediatypes.o \
  40. dshow_enumpins.o dshow_filter.o \
  41. dshow_pin.o dshow_common.o
  42. OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o
  43. +OBJS-$(CONFIG_DVD_INDEV) += dvd-dec.o
  44. OBJS-$(CONFIG_FBDEV_INDEV) += fbdev_dec.o \
  45. fbdev_common.o
  46. OBJS-$(CONFIG_FBDEV_OUTDEV) += fbdev_enc.o \
  47. diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
  48. index 26aecf2..dd125df 100644
  49. --- a/libavdevice/alldevices.c
  50. +++ b/libavdevice/alldevices.c
  51. @@ -53,6 +53,7 @@ void avdevice_register_all(void)
  52. REGISTER_INOUTDEV(DECKLINK, decklink);
  53. REGISTER_INDEV (DSHOW, dshow);
  54. REGISTER_INDEV (DV1394, dv1394);
  55. + REGISTER_INDEV (DVD, dvd);
  56. REGISTER_INOUTDEV(FBDEV, fbdev);
  57. REGISTER_INDEV (GDIGRAB, gdigrab);
  58. REGISTER_INDEV (IEC61883, iec61883);
  59. diff --git a/libavdevice/dvd-dec.c b/libavdevice/dvd-dec.c
  60. new file mode 100644
  61. index 0000000..4795da0
  62. --- /dev/null
  63. +++ b/libavdevice/dvd-dec.c
  64. @@ -0,0 +1,360 @@
  65. +/*
  66. + * Copyright (c) 2014 Eejya Singh
  67. + *
  68. + * This file is part of FFmpeg.
  69. + *
  70. + * Permission to use, copy, modify, and/or distribute this software for any
  71. + * purpose with or without fee is hereby granted, provided that the above
  72. + * copyright notice and this permission notice appear in all copies.
  73. + *
  74. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  75. + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  76. + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  77. + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  78. + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  79. + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  80. + * PERFORMANCE OF THIS SOFTWARE.
  81. + */
  82. +
  83. +/**
  84. + * @file
  85. + * DVD 1.1 capture device for libavdevice
  86. + **/
  87. +
  88. +#include "libavutil/opt.h"
  89. +#include "libavutil/time.h"
  90. +#include "libavformat/internal.h"
  91. +#include "avdevice.h"
  92. +
  93. +#include <dvdnav/dvdnav.h>
  94. +#include <dvdnav/dvd_types.h>
  95. +
  96. +
  97. +/* libdvdnav's read ahead cache to be used */
  98. +#define DVD_READ_CACHE 1
  99. +
  100. +/* default language for menus/audio/subpictures */
  101. +#define DVD_LANGUAGE "en"
  102. +
  103. +typedef struct {
  104. + dvdnav_t *nav_data;
  105. + uint8_t cache_buf[DVD_VIDEO_LB_LEN];
  106. + char *language;
  107. + dvdnav_status_t status;
  108. + /*Sample Rate of the audio in the DVD (in Hz) */
  109. + int sample_rate;
  110. +} DVDContext;
  111. +
  112. +
  113. +static int read_header(AVFormatContext *ctx)
  114. +{
  115. + AVStream *st_audio = NULL;
  116. + AVStream *st_video = NULL;
  117. + AVStream *st_subp = NULL;
  118. + int audio_stream,spu_stream;
  119. + DVDContext *dvd = ctx->priv_data;
  120. + uint32_t width = 0 , height = 0, i_width, i_height;
  121. + uint8_t stream,stream_format;
  122. + uint8_t mem[DVD_VIDEO_LB_LEN];
  123. + int dump = 0, tt_dump = 0, finished = 0;
  124. + int result, event, len;
  125. + uint8_t *buf = mem;
  126. +
  127. + if((dvd->status = dvdnav_open(&dvd->nav_data,ctx->filename[0] ? ctx->filename : NULL)) != DVDNAV_STATUS_OK)
  128. + {
  129. + return AVERROR(EIO);
  130. + }
  131. + dvd->language = av_strdup(DVD_LANGUAGE);
  132. +
  133. + /* set read ahead cache usage */
  134. + if (dvdnav_set_readahead_flag(dvd->nav_data, DVD_READ_CACHE) != DVDNAV_STATUS_OK) {
  135. + dvdnav_close(dvd->nav_data);
  136. + return AVERROR(EACCES);
  137. + }
  138. +
  139. + /* set the language */
  140. + if ((dvdnav_menu_language_select (dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK) ||
  141. + (dvdnav_audio_language_select(dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK) ||
  142. + (dvdnav_spu_language_select (dvd->nav_data, dvd->language) != DVDNAV_STATUS_OK)) {
  143. + av_log(ctx, AV_LOG_ERROR, "Error selecting language\n");
  144. + return AVERROR(EACCES);
  145. + }
  146. +
  147. +
  148. + /*set the PGC positioning flag to have position information relatively to the
  149. + *current chapter (seek will seek in the chapter) */
  150. + if (dvdnav_set_PGC_positioning_flag(dvd->nav_data, 0) != DVDNAV_STATUS_OK) {
  151. + av_log(ctx, AV_LOG_ERROR, "Error setting PGC positioning flags\n");
  152. + dvdnav_close(dvd->nav_data);
  153. + return AVERROR(EACCES);
  154. + }
  155. +
  156. + while (!finished) {
  157. +
  158. + /* the main reading function */
  159. + #if DVD_READ_CACHE
  160. + result = dvdnav_get_next_cache_block(dvd->nav_data, &buf, &event, &len);
  161. + #else
  162. + result = dvdnav_get_next_block(dvd->nav_data, buf, &event, &len);
  163. + #endif
  164. + if (result == DVDNAV_STATUS_ERR) {
  165. + printf("Error getting next block: %s\n", dvdnav_err_to_string(dvd->nav_data));
  166. + return 3;
  167. + }
  168. +
  169. + switch (event) {
  170. + case DVDNAV_BLOCK_OK:
  171. + /* We have received a regular block of the currently playing MPEG stream.
  172. + * A real player application would now pass this block through demuxing
  173. + * and decoding. We simply write it to disc here. */
  174. + break;
  175. + case DVDNAV_NOP:
  176. + /* Nothing to do here. */
  177. + break;
  178. + case DVDNAV_STILL_FRAME:
  179. + /* We have reached a still frame. A real player application would wait
  180. + * the amount of time specified by the still's length while still handling
  181. + * user input to make menus and other interactive stills work.
  182. + * A length of 0xff means an indefinite still which has to be skipped
  183. + * indirectly by some user interaction. */
  184. + {
  185. + dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)buf;
  186. + if (still_event->length < 0xff)
  187. + av_log(ctx, 0 ,"Skipping %d seconds of still frame\n", still_event->length);
  188. + else
  189. + av_log(ctx, 0 ,"Skipping indefinite length still frame\n");
  190. + dvdnav_still_skip(dvd->nav_data);
  191. + }
  192. + break;
  193. + case DVDNAV_WAIT:
  194. + /* We have reached a point in DVD playback, where timing is critical.
  195. + * Player application with internal fifos can introduce state
  196. + * inconsistencies, because libdvdnav is always the fifo's length
  197. + * ahead in the stream compared to what the application sees.
  198. + * Such applications should wait until their fifos are empty
  199. + * when they receive this type of event. */
  200. + {
  201. + av_log(ctx, 0 ,"Skipping wait condition\n");
  202. + dvdnav_wait_skip(dvd->nav_data);
  203. + }
  204. + break;
  205. + case DVDNAV_SPU_CLUT_CHANGE:
  206. + /* Player applications should pass the new colour lookup table to their
  207. + * SPU decoder */
  208. + break;
  209. + case DVDNAV_SPU_STREAM_CHANGE:
  210. + /* Player applications should inform their SPU decoder to switch channels */
  211. + av_log(ctx, 0 ,"SubPicture Stream Change \n");
  212. + break;
  213. + case DVDNAV_AUDIO_STREAM_CHANGE:
  214. + /* Player applications should inform their audio decoder to switch channels */
  215. + av_log(ctx, 0 ,"Audio Stream Change \n");
  216. + break;
  217. + case DVDNAV_HIGHLIGHT:
  218. + /* Player applications should inform their overlay engine to highlight the
  219. + * given button */
  220. + {
  221. + dvdnav_highlight_event_t *highlight_event = (dvdnav_highlight_event_t *)buf;
  222. + av_log(ctx , 0 ,"Selected button %d\n", highlight_event->buttonN);
  223. + }
  224. + break;
  225. + case DVDNAV_VTS_CHANGE:
  226. + /* Some status information like video aspect and video scale permissions do
  227. + * not change inside a VTS. Therefore this event can be used to query such
  228. + * information only when necessary and update the decoding/displaying
  229. + * accordingly. */
  230. + {
  231. + if( dvdnav_get_video_resolution(dvd->nav_data,&i_width, &i_height ) )
  232. + i_width = i_height = 0;
  233. + switch( dvdnav_get_video_aspect(dvd->nav_data) )
  234. + {
  235. + case 0:
  236. + height = 4 * i_height;
  237. + width = 3 * i_width;
  238. + break;
  239. + case 3:
  240. + height = 16 * i_height;
  241. + width = 9 * i_width;
  242. + break;
  243. + default:
  244. + height = 0;
  245. + width = 0;
  246. + break;
  247. + }
  248. + }
  249. +
  250. + break;
  251. + case DVDNAV_CELL_CHANGE:
  252. + /* Some status information like the current Title and Part numbers do not
  253. + * change inside a cell. Therefore this event can be used to query such
  254. + * information only when necessary and update the decoding/displaying
  255. + * accordingly. */
  256. + {
  257. + int tt = 0, ptt = 0, pos, len; //Title and part number
  258. + char input = '\0';
  259. +
  260. + dvdnav_current_title_info(dvd->nav_data, &tt, &ptt);
  261. + dvdnav_get_position(dvd->nav_data, &pos, &len);
  262. + av_log(ctx , 0 ,"Cell change: Title %d, Chapter %d\n", tt, ptt);
  263. + av_log(ctx , 0 ,"At position %.0f%% inside the feature\n", 100 * (double)pos / (double)len);
  264. +
  265. + dump = 0;
  266. + if (tt_dump && tt != tt_dump)
  267. + tt_dump = 0;
  268. +
  269. + if (!dump && !tt_dump) {
  270. + fflush(stdin);
  271. + av_log(ctx , 0 ,"(a)ppend cell to output\n(s)kip cell\nappend until end of (t)itle\n(q)uit\n");
  272. + input='a';
  273. + switch (input) {
  274. + case 'a':
  275. + dump = 1;
  276. + av_log(ctx,0,"Input is appending cell to output\n");
  277. + break;
  278. + case 't':
  279. + tt_dump = tt;
  280. + av_log(ctx,0,"Skipping current cell\n");
  281. + break;
  282. + case 'q':
  283. + finished = 1;
  284. + av_log(ctx,0,"Quit\n");
  285. + }
  286. +
  287. + }
  288. + }
  289. + break;
  290. + case DVDNAV_NAV_PACKET:
  291. + /* A NAV packet provides PTS discontinuity information, angle linking information and
  292. + * button definitions for DVD menus. Angles are handled completely inside libdvdnav.
  293. + * For the menus to work, the NAV packet information has to be passed to the overlay
  294. + * engine of the player so that it knows the dimensions of the button areas. */
  295. + {
  296. + pci_t *pci;
  297. + dsi_t *dsi;
  298. +
  299. + /* Applications with fifos should not use these functions to retrieve NAV packets,
  300. + * they should implement their own NAV handling, because the packet you get from these
  301. + * functions will already be ahead in the stream which can cause state inconsistencies.
  302. + * Applications with fifos should therefore pass the NAV packet through the fifo
  303. + * and decoding pipeline just like any other data. */
  304. + pci = dvdnav_get_current_nav_pci(dvd->nav_data);
  305. + dsi = dvdnav_get_current_nav_dsi(dvd->nav_data);
  306. +
  307. + if(pci->hli.hl_gi.btn_ns > 0) {
  308. + int button;
  309. +
  310. + av_log(ctx, 0 ,"Found %i DVD menu buttons...\n", pci->hli.hl_gi.btn_ns);
  311. +
  312. + for (button = 0; button < pci->hli.hl_gi.btn_ns; button++) {
  313. + btni_t *btni = &(pci->hli.btnit[button]);
  314. + av_log(ctx, 0 ,"Button %i top-left @ (%i,%i), bottom-right @ (%i,%i)\n",
  315. + button + 1, btni->x_start, btni->y_start,
  316. + btni->x_end, btni->y_end);
  317. + }
  318. +
  319. + button = 0;
  320. + while ((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) {
  321. + av_log(ctx, 0 ,"Which button (1 to %i): ", pci->hli.hl_gi.btn_ns);
  322. + //scanf("%i", &button);
  323. + button++;
  324. + }
  325. +
  326. + av_log(ctx, 0 ,"Selecting button %i...\n", button);
  327. + /* This is the point where applications with fifos have to hand in a NAV packet
  328. + * which has traveled through the fifos. See the notes above. */
  329. + dvdnav_button_select_and_activate(dvd->nav_data, pci, button);
  330. + }
  331. + }
  332. + break;
  333. + case DVDNAV_HOP_CHANNEL:
  334. + /* This event is issued whenever a non-seamless operation has been executed.
  335. + * Applications with fifos should drop the fifos content to speed up responsiveness. */
  336. + break;
  337. + case DVDNAV_STOP:
  338. + /* Playback should end here. */
  339. + {
  340. + finished = 1;
  341. + av_log(ctx,0,"Stopping Playback\n");
  342. + }
  343. + break;
  344. + default:
  345. + av_log(ctx, 0 ,"Unknown event (%i)\n", event);
  346. + finished = 1;
  347. + break;
  348. +}
  349. + #if DVD_READ_CACHE
  350. + if(dvdnav_free_cache_block(dvd->nav_data, buf) != DVDNAV_STATUS_OK)
  351. + {
  352. + av_log(ctx,0,"Error freeing the buffer");
  353. + return 5;
  354. + }
  355. + #endif
  356. +
  357. +}
  358. +
  359. + /*Setting the codec IDs and other attributes*/
  360. +/*
  361. + st_video = avformat_new_stream(ctx, NULL);
  362. + st_audio = avformat_new_stream(ctx, NULL);
  363. + st_subp = avformat_new_stream(ctx, NULL);
  364. +
  365. + if (!st_video)
  366. + return AVERROR(ENOMEM);
  367. + avpriv_set_pts_info(st_video, 64, 1, 100); //pts information in seconds at max??
  368. + st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  369. + st_video->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO;
  370. + st_video->codec->width = width;
  371. + st_video->codec->height = height;
  372. + av_log(ctx,0,"Height and Width are %d and %d\n", height , width);
  373. +
  374. + if (!st_audio)
  375. + return AVERROR(ENOMEM);
  376. + avpriv_set_pts_info(st_audio, 64, 1, 100);
  377. + st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  378. + st_audio->codec->codec_id = AV_CODEC_ID_AC3;
  379. +
  380. + av_log(ctx,0,"Audio Check !");
  381. + if (!st_subp)
  382. + return AVERROR(ENOMEM);
  383. + avpriv_set_pts_info(st_subp, 64, 1, 100);
  384. + st_subp->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
  385. + st_subp->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
  386. + av_log(ctx,0,"Subp Check !");
  387. +*/
  388. + return 0;
  389. +}
  390. +
  391. +static int read_packet(AVFormatContext* ctx, AVPacket *pkt)
  392. +{
  393. + return pkt->size;
  394. +}
  395. +
  396. +static int read_close(AVFormatContext* ctx)
  397. +{
  398. + av_log(ctx,0,"Closing the DVD structure");
  399. + DVDContext *dvd = (DVDContext *)ctx->priv_data;
  400. + if (dvd->status && dvd->nav_data != NULL) {
  401. + dvdnav_close(dvd->nav_data);
  402. + }
  403. + return 0;
  404. +}
  405. +
  406. +static const AVClass class = {
  407. + .class_name = "dvd",
  408. + .item_name = av_default_item_name,
  409. +// .option = options,
  410. + .version = LIBAVUTIL_VERSION_INT,
  411. + .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT,
  412. +};
  413. +
  414. +AVInputFormat ff_dvd_demuxer = {
  415. + .name = "dvd",
  416. + .long_name = NULL_IF_CONFIG_SMALL("DVD audio video capture device"),
  417. + .priv_data_size = sizeof(DVDContext),
  418. + .read_probe = NULL,
  419. + .read_header = read_header,
  420. + .read_packet = read_packet,
  421. + .read_close = read_close,
  422. + .flags = AVFMT_NOFILE,
  423. + .priv_class = &class
  424. +};
Advertisement
Add Comment
Please, Sign In to add comment