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.

179 lines
5.5KB

  1. /*
  2. * RTP Depacketization of MP4A-LATM, RFC 3016
  3. * Copyright (c) 2010 Martin Storsjo
  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 "libavutil/avstring.h"
  22. #include "libavcodec/bitstream.h"
  23. #include "avio_internal.h"
  24. #include "rtpdec_formats.h"
  25. #include "internal.h"
  26. struct PayloadContext {
  27. AVIOContext *dyn_buf;
  28. uint8_t *buf;
  29. int pos, len;
  30. uint32_t timestamp;
  31. };
  32. static void latm_close_context(PayloadContext *data)
  33. {
  34. ffio_free_dyn_buf(&data->dyn_buf);
  35. av_free(data->buf);
  36. }
  37. static int latm_parse_packet(AVFormatContext *ctx, PayloadContext *data,
  38. AVStream *st, AVPacket *pkt, uint32_t *timestamp,
  39. const uint8_t *buf, int len, uint16_t seq,
  40. int flags)
  41. {
  42. int ret, cur_len;
  43. if (buf) {
  44. if (!data->dyn_buf || data->timestamp != *timestamp) {
  45. av_freep(&data->buf);
  46. ffio_free_dyn_buf(&data->dyn_buf);
  47. data->timestamp = *timestamp;
  48. if ((ret = avio_open_dyn_buf(&data->dyn_buf)) < 0)
  49. return ret;
  50. }
  51. avio_write(data->dyn_buf, buf, len);
  52. if (!(flags & RTP_FLAG_MARKER))
  53. return AVERROR(EAGAIN);
  54. av_free(data->buf);
  55. data->len = avio_close_dyn_buf(data->dyn_buf, &data->buf);
  56. data->dyn_buf = NULL;
  57. data->pos = 0;
  58. }
  59. if (!data->buf) {
  60. av_log(ctx, AV_LOG_ERROR, "No data available yet\n");
  61. return AVERROR(EIO);
  62. }
  63. cur_len = 0;
  64. while (data->pos < data->len) {
  65. uint8_t val = data->buf[data->pos++];
  66. cur_len += val;
  67. if (val != 0xff)
  68. break;
  69. }
  70. if (data->pos + cur_len > data->len) {
  71. av_log(ctx, AV_LOG_ERROR, "Malformed LATM packet\n");
  72. return AVERROR(EIO);
  73. }
  74. if ((ret = av_new_packet(pkt, cur_len)) < 0)
  75. return ret;
  76. memcpy(pkt->data, data->buf + data->pos, cur_len);
  77. data->pos += cur_len;
  78. pkt->stream_index = st->index;
  79. return data->pos < data->len;
  80. }
  81. static int parse_fmtp_config(AVStream *st, const char *value)
  82. {
  83. int len = ff_hex_to_data(NULL, value), i, ret = 0;
  84. BitstreamContext bc;
  85. uint8_t *config;
  86. int audio_mux_version, same_time_framing, num_programs, num_layers;
  87. /* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
  88. config = av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE);
  89. if (!config)
  90. return AVERROR(ENOMEM);
  91. ff_hex_to_data(config, value);
  92. bitstream_init8(&bc, config, len);
  93. audio_mux_version = bitstream_read(&bc, 1);
  94. same_time_framing = bitstream_read(&bc, 1);
  95. bitstream_skip(&bc, 6); /* num_sub_frames */
  96. num_programs = bitstream_read(&bc, 4);
  97. num_layers = bitstream_read(&bc, 3);
  98. if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 ||
  99. num_layers != 0) {
  100. avpriv_report_missing_feature(NULL, "LATM config (%d,%d,%d,%d)",
  101. audio_mux_version, same_time_framing,
  102. num_programs, num_layers);
  103. ret = AVERROR_PATCHWELCOME;
  104. goto end;
  105. }
  106. av_freep(&st->codecpar->extradata);
  107. st->codecpar->extradata_size = (bitstream_bits_left(&bc) + 7) / 8;
  108. st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size +
  109. AV_INPUT_BUFFER_PADDING_SIZE);
  110. if (!st->codecpar->extradata) {
  111. ret = AVERROR(ENOMEM);
  112. goto end;
  113. }
  114. for (i = 0; i < st->codecpar->extradata_size; i++)
  115. st->codecpar->extradata[i] = bitstream_read(&bc, 8);
  116. end:
  117. av_free(config);
  118. return ret;
  119. }
  120. static int parse_fmtp(AVFormatContext *s,
  121. AVStream *stream, PayloadContext *data,
  122. const char *attr, const char *value)
  123. {
  124. int res;
  125. if (!strcmp(attr, "config")) {
  126. res = parse_fmtp_config(stream, value);
  127. if (res < 0)
  128. return res;
  129. } else if (!strcmp(attr, "cpresent")) {
  130. int cpresent = atoi(value);
  131. if (cpresent != 0)
  132. avpriv_request_sample(s,
  133. "RTP MP4A-LATM with in-band configuration");
  134. }
  135. return 0;
  136. }
  137. static int latm_parse_sdp_line(AVFormatContext *s, int st_index,
  138. PayloadContext *data, const char *line)
  139. {
  140. const char *p;
  141. if (st_index < 0)
  142. return 0;
  143. if (av_strstart(line, "fmtp:", &p))
  144. return ff_parse_fmtp(s, s->streams[st_index], data, p, parse_fmtp);
  145. return 0;
  146. }
  147. RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler = {
  148. .enc_name = "MP4A-LATM",
  149. .codec_type = AVMEDIA_TYPE_AUDIO,
  150. .codec_id = AV_CODEC_ID_AAC,
  151. .priv_data_size = sizeof(PayloadContext),
  152. .parse_sdp_a_line = latm_parse_sdp_line,
  153. .close = latm_close_context,
  154. .parse_packet = latm_parse_packet,
  155. };