* qatar/master: (24 commits) flvdec: remove incomplete, disabled seeking code mem: add support for _aligned_malloc() as found on Windows lavc: Extend the documentation for avcodec_init_packet flvdec: remove incomplete, disabled seeking code http: replace atoll() with strtoll() mpegts: remove unused/incomplete/broken seeking code af_amix: allow float planar sample format as input af_amix: use AVFloatDSPContext.vector_fmac_scalar() float_dsp: add x86-optimized functions for vector_fmac_scalar() float_dsp: Move vector_fmac_scalar() from libavcodec to libavutil lavr: Add x86-optimized function for flt to s32 conversion lavr: Add x86-optimized function for flt to s16 conversion lavr: Add x86-optimized functions for s32 to flt conversion lavr: Add x86-optimized functions for s32 to s16 conversion lavr: Add x86-optimized functions for s16 to flt conversion lavr: Add x86-optimized function for s16 to s32 conversion rtpenc: Support packetizing iLBC rtpdec: Add a depacketizer for iLBC Implement the iLBC storage file format mov: Support muxing/demuxing iLBC ... Conflicts: Changelog configure libavcodec/avcodec.h libavcodec/dsputil.c libavcodec/version.h libavformat/movenc.c libavformat/mpegts.c libavformat/version.h libavutil/mem.c
Showing the changes to libavformat/ilbc.c (1 of 44 files). Show all
Unified · Split
| @@ -0,0 +1,141 @@ | |||
| 1 | /* | ||
| 2 | * iLBC storage file format | ||
| 3 | * Copyright (c) 2012 Martin Storsjo | ||
| 4 | * | ||
| 5 | * This file is part of FFmpeg. | ||
| 6 | * | ||
| 7 | * FFmpeg 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 | * FFmpeg 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 FFmpeg; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include "avformat.h" | ||
| 23 | #include "internal.h" | ||
| 24 | |||
| 25 | static const char mode20_header[] = "#!iLBC20\n"; | ||
| 26 | static const char mode30_header[] = "#!iLBC30\n"; | ||
| 27 | |||
| 28 | static int ilbc_write_header(AVFormatContext *s) | ||
| 29 | { | ||
| 30 | AVIOContext *pb = s->pb; | ||
| 31 | AVCodecContext *enc; | ||
| 32 | |||
| 33 | if (s->nb_streams != 1) { | ||
| 34 | av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n"); | ||
| 35 | return AVERROR(EINVAL); | ||
| 36 | } | ||
| 37 | enc = s->streams[0]->codec; | ||
| 38 | |||
| 39 | if (enc->codec_id != CODEC_ID_ILBC) { | ||
| 40 | av_log(s, AV_LOG_ERROR, "Unsupported codec\n"); | ||
| 41 | return AVERROR(EINVAL); | ||
| 42 | } | ||
| 43 | |||
| 44 | if (enc->block_align == 50) { | ||
| 45 | avio_write(pb, mode30_header, sizeof(mode30_header) - 1); | ||
| 46 | } else if (enc->block_align == 38) { | ||
| 47 | avio_write(pb, mode20_header, sizeof(mode20_header) - 1); | ||
| 48 | } else { | ||
| 49 | av_log(s, AV_LOG_ERROR, "Unsupported mode\n"); | ||
| 50 | return AVERROR(EINVAL); | ||
| 51 | } | ||
| 52 | avio_flush(pb); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt) | ||
| 57 | { | ||
| 58 | avio_write(s->pb, pkt->data, pkt->size); | ||
| 59 | avio_flush(s->pb); | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | static int ilbc_probe(AVProbeData *p) | ||
| 64 | { | ||
| 65 | // Only check for "#!iLBC" which matches both formats | ||
| 66 | if (!memcmp(p->buf, mode20_header, 6)) | ||
| 67 | return AVPROBE_SCORE_MAX; | ||
| 68 | else | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int ilbc_read_header(AVFormatContext *s) | ||
| 73 | { | ||
| 74 | AVIOContext *pb = s->pb; | ||
| 75 | AVStream *st; | ||
| 76 | uint8_t header[9]; | ||
| 77 | |||
| 78 | avio_read(pb, header, 9); | ||
| 79 | |||
| 80 | st = avformat_new_stream(s, NULL); | ||
| 81 | if (!st) | ||
| 82 | return AVERROR(ENOMEM); | ||
| 83 | st->codec->codec_id = CODEC_ID_ILBC; | ||
| 84 | st->codec->sample_rate = 8000; | ||
| 85 | st->codec->channels = 1; | ||
| 86 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; | ||
| 87 | st->start_time = 0; | ||
| 88 | avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); | ||
| 89 | if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) { | ||
| 90 | st->codec->block_align = 38; | ||
| 91 | st->codec->bit_rate = 15200; | ||
| 92 | } else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) { | ||
| 93 | st->codec->block_align = 50; | ||
| 94 | st->codec->bit_rate = 13333; | ||
| 95 | } else { | ||
| 96 | av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n"); | ||
| 97 | return AVERROR_INVALIDDATA; | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int ilbc_read_packet(AVFormatContext *s, | ||
| 104 | AVPacket *pkt) | ||
| 105 | { | ||
| 106 | AVCodecContext *enc = s->streams[0]->codec; | ||
| 107 | int ret; | ||
| 108 | |||
| 109 | if ((ret = av_new_packet(pkt, enc->block_align)) < 0) | ||
| 110 | return ret; | ||
| 111 | |||
| 112 | pkt->stream_index = 0; | ||
| 113 | pkt->pos = avio_tell(s->pb); | ||
| 114 | pkt->duration = enc->block_align == 38 ? 160 : 240; | ||
| 115 | if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) { | ||
| 116 | av_free_packet(pkt); | ||
| 117 | return ret < 0 ? ret : AVERROR(EIO); | ||
| 118 | } | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | AVInputFormat ff_ilbc_demuxer = { | ||
| 124 | .name = "ilbc", | ||
| 125 | .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"), | ||
| 126 | .read_probe = ilbc_probe, | ||
| 127 | .read_header = ilbc_read_header, | ||
| 128 | .read_packet = ilbc_read_packet, | ||
| 129 | .flags = AVFMT_GENERIC_INDEX, | ||
| 130 | }; | ||
| 131 | |||
| 132 | AVOutputFormat ff_ilbc_muxer = { | ||
| 133 | .name = "ilbc", | ||
| 134 | .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"), | ||
| 135 | .mime_type = "audio/iLBC", | ||
| 136 | .extensions = "lbc", | ||
| 137 | .audio_codec = CODEC_ID_ILBC, | ||
| 138 | .write_header = ilbc_write_header, | ||
| 139 | .write_packet = ilbc_write_packet, | ||
| 140 | .flags = AVFMT_NOTIMESTAMPS, | ||
| 141 | }; | ||