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.

172 lines
3.5KB

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