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.

163 lines
5.0KB

  1. /*
  2. * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
  3. * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "avcodec.h"
  22. #include "aacadtsdec.h"
  23. #include "bsf.h"
  24. #include "put_bits.h"
  25. #include "get_bits.h"
  26. #include "mpeg4audio.h"
  27. #include "internal.h"
  28. typedef struct AACBSFContext {
  29. int first_frame_done;
  30. } AACBSFContext;
  31. /**
  32. * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
  33. * ADTS header and removes the ADTS header.
  34. */
  35. static int aac_adtstoasc_filter(AVBSFContext *bsfc, AVPacket *out)
  36. {
  37. AACBSFContext *ctx = bsfc->priv_data;
  38. GetBitContext gb;
  39. PutBitContext pb;
  40. AACADTSHeaderInfo hdr;
  41. AVPacket *in;
  42. int ret;
  43. ret = ff_bsf_get_packet(bsfc, &in);
  44. if (ret < 0)
  45. return ret;
  46. if (in->size < AAC_ADTS_HEADER_SIZE)
  47. goto packet_too_small;
  48. init_get_bits(&gb, in->data, AAC_ADTS_HEADER_SIZE * 8);
  49. if (bsfc->par_in->extradata && show_bits(&gb, 12) != 0xfff)
  50. goto finish;
  51. if (avpriv_aac_parse_header(&gb, &hdr) < 0) {
  52. av_log(bsfc, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
  53. ret = AVERROR_INVALIDDATA;
  54. goto fail;
  55. }
  56. if (!hdr.crc_absent && hdr.num_aac_frames > 1) {
  57. avpriv_report_missing_feature(bsfc,
  58. "Multiple RDBs per frame with CRC");
  59. ret = AVERROR_PATCHWELCOME;
  60. goto fail;
  61. }
  62. in->size -= AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent;
  63. if (in->size <= 0)
  64. goto packet_too_small;
  65. in->data += AAC_ADTS_HEADER_SIZE + 2 * !hdr.crc_absent;
  66. if (!ctx->first_frame_done) {
  67. int pce_size = 0;
  68. uint8_t pce_data[MAX_PCE_SIZE];
  69. uint8_t *extradata;
  70. if (!hdr.chan_config) {
  71. init_get_bits(&gb, in->data, in->size * 8);
  72. if (get_bits(&gb, 3) != 5) {
  73. avpriv_report_missing_feature(bsfc,
  74. "PCE-based channel configuration "
  75. "without PCE as first syntax "
  76. "element");
  77. ret = AVERROR_PATCHWELCOME;
  78. goto fail;
  79. }
  80. init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
  81. pce_size = ff_copy_pce_data(&pb, &gb) / 8;
  82. flush_put_bits(&pb);
  83. in->size -= get_bits_count(&gb)/8;
  84. in->data += get_bits_count(&gb)/8;
  85. }
  86. extradata = av_packet_new_side_data(in, AV_PKT_DATA_NEW_EXTRADATA,
  87. 2 + pce_size);
  88. if (!extradata) {
  89. ret = AVERROR(ENOMEM);
  90. goto fail;
  91. }
  92. init_put_bits(&pb, extradata, 2 + pce_size);
  93. put_bits(&pb, 5, hdr.object_type);
  94. put_bits(&pb, 4, hdr.sampling_index);
  95. put_bits(&pb, 4, hdr.chan_config);
  96. put_bits(&pb, 1, 0); //frame length - 1024 samples
  97. put_bits(&pb, 1, 0); //does not depend on core coder
  98. put_bits(&pb, 1, 0); //is not extension
  99. flush_put_bits(&pb);
  100. if (pce_size) {
  101. memcpy(extradata + 2, pce_data, pce_size);
  102. }
  103. ctx->first_frame_done = 1;
  104. }
  105. finish:
  106. av_packet_move_ref(out, in);
  107. av_packet_free(&in);
  108. return 0;
  109. packet_too_small:
  110. av_log(bsfc, AV_LOG_ERROR, "Input packet too small\n");
  111. ret = AVERROR_INVALIDDATA;
  112. fail:
  113. av_packet_free(&in);
  114. return ret;
  115. }
  116. static int aac_adtstoasc_init(AVBSFContext *ctx)
  117. {
  118. /* Validate the extradata if the stream is already MPEG-4 AudioSpecificConfig */
  119. if (ctx->par_in->extradata) {
  120. MPEG4AudioConfig mp4ac;
  121. int ret = avpriv_mpeg4audio_get_config(&mp4ac, ctx->par_in->extradata,
  122. ctx->par_in->extradata_size * 8, 1);
  123. if (ret < 0) {
  124. av_log(ctx, AV_LOG_ERROR, "Error parsing AudioSpecificConfig extradata!\n");
  125. return ret;
  126. }
  127. }
  128. return 0;
  129. }
  130. static const enum AVCodecID codec_ids[] = {
  131. AV_CODEC_ID_AAC, AV_CODEC_ID_NONE,
  132. };
  133. const AVBitStreamFilter ff_aac_adtstoasc_bsf = {
  134. .name = "aac_adtstoasc",
  135. .priv_data_size = sizeof(AACBSFContext),
  136. .init = aac_adtstoasc_init,
  137. .filter = aac_adtstoasc_filter,
  138. .codec_ids = codec_ids,
  139. };