You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
3.6KB

  1. #include "errno.h"
  2. #include "avcodec.h"
  3. #ifndef MKTAG
  4. #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
  5. #endif
  6. // private structure used to hide all internal memory allocations
  7. // and structures used for de/encoding - end user should
  8. // never see any complicated structure
  9. typedef struct private_handle
  10. {
  11. AVCodec* avcodec;
  12. AVCodecContext avcontext;
  13. struct private_handle* next;
  14. struct private_handle* prev;
  15. } private_handle_t;
  16. static private_handle_t* handle_first = 0;
  17. static AVCodec* avcodec_find_by_fcc(uint32_t fcc)
  18. {
  19. // translation table
  20. static const struct fcc_to_avcodecid {
  21. enum CodecID codec;
  22. uint32_t list[4]; // maybe we could map more fcc to same codec
  23. } lc[] = {
  24. { CODEC_ID_H263, { MKTAG('U', '2', '6', '3'), 0 } },
  25. { CODEC_ID_H263I, { MKTAG('I', '2', '6', '3'), 0 } },
  26. { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
  27. { CODEC_ID_MPEG4, { MKTAG('D', 'I', 'V', 'X'), MKTAG('D', 'X', '5', '0'), 0 } },
  28. { CODEC_ID_MSMPEG4V2, { MKTAG('M', 'P', '4', '2'), 0 } },
  29. { CODEC_ID_MJPEG, { MKTAG('M', 'J', 'P', 'G'), 0 } },
  30. { CODEC_ID_MPEG1VIDEO, { MKTAG('P', 'I', 'M', '1'), 0 } },
  31. { CODEC_ID_AC3, { 0x2000, 0 } },
  32. { CODEC_ID_MP2, { 0x50, 0x55, 0 } },
  33. { CODEC_ID_NONE, {0}}
  34. };
  35. const struct fcc_to_avcodecid* c;
  36. for (c = lc; c->codec != CODEC_ID_NONE; c++)
  37. {
  38. int i = 0;
  39. while (c->list[i] != 0)
  40. if (c->list[i++] == fcc)
  41. return avcodec_find_decoder(c->codec);
  42. }
  43. return NULL;
  44. }
  45. static private_handle_t* create_handle()
  46. {
  47. private_handle_t* t = malloc(sizeof(private_handle_t));
  48. if (!t)
  49. return NULL;
  50. memset(t, 0, sizeof(*t));
  51. // register and fill
  52. if (!handle_first)
  53. {
  54. avcodec_init();
  55. avcodec_register_all();
  56. handle_first = t;
  57. }
  58. else
  59. {
  60. t->prev = handle_first->next;
  61. handle_first->next = t;
  62. t->next = handle_first;
  63. }
  64. return t;
  65. }
  66. static void destroy_handle(private_handle_t* handle)
  67. {
  68. if (handle)
  69. {
  70. if (handle->avcodec)
  71. {
  72. avcodec_close(&handle->avcontext);
  73. }
  74. free(handle);
  75. // count referencies
  76. }
  77. }
  78. int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
  79. {
  80. AVCodecContext* ctx = handle;
  81. switch (cmd)
  82. {
  83. case AVC_OPEN_BY_NAME:
  84. {
  85. // pin char* codec name
  86. private_handle_t* handle = create_handle();
  87. (private_handle_t**)pout = handle;
  88. if (!handle)
  89. return -ENOMEM;
  90. if (!handle->avcodec)
  91. {
  92. destroy_handle(handle);
  93. (private_handle_t**)pout = NULL;
  94. return -1;// better error
  95. }
  96. return 0;
  97. }
  98. case AVC_OPEN_BY_CODEC_ID:
  99. {
  100. // pin uint32_t codec fourcc
  101. private_handle_t* handle = create_handle();
  102. (private_handle_t**)pout = handle;
  103. if (!handle)
  104. return -ENOMEM;
  105. if (!handle->avcodec)
  106. {
  107. destroy_handle(handle);
  108. (private_handle_t**)pout = NULL;
  109. return -1;// better error
  110. }
  111. return 0;
  112. }
  113. case AVC_OPEN_BY_FOURCC:
  114. {
  115. // pin uint32_t codec fourcc
  116. private_handle_t* handle = create_handle();
  117. (private_handle_t**)pout = handle;
  118. if (!handle)
  119. return -ENOMEM;
  120. handle->avcodec = avcodec_find_by_fcc((uint32_t) pin);
  121. if (!handle->avcodec)
  122. {
  123. destroy_handle(handle);
  124. (private_handle_t**)pout = NULL;
  125. return -1;// better error
  126. }
  127. return 0;
  128. }
  129. case AVC_CLOSE:
  130. // uninit part
  131. // eventually close all allocated space if this was last
  132. // instance
  133. destroy_handle(handle);
  134. break;
  135. case AVC_FLUSH:
  136. break;
  137. case AVC_DECODE:
  138. break;
  139. case AVC_ENCODE:
  140. break;
  141. case AVC_GET_VERSION:
  142. (int*) pout = 500;
  143. default:
  144. return -1;
  145. }
  146. return 0;
  147. }