rtp: Support packetization/depacketization of opus
authorMartin Storsjö <martin@martin.st>
Mon, 8 Oct 2012 21:51:42 +0000 (00:51 +0300)
committerMartin Storsjö <martin@martin.st>
Tue, 9 Oct 2012 08:57:11 +0000 (11:57 +0300)
Signed-off-by: Martin Storsjö <martin@martin.st>
libavformat/rtpdec.c
libavformat/rtpenc.c
libavformat/sdp.c

index 0f4e1d1..dac367d 100644 (file)
@@ -55,6 +55,12 @@ static RTPDynamicProtocolHandler speex_dynamic_handler = {
     .codec_id         = AV_CODEC_ID_SPEEX,
 };
 
+static RTPDynamicProtocolHandler opus_dynamic_handler = {
+    .enc_name         = "opus",
+    .codec_type       = AVMEDIA_TYPE_AUDIO,
+    .codec_id         = AV_CODEC_ID_OPUS,
+};
+
 /* statistics functions */
 static RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL;
 
@@ -85,6 +91,7 @@ void av_register_rtp_dynamic_payload_handlers(void)
     ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
     ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
     ff_register_dynamic_payload_handler(&speex_dynamic_handler);
+    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
 
     ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
     ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
index 36064ed..b17c465 100644 (file)
@@ -77,6 +77,7 @@ static int is_supported(enum AVCodecID id)
     case AV_CODEC_ID_ILBC:
     case AV_CODEC_ID_MJPEG:
     case AV_CODEC_ID_SPEEX:
+    case AV_CODEC_ID_OPUS:
         return 1;
     default:
         return 0;
@@ -186,6 +187,16 @@ static int rtp_write_header(AVFormatContext *s1)
          * 8000, even if the sample rate is 16000. See RFC 3551. */
         avpriv_set_pts_info(st, 32, 1, 8000);
         break;
+    case AV_CODEC_ID_OPUS:
+        if (st->codec->channels > 2) {
+            av_log(s1, AV_LOG_ERROR, "Multistream opus not supported in RTP\n");
+            goto fail;
+        }
+        /* The opus RTP RFC says that all opus streams should use 48000 Hz
+         * as clock rate, since all opus sample rates can be expressed in
+         * this clock rate, and sample rate changes on the fly are supported. */
+        avpriv_set_pts_info(st, 32, 1, 48000);
+        break;
     case AV_CODEC_ID_ILBC:
         if (st->codec->block_align != 38 && st->codec->block_align != 50) {
             av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n");
@@ -525,6 +536,14 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     case AV_CODEC_ID_MJPEG:
         ff_rtp_send_jpeg(s1, pkt->data, size);
         break;
+    case AV_CODEC_ID_OPUS:
+        if (size > s->max_payload_size) {
+            av_log(s1, AV_LOG_ERROR,
+                   "Packet size %d too large for max RTP payload size %d\n",
+                   size, s->max_payload_size);
+            return AVERROR(EINVAL);
+        }
+        /* Intentional fallthrough */
     default:
         /* better than nothing : send the codec raw data */
         rtp_send_raw(s1, pkt->data, size);
index 91de413..0f7eb2f 100644 (file)
@@ -576,6 +576,10 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
             av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",
                                      payload_type, c->sample_rate);
             break;
+        case AV_CODEC_ID_OPUS:
+            av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",
+                                     payload_type);
+            break;
         default:
             /* Nothing special to do here... */
             break;