[1/5] rtpenc: MP4A-LATM payload support

Message ID 1305893663-56629-2-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö May 20, 2011, 12:14 p.m.
From: Juan Carlos Rodriguez <ing.juancarlosrodriguez@hotmail.com>

---
 libavformat/rtpenc.c |    4 +++
 libavformat/sdp.c    |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 0 deletions(-)

Patch

diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 7cedff3..ed9154f 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -40,6 +40,7 @@  static int is_supported(enum CodecID id)
     case CODEC_ID_MPEG2VIDEO:
     case CODEC_ID_MPEG4:
     case CODEC_ID_AAC:
+    case CODEC_ID_AAC_LATM:
     case CODEC_ID_MP2:
     case CODEC_ID_MP3:
     case CODEC_ID_PCM_ALAW:
@@ -406,6 +407,9 @@  static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     case CODEC_ID_AAC:
         ff_rtp_send_aac(s1, pkt->data, size);
         break;
+    case CODEC_ID_AAC_LATM:
+        rtp_send_raw(s1, pkt->data, size);
+        break;
     case CODEC_ID_AMR_NB:
     case CODEC_ID_AMR_WB:
         ff_rtp_send_amr(s1, pkt->data, size);
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 005434c..e8ac2df 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -23,6 +23,7 @@ 
 #include "libavutil/base64.h"
 #include "libavutil/parseutils.h"
 #include "libavcodec/xiph.h"
+#include "libavcodec/mpeg4audio.h"
 #include "avformat.h"
 #include "internal.h"
 #include "avc.h"
@@ -299,6 +300,59 @@  xiph_fail:
     return NULL;
 }
 
+static int latm_context2profilelevel(AVCodecContext *c)
+{
+    /* MP4A-LATM
+     * The RTP payload format specification is described in RFC 3016
+     * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+    int profile_level = 0x2B;
+
+    /* TODO: AAC Profile only supports AAC LC Object Type.
+     * Different Object Types should implement different Profile Levels */
+
+    if (c->sample_rate <= 24000) {
+        if (c->channels <= 2)
+            profile_level = 0x28; // AAC Profile, Level 1
+    } else if (c->sample_rate <= 48000) {
+        if (c->channels <= 2) {
+            profile_level = 0x29; // AAC Profile, Level 2
+        } else if (c->channels <= 5) {
+            profile_level = 0x2A; // AAC Profile, Level 4
+        }
+    } else if (c->sample_rate <= 96000) {
+        if (c->channels <= 5) {
+            profile_level = 0x2B; // AAC Profile, Level 5
+        }
+    }
+
+    return profile_level;
+}
+
+static char *latm_context2config(AVCodecContext *c)
+{
+    /* MP4A-LATM
+     * The RTP payload format specification is described in RFC 3016
+     * The encoding specifications are provided in ISO/IEC 14496-3 */
+
+    char *config;
+
+    if (!c->extradata) {
+        av_log(c, AV_LOG_ERROR, "No LATM extradata present.\n");
+        return NULL;
+    }
+
+    config = av_malloc(c->extradata_size*2 + 1);
+    if (!config) {
+        av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
+        return NULL;
+    }
+    ff_data_to_hex(config, c->extradata, c->extradata_size, 1);
+    config[c->extradata_size*2] = 0;
+
+    return config;
+}
+
 static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type)
 {
     char *config = NULL;
@@ -353,6 +407,15 @@  static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
                                      payload_type, c->sample_rate, c->channels,
                                      payload_type, config);
             break;
+        case CODEC_ID_AAC_LATM:
+            config = latm_context2config(c);
+            if (!config)
+                return NULL;
+            av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
+                                    "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
+                                     payload_type, c->sample_rate, c->channels,
+                                     payload_type, latm_context2profilelevel(c), config);
+            break;
         case CODEC_ID_PCM_S16BE:
             if (payload_type >= RTP_PT_PRIVATE)
                 av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",