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.

151 lines
3.3KB

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