/local_src/libs/libeplayer3/output/output.c

https://bitbucket.org/Taapat/stlinux.bsp-duckbox · C · 353 lines · 263 code · 33 blank · 57 comment · 103 complexity · 5cca0195d959e7392c8de75c3a8934af MD5 · raw file

  1. /*
  2. * Output handling.
  3. *
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. /* ***************************** */
  21. /* Includes */
  22. /* ***************************** */
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include "common.h"
  26. #include "output.h"
  27. /* ***************************** */
  28. /* Makros/Constants */
  29. /* ***************************** */
  30. #define OUTPUT_DEBUG
  31. #ifdef OUTPUT_DEBUG
  32. static short debug_level = 0;
  33. #define output_printf(level, x...) do { \
  34. if (debug_level >= level) printf(x); } while (0)
  35. #else
  36. #define output_printf(level, x...)
  37. #endif
  38. #ifndef OUTPUT_SILENT
  39. #define output_err(x...) do { printf(x); } while (0)
  40. #else
  41. #define output_err(x...)
  42. #endif
  43. /* Error Constants */
  44. #define cERR_OUTPUT_NO_ERROR 0
  45. #define cERR_OUTPUT_INTERNAL_ERROR -1
  46. static const char* FILENAME = __FILE__;
  47. /* ***************************** */
  48. /* Types */
  49. /* ***************************** */
  50. /* ***************************** */
  51. /* Varaibles */
  52. /* ***************************** */
  53. /* ***************************** */
  54. /* Prototypes */
  55. /* ***************************** */
  56. /* ***************************** */
  57. /* MISC Functions */
  58. /* ***************************** */
  59. static void printOutputCapabilities() {
  60. int i, j;
  61. output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
  62. output_printf(10, "Capabilities:\n");
  63. for (i = 0; AvailableOutput[i] != NULL; i++) {
  64. output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
  65. for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
  66. output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]);
  67. output_printf(10, "\n");
  68. }
  69. }
  70. /* ***************************** */
  71. /* Output Functions */
  72. /* ***************************** */
  73. static void OutputAdd(Context_t *context, char * port) {
  74. int i, j;
  75. output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
  76. for (i = 0; AvailableOutput[i] != NULL; i++)
  77. for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
  78. if (!strcmp(AvailableOutput[i]->Capabilities[j], port)) {
  79. if (!strcmp("audio", port))
  80. context->output->audio = AvailableOutput[i];
  81. else if (!strcmp("video", port))
  82. context->output->video = AvailableOutput[i];
  83. else if (!strcmp("subtitle", port))
  84. context->output->subtitle = AvailableOutput[i];
  85. break;
  86. }
  87. }
  88. static void OutputDel(Context_t *context, char * port) {
  89. output_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
  90. if (!strcmp("audio", port))
  91. context->output->audio = NULL;
  92. else if (!strcmp("video", port))
  93. context->output->video = NULL;
  94. else if (!strcmp("subtitle", port))
  95. context->output->subtitle = NULL;
  96. }
  97. static int Command(void *_context, OutputCmd_t command, void * argument) {
  98. Context_t *context = (Context_t*) _context;
  99. int ret = cERR_OUTPUT_NO_ERROR;
  100. output_printf(10, "%s::%s Command %d\n", FILENAME, __FUNCTION__, command);
  101. switch(command) {
  102. case OUTPUT_OPEN: {
  103. if (context && context->playback ) {
  104. if (context->playback->isVideo)
  105. ret |= context->output->video->Command(context, OUTPUT_OPEN, "video");
  106. if (context->playback->isAudio)
  107. ret |= context->output->audio->Command(context, OUTPUT_OPEN, "audio");
  108. if (context->playback->isSubtitle)
  109. ret |= context->output->subtitle->Command(context, OUTPUT_OPEN, "subtitle");
  110. } else
  111. ret = cERR_OUTPUT_INTERNAL_ERROR;
  112. break;
  113. }
  114. case OUTPUT_CLOSE: {
  115. if (context && context->playback ) {
  116. if (context->playback->isVideo)
  117. ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video");
  118. if (context->playback->isAudio)
  119. ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio");
  120. if (context->playback->isSubtitle)
  121. ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle");
  122. } else
  123. ret = cERR_OUTPUT_INTERNAL_ERROR;
  124. break;
  125. }
  126. case OUTPUT_ADD: {
  127. OutputAdd(context, (char*) argument);
  128. break;
  129. }
  130. case OUTPUT_DEL: {
  131. OutputDel(context, (char*) argument);
  132. break;
  133. }
  134. case OUTPUT_CAPABILITIES: {
  135. printOutputCapabilities();
  136. break;
  137. }
  138. case OUTPUT_PLAY: { // 4
  139. if (context && context->playback ) {
  140. if (context->playback->isVideo)
  141. ret = context->output->video->Command(context, OUTPUT_PLAY, "video");
  142. if (!ret) { // success or not executed, dunn care
  143. if (context->playback->isAudio)
  144. ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio");
  145. if (!ret) { // success or not executed, dunn care
  146. if (context->playback->isSubtitle)
  147. ret = context->output->subtitle->Command(context, OUTPUT_PLAY, "subtitle");
  148. }
  149. }
  150. } else
  151. ret = cERR_OUTPUT_INTERNAL_ERROR;
  152. break;
  153. }
  154. case OUTPUT_STOP: {
  155. if (context && context->playback ) {
  156. if (context->playback->isVideo)
  157. ret |= context->output->video->Command(context, OUTPUT_STOP, "video");
  158. if (context->playback->isAudio)
  159. ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio");
  160. if (context->playback->isSubtitle)
  161. ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle");
  162. } else
  163. ret = cERR_OUTPUT_INTERNAL_ERROR;
  164. break;
  165. }
  166. case OUTPUT_FLUSH: {
  167. if (context && context->playback ) {
  168. if (context->playback->isVideo)
  169. ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video");
  170. if (context->playback->isAudio)
  171. ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio");
  172. //if (context->playback->isSubtitle)
  173. // ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
  174. } else
  175. ret = cERR_OUTPUT_INTERNAL_ERROR;
  176. break;
  177. }
  178. case OUTPUT_PAUSE: {
  179. if (context && context->playback ) {
  180. if (context->playback->isVideo)
  181. ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video");
  182. if (context->playback->isAudio)
  183. ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio");
  184. //if (context->playback->isSubtitle)
  185. // ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
  186. } else
  187. ret = cERR_OUTPUT_INTERNAL_ERROR;
  188. break;
  189. }
  190. case OUTPUT_FASTFORWARD: {
  191. if (context && context->playback ) {
  192. if (context->playback->isVideo)
  193. ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video");
  194. if (context->playback->isAudio)
  195. ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio");
  196. //if (context->playback->isSubtitle)
  197. // ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
  198. } else
  199. ret = cERR_OUTPUT_INTERNAL_ERROR;
  200. break;
  201. }
  202. case OUTPUT_REVERSE: {
  203. if (context && context->playback ) {
  204. if (context->playback->isVideo)
  205. ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video");
  206. if (context->playback->isAudio)
  207. ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio");
  208. } else
  209. ret = cERR_OUTPUT_INTERNAL_ERROR;
  210. break;
  211. }
  212. case OUTPUT_CONTINUE: {
  213. if (context && context->playback ) {
  214. if (context->playback->isVideo)
  215. ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video");
  216. if (context->playback->isAudio)
  217. ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio");
  218. //if (context->playback->isSubtitle)
  219. // ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
  220. } else
  221. ret = cERR_OUTPUT_INTERNAL_ERROR;
  222. break;
  223. }
  224. case OUTPUT_AVSYNC: {
  225. if (context && context->playback ) {
  226. if (context->playback->isVideo && context->playback->isAudio)
  227. ret |= context->output->audio->Command(context, OUTPUT_AVSYNC, "audio");
  228. } else
  229. ret = cERR_OUTPUT_INTERNAL_ERROR;
  230. break;
  231. }
  232. case OUTPUT_CLEAR: {
  233. if (context && context->playback ) {
  234. if (context->playback->isVideo && (argument == NULL || *(char *) argument == 'v'))
  235. ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video");
  236. if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a'))
  237. ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio");
  238. //if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
  239. // ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
  240. } else
  241. ret = cERR_OUTPUT_INTERNAL_ERROR;
  242. break;
  243. }
  244. case OUTPUT_PTS: {
  245. if (context && context->playback ) {
  246. if (context->playback->isVideo)
  247. return context->output->video->Command(context, OUTPUT_PTS, argument);
  248. if (context->playback->isAudio)
  249. return context->output->audio->Command(context, OUTPUT_PTS, argument);
  250. //if (context->playback->isSubtitle)
  251. // return context->output->subtitle->Command(context, OUTPUT_PTS, "subtitle");
  252. } else
  253. ret = cERR_OUTPUT_INTERNAL_ERROR;
  254. break;
  255. }
  256. case OUTPUT_SWITCH: {
  257. if (context && context->playback ) {
  258. if (context->playback->isAudio)
  259. return context->output->audio->Command(context, OUTPUT_SWITCH, "audio");
  260. if (context->playback->isVideo)
  261. return context->output->video->Command(context, OUTPUT_SWITCH, "video");
  262. } else
  263. ret = cERR_OUTPUT_INTERNAL_ERROR;
  264. break;
  265. }
  266. case OUTPUT_SLOWMOTION: {
  267. if (context && context->playback ) {
  268. if (context->playback->isVideo)
  269. ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video");
  270. if (context->playback->isAudio)
  271. ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio");
  272. //if (context->playback->isSubtitle)
  273. // ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
  274. } else
  275. ret = cERR_OUTPUT_INTERNAL_ERROR;
  276. break;
  277. }
  278. case OUTPUT_AUDIOMUTE: {
  279. if (context && context->playback ) {
  280. if (context->playback->isAudio)
  281. ret |= context->output->audio->Command(context, OUTPUT_AUDIOMUTE, (char*) argument);
  282. } else
  283. ret = cERR_OUTPUT_INTERNAL_ERROR;
  284. break;
  285. }
  286. case OUTPUT_DISCONTINUITY_REVERSE: {
  287. if (context && context->playback ) {
  288. if (context->playback->isVideo)
  289. ret |= context->output->video->Command(context, OUTPUT_DISCONTINUITY_REVERSE, (void*) argument);
  290. } else
  291. ret = cERR_OUTPUT_INTERNAL_ERROR;
  292. break;
  293. }
  294. case OUTPUT_GET_FRAME_COUNT: {
  295. if (context && context->playback ) {
  296. if (context->playback->isVideo)
  297. return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
  298. if (context->playback->isAudio)
  299. return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
  300. //if (context->playback->isSubtitle)
  301. // return context->output->subtitle->Command(context, OUTPUT_GET_FRAME_COUNT, "subtitle");
  302. } else
  303. ret = cERR_OUTPUT_INTERNAL_ERROR;
  304. break;
  305. }
  306. default:
  307. output_err("%s::%s OutputCmd %d not supported!\n", FILENAME, __FUNCTION__, command);
  308. ret = cERR_OUTPUT_INTERNAL_ERROR;
  309. break;
  310. }
  311. output_printf(10, "%s::%s exiting with value %d\n", FILENAME, __FUNCTION__, ret);
  312. return ret;
  313. }
  314. OutputHandler_t OutputHandler = {
  315. "Output",
  316. NULL,
  317. NULL,
  318. NULL,
  319. &Command
  320. };