diff options
author | Martin Storsjö <martin@martin.st> | 2012-06-17 17:25:46 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2012-06-18 22:01:04 +0300 |
commit | 579fd87b46ccf8b126fed180a7194460fe55c016 (patch) | |
tree | 372c6b99b302aca2b6c3d77757b6b5414358b6eb /libavformat/rtpenc.c | |
parent | 89c3960544310c4e8b11f788638e13e63a0ee37b (diff) | |
download | ffmpeg-579fd87b46ccf8b126fed180a7194460fe55c016.tar.gz |
rtpenc: Support packetizing iLBC
Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/rtpenc.c')
-rw-r--r-- | libavformat/rtpenc.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 6752fb6f7e..9cf1a165d2 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -74,6 +74,7 @@ static int is_supported(enum CodecID id) case CODEC_ID_VP8: case CODEC_ID_ADPCM_G722: case CODEC_ID_ADPCM_G726: + case CODEC_ID_ILBC: return 1; default: return 0; @@ -187,6 +188,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 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"); + goto fail; + } + if (!s->max_frames_per_packet) + s->max_frames_per_packet = 1; + s->max_frames_per_packet = FFMIN(s->max_frames_per_packet, + s->max_payload_size / st->codec->block_align); + goto defaultcase; case CODEC_ID_AMR_NB: case CODEC_ID_AMR_WB: if (!s->max_frames_per_packet) @@ -395,6 +406,36 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1, } } +static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size) +{ + RTPMuxContext *s = s1->priv_data; + AVStream *st = s1->streams[0]; + int frame_duration = av_get_audio_frame_duration(st->codec, 0); + int frame_size = st->codec->block_align; + int frames = size / frame_size; + + while (frames > 0) { + int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames); + + if (!s->num_frames) { + s->buf_ptr = s->buf; + s->timestamp = s->cur_timestamp; + } + memcpy(s->buf_ptr, buf, n * frame_size); + frames -= n; + s->num_frames += n; + s->buf_ptr += n * frame_size; + buf += n * frame_size; + s->cur_timestamp += n * frame_duration; + + if (s->num_frames == s->max_frames_per_packet) { + ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1); + s->num_frames = 0; + } + } + return 0; +} + static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) { RTPMuxContext *s = s1->priv_data; @@ -483,6 +524,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) case CODEC_ID_VP8: ff_rtp_send_vp8(s1, pkt->data, size); break; + case CODEC_ID_ILBC: + rtp_send_ilbc(s1, pkt->data, size); + break; default: /* better than nothing : send the codec raw data */ rtp_send_raw(s1, pkt->data, size); |