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.

101 lines
2.7KB

  1. #include "libavutil/opt.h"
  2. #include "libavutil/samplefmt.h"
  3. #include "avcodec.h"
  4. #include "ac3.h"
  5. typedef struct CombineContext{
  6. AVClass *av_class; ///< AVClass used for AVOption
  7. AC3EncOptions options; ///< encoding options
  8. void *ctx;
  9. AVCodec *codec;
  10. }CombineContext;
  11. #define OFFSET(param) offsetof(CombineContext, options.param)
  12. #define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
  13. #define AC3ENC_TYPE_AC3_FIXED 0
  14. #define AC3ENC_TYPE_AC3 1
  15. #define AC3ENC_TYPE_EAC3 2
  16. #define AC3ENC_TYPE 12354
  17. #include "ac3enc_opts_template.c"
  18. static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
  19. eac3_options, LIBAVUTIL_VERSION_INT };
  20. static av_cold AVCodec *get_codec(enum AVSampleFormat s){
  21. #if CONFIG_AC3_FIXED_ENCODER
  22. if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder;
  23. #endif
  24. #if CONFIG_AC3_FLOAT_ENCODER
  25. if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder;
  26. #endif
  27. return NULL;
  28. }
  29. static av_cold int encode_init(AVCodecContext *avctx)
  30. {
  31. CombineContext *c= avctx->priv_data;
  32. int ret;
  33. int offset= (uint8_t*)&c->options - (uint8_t*)c;
  34. c->codec= get_codec(avctx->sample_fmt);
  35. if(!c->codec){
  36. av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n");
  37. return -1;
  38. }
  39. c->ctx= av_mallocz(c->codec->priv_data_size);
  40. memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options);
  41. FFSWAP(void *,avctx->priv_data, c->ctx);
  42. ret= c->codec->init(avctx);
  43. FFSWAP(void *,avctx->priv_data, c->ctx);
  44. return ret;
  45. }
  46. static int encode_frame(AVCodecContext *avctx, unsigned char *frame,
  47. int buf_size, void *data)
  48. {
  49. CombineContext *c= avctx->priv_data;
  50. int ret;
  51. FFSWAP(void *,avctx->priv_data, c->ctx);
  52. ret= c->codec->encode(avctx, frame, buf_size, data);
  53. FFSWAP(void *,avctx->priv_data, c->ctx);
  54. return ret;
  55. }
  56. static av_cold int encode_close(AVCodecContext *avctx)
  57. {
  58. CombineContext *c= avctx->priv_data;
  59. int ret;
  60. FFSWAP(void *,avctx->priv_data, c->ctx);
  61. ret= c->codec->close(avctx);
  62. FFSWAP(void *,avctx->priv_data, c->ctx);
  63. return ret;
  64. }
  65. AVCodec ff_ac3_encoder = {
  66. "ac3",
  67. AVMEDIA_TYPE_AUDIO,
  68. CODEC_ID_AC3,
  69. sizeof(CombineContext),
  70. encode_init,
  71. encode_frame,
  72. encode_close,
  73. NULL,
  74. .sample_fmts = (const enum AVSampleFormat[]){
  75. #if CONFIG_AC3_FLOAT_ENCODER
  76. AV_SAMPLE_FMT_FLT,
  77. #endif
  78. #if CONFIG_AC3_FIXED_ENCODER
  79. AV_SAMPLE_FMT_S16,
  80. #endif
  81. AV_SAMPLE_FMT_NONE},
  82. .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
  83. .priv_class = &ac3enc_class,
  84. .channel_layouts = ff_ac3_channel_layouts,
  85. };