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.

174 lines
3.6KB

  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_DTS, { 0x10, 0 } },
  37. { CODEC_ID_MP2, { 0x50, 0x55, 0 } },
  38. { CODEC_ID_FLV1, { MKTAG('F', 'L', 'V', '1'), 0 } },
  39. { CODEC_ID_NONE, {0}}
  40. };
  41. const struct fcc_to_avcodecid* c;
  42. for (c = lc; c->codec != CODEC_ID_NONE; c++)
  43. {
  44. int i = 0;
  45. while (c->list[i] != 0)
  46. if (c->list[i++] == fcc)
  47. return avcodec_find_decoder(c->codec);
  48. }
  49. return NULL;
  50. }
  51. static private_handle_t* create_handle(void)
  52. {
  53. private_handle_t* t = av_malloc(sizeof(private_handle_t));
  54. if (!t)
  55. return NULL;
  56. memset(t, 0, sizeof(*t));
  57. // register and fill
  58. if (!handle_first)
  59. {
  60. avcodec_init();
  61. avcodec_register_all();
  62. handle_first = t;
  63. }
  64. else
  65. {
  66. t->prev = handle_first->next;
  67. handle_first->next = t;
  68. t->next = handle_first;
  69. }
  70. return t;
  71. }
  72. static void destroy_handle(private_handle_t* handle)
  73. {
  74. if (handle)
  75. {
  76. if (handle->avcodec)
  77. {
  78. avcodec_close(&handle->avcontext);
  79. }
  80. av_free(handle);
  81. // count referencies
  82. }
  83. }
  84. int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
  85. {
  86. AVCodecContext* ctx = handle;
  87. switch (cmd)
  88. {
  89. case AVC_OPEN_BY_NAME:
  90. {
  91. // pin char* codec name
  92. private_handle_t* h = create_handle();
  93. (private_handle_t**)pout = h;
  94. if (!h)
  95. return -ENOMEM;
  96. if (!h->avcodec)
  97. {
  98. destroy_handle(h);
  99. (private_handle_t**)pout = NULL;
  100. return -1;// better error
  101. }
  102. return 0;
  103. }
  104. case AVC_OPEN_BY_CODEC_ID:
  105. {
  106. // pin uint32_t codec fourcc
  107. private_handle_t* h = create_handle();
  108. (private_handle_t**)pout = h;
  109. if (!h)
  110. return -ENOMEM;
  111. if (!h->avcodec)
  112. {
  113. destroy_handle(h);
  114. (private_handle_t**)pout = NULL;
  115. return -1;// better error
  116. }
  117. return 0;
  118. }
  119. case AVC_OPEN_BY_FOURCC:
  120. {
  121. // pin uint32_t codec fourcc
  122. private_handle_t* h = create_handle();
  123. (private_handle_t**)pout = h;
  124. if (!h)
  125. return -ENOMEM;
  126. h->avcodec = avcodec_find_by_fcc((uint32_t) pin);
  127. if (!h->avcodec)
  128. {
  129. destroy_handle(h);
  130. (private_handle_t**)pout = NULL;
  131. return -1;// better error
  132. }
  133. return 0;
  134. }
  135. case AVC_CLOSE:
  136. // uninit part
  137. // eventually close all allocated space if this was last
  138. // instance
  139. destroy_handle(handle);
  140. break;
  141. case AVC_FLUSH:
  142. break;
  143. case AVC_DECODE:
  144. break;
  145. case AVC_ENCODE:
  146. break;
  147. case AVC_GET_VERSION:
  148. (int*) pout = 500;
  149. default:
  150. return -1;
  151. }
  152. return 0;
  153. }