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.

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