diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-02-24 02:57:18 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-02-24 02:57:18 +0100 |
commit | e2cc39b6096ed4353293252e3955417b7766f161 (patch) | |
tree | 0bc4d98c120dedcffb9b6e50943b4fc9e3c2a877 /libavformat | |
parent | 32e74395a8e88dee1c149aeb36e7a21df431c181 (diff) | |
parent | 31632e73f47d25e2077fce729571259ee6354854 (diff) | |
download | ffmpeg-e2cc39b6096ed4353293252e3955417b7766f161.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (40 commits)
swf: check return values for av_get/new_packet().
wavpack: Don't shift minclip/maxclip
rtpenc: Expose the max packet size via an avoption
rtpenc: Move max_packet_size to a context variable
rtpenc: Add an option for not sending RTCP packets
lavc: drop encode() support for video.
snowenc: switch to encode2().
snowenc: don't abuse input picture for storing information.
a64multienc: switch to encode2().
a64multienc: don't write into output buffer when there's no output.
libxvid: switch to encode2().
tiffenc: switch to encode2().
tiffenc: properly forward error codes in encode_frame().
lavc: drop libdirac encoder.
gifenc: switch to encode2().
libvpxenc: switch to encode2().
flashsvenc: switch to encode2().
Remove libpostproc.
lcl: don't overwrite input memory.
swscale: take first/lastline over/underflows into account for MMX.
...
Conflicts:
.gitignore
Makefile
cmdutils.c
configure
doc/APIchanges
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/libdiracenc.c
libavcodec/libxvidff.c
libavcodec/qtrleenc.c
libavcodec/tiffenc.c
libavcodec/utils.c
libavformat/mov.c
libavformat/movenc.c
libpostproc/Makefile
libpostproc/postprocess.c
libpostproc/postprocess.h
libpostproc/postprocess_altivec_template.c
libpostproc/postprocess_internal.h
libpostproc/postprocess_template.c
libswscale/swscale.c
libswscale/utils.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/mov.c | 5 | ||||
-rw-r--r-- | libavformat/movenc.c | 2 | ||||
-rw-r--r-- | libavformat/rtp.c | 4 | ||||
-rw-r--r-- | libavformat/rtpenc.c | 36 | ||||
-rw-r--r-- | libavformat/rtpenc.h | 11 | ||||
-rw-r--r-- | libavformat/rtpenc_h263.c | 7 | ||||
-rw-r--r-- | libavformat/rtpenc_h263_rfc2190.c | 104 | ||||
-rw-r--r-- | libavformat/rtsp.c | 2 | ||||
-rw-r--r-- | libavformat/sdp.c | 3 | ||||
-rw-r--r-- | libavformat/swfdec.c | 14 |
11 files changed, 166 insertions, 23 deletions
diff --git a/libavformat/Makefile b/libavformat/Makefile index f58dc42ac3..61bb1120d7 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -258,6 +258,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_latm.o \ rtpenc_amr.o \ rtpenc_h263.o \ + rtpenc_h263_rfc2190.o \ rtpenc_mpv.o \ rtpenc.o \ rtpenc_h264.o \ diff --git a/libavformat/mov.c b/libavformat/mov.c index ff97a9b58f..15df2bf198 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -25,6 +25,7 @@ //#define DEBUG //#define MOV_EXPORT_ALL_METADATA +#include "libavutil/audioconvert.h" #include "libavutil/intreadwrite.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" @@ -32,6 +33,7 @@ #include "libavutil/dict.h" #include "libavutil/opt.h" #include "libavutil/timecode.h" +#include "libavcodec/ac3tab.h" #include "avformat.h" #include "internal.h" #include "avio_internal.h" @@ -570,6 +572,9 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) acmod = (ac3info >> 11) & 0x7; lfeon = (ac3info >> 10) & 0x1; st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; + st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; + if (lfeon) + st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; st->codec->audio_service_type = bsmod; if (st->codec->channels > 1 && bsmod == 0x7) st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 138c00fcb4..472281957b 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -52,7 +52,7 @@ static const AVOption options[] = { { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), + FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags) { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, diff --git a/libavformat/rtp.c b/libavformat/rtp.c index 98d96160db..a5484ae6fa 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -106,7 +106,9 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt, AVCodecContext *codec) /* static payload type */ for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i) if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) { - if (codec->codec_id == CODEC_ID_H263) + if (codec->codec_id == CODEC_ID_H263 && (!fmt || + !fmt->oformat->priv_class || + !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190"))) continue; if (codec->codec_id == CODEC_ID_PCM_S16BE) if (codec->channels != AVRtpPayloadTypes[i].audio_channels) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 4b1ff1d889..32288684eb 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -31,8 +31,9 @@ //#define DEBUG static const AVOption options[] = { - FF_RTP_FLAG_OPTS(RTPMuxContext, flags), + FF_RTP_FLAG_OPTS(RTPMuxContext, flags) { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM }, + { "max_packet_size", "Max packet size", offsetof(RTPMuxContext, max_packet_size), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, { NULL }, }; @@ -82,11 +83,13 @@ static int is_supported(enum CodecID id) static int rtp_write_header(AVFormatContext *s1) { RTPMuxContext *s = s1->priv_data; - int max_packet_size, n; + int n; AVStream *st; - if (s1->nb_streams != 1) - return -1; + if (s1->nb_streams != 1) { + av_log(s1, AV_LOG_ERROR, "Only one stream supported in the RTP muxer\n"); + return AVERROR(EINVAL); + } st = s1->streams[0]; if (!is_supported(st->codec->codec_id)) { av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id)); @@ -107,16 +110,21 @@ static int rtp_write_header(AVFormatContext *s1) s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 + NTP_OFFSET_US; - max_packet_size = s1->pb->max_packet_size; - if (max_packet_size <= 12) { - av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", max_packet_size); + if (s->max_packet_size) { + if (s1->pb->max_packet_size) + s->max_packet_size = FFMIN(s->max_payload_size, + s1->pb->max_packet_size); + } else + s->max_packet_size = s1->pb->max_packet_size; + if (s->max_packet_size <= 12) { + av_log(s1, AV_LOG_ERROR, "Max packet size %d too low\n", s->max_packet_size); return AVERROR(EIO); } - s->buf = av_malloc(max_packet_size); + s->buf = av_malloc(s->max_packet_size); if (s->buf == NULL) { return AVERROR(ENOMEM); } - s->max_payload_size = max_packet_size - 12; + s->max_payload_size = s->max_packet_size - 12; s->max_frames_per_packet = 0; if (s1->max_delay) { @@ -386,8 +394,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / RTCP_TX_RATIO_DEN; - if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && - (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) { + if ((s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && + (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) && + !(s->flags & FF_RTP_FLAG_SKIP_RTCP)) { rtcp_send_sr(s1, ff_ntp_time()); s->last_octet_count = s->octet_count; s->first_packet = 0; @@ -443,6 +452,11 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) ff_rtp_send_h264(s1, pkt->data, size); break; case CODEC_ID_H263: + if (s->flags & FF_RTP_FLAG_RFC2190) { + ff_rtp_send_h263_rfc2190(s1, pkt->data, size); + break; + } + /* Fallthrough */ case CODEC_ID_H263P: ff_rtp_send_h263(s1, pkt->data, size); break; diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h index 901336322d..c28377fec0 100644 --- a/libavformat/rtpenc.h +++ b/libavformat/rtpenc.h @@ -34,6 +34,7 @@ struct RTPMuxContext { uint32_t timestamp; uint32_t base_timestamp; uint32_t cur_timestamp; + int max_packet_size; int max_payload_size; int num_frames; @@ -64,15 +65,20 @@ struct RTPMuxContext { typedef struct RTPMuxContext RTPMuxContext; #define FF_RTP_FLAG_MP4A_LATM 1 +#define FF_RTP_FLAG_RFC2190 2 +#define FF_RTP_FLAG_SKIP_RTCP 4 #define FF_RTP_FLAG_OPTS(ctx, fieldname) \ { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \ - { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \ + { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \ + { "rfc2190", "Use RFC 2190 packetization instead of RFC 4629 for H.263", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_RFC2190}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \ + { "skip_rtcp", "Don't send RTCP sender reports", 0, AV_OPT_TYPE_CONST, {.dbl = FF_RTP_FLAG_SKIP_RTCP}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m); void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size); +void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size); @@ -80,4 +86,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size); void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size); void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buff, int size); +const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *restrict start, + const uint8_t *restrict end); + #endif /* AVFORMAT_RTPENC_H */ diff --git a/libavformat/rtpenc_h263.c b/libavformat/rtpenc_h263.c index 84403a1069..e14aaf1dbd 100644 --- a/libavformat/rtpenc_h263.c +++ b/libavformat/rtpenc_h263.c @@ -23,8 +23,8 @@ #include "avformat.h" #include "rtpenc.h" -static const uint8_t *find_resync_marker_reverse(const uint8_t *restrict start, - const uint8_t *restrict end) +const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *restrict start, + const uint8_t *restrict end) { const uint8_t *p = end - 1; start += 1; /* Make sure we never return the original start. */ @@ -63,7 +63,8 @@ void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size) /* Look for a better place to split the frame into packets. */ if (len < size) { - const uint8_t *end = find_resync_marker_reverse(buf1, buf1 + len); + const uint8_t *end = ff_h263_find_resync_marker_reverse(buf1, + buf1 + len); len = end - buf1; } diff --git a/libavformat/rtpenc_h263_rfc2190.c b/libavformat/rtpenc_h263_rfc2190.c new file mode 100644 index 0000000000..305c1a27c8 --- /dev/null +++ b/libavformat/rtpenc_h263_rfc2190.c @@ -0,0 +1,104 @@ +/* + * RTP packetization for H.263 video + * Copyright (c) 2012 Martin Storsjo + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "rtpenc.h" +#include "libavcodec/put_bits.h" +#include "libavcodec/get_bits.h" + +struct H263Info { + int src; + int i; + int u; + int s; + int a; + int pb; + int tr; +}; + +static void send_mode_a(AVFormatContext *s1, const struct H263Info *info, + const uint8_t *buf, int len, int m) +{ + RTPMuxContext *s = s1->priv_data; + PutBitContext pb; + + init_put_bits(&pb, s->buf, 32); + put_bits(&pb, 1, 0); /* F - 0, mode A */ + put_bits(&pb, 1, 0); /* P - 0, normal I/P */ + put_bits(&pb, 3, 0); /* SBIT - 0 bits */ + put_bits(&pb, 3, 0); /* EBIT - 0 bits */ + put_bits(&pb, 3, info->src); /* SRC - source format */ + put_bits(&pb, 1, info->i); /* I - inter/intra */ + put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */ + put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */ + put_bits(&pb, 1, info->a); /* A - advanced prediction */ + put_bits(&pb, 4, 0); /* R - reserved */ + put_bits(&pb, 2, 0); /* DBQ - 0 */ + put_bits(&pb, 3, 0); /* TRB - 0 */ + put_bits(&pb, 8, info->tr); /* TR */ + flush_put_bits(&pb); + memcpy(s->buf + 4, buf, len); + + ff_rtp_send_data(s1, s->buf, len + 4, m); +} + +void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size) +{ + RTPMuxContext *s = s1->priv_data; + int len; + GetBitContext gb; + struct H263Info info = { 0 }; + + s->timestamp = s->cur_timestamp; + + init_get_bits(&gb, buf, size*8); + if (get_bits(&gb, 22) == 0x20) { /* Picture Start Code */ + info.tr = get_bits(&gb, 8); + skip_bits(&gb, 2); /* PTYPE start, H261 disambiguation */ + skip_bits(&gb, 3); /* Split screen, document camera, freeze picture release */ + info.src = get_bits(&gb, 3); + info.i = get_bits(&gb, 1); + info.u = get_bits(&gb, 1); + info.s = get_bits(&gb, 1); + info.a = get_bits(&gb, 1); + info.pb = get_bits(&gb, 1); + } + + while (size > 0) { + len = FFMIN(s->max_payload_size - 4, size); + + /* Look for a better place to split the frame into packets. */ + if (len < size) { + const uint8_t *end = ff_h263_find_resync_marker_reverse(buf, + buf + len); + len = end - buf; + if (len == s->max_payload_size - 4) + av_log(s1, AV_LOG_WARNING, + "No GOB boundary found within MTU size, splitting at " + "a random boundary\n"); + } + + send_mode_a(s1, &info, buf, len, len == size); + + buf += len; + size -= len; + } +} diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index bc03db41a9..0d919ae874 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -73,7 +73,7 @@ const AVOption ff_rtsp_options[] = { { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC }, - FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags), + FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags) { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \ { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \ { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \ diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 20cf58809e..77b8945a25 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -404,6 +404,9 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, * actually specifies the maximum video size, but we only know * the current size. This is required for playback on Android * stagefright and on Samsung bada. */ + if (!fmt || !fmt->oformat->priv_class || + !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190") || + c->codec_id == CODEC_ID_H263P) av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n" "a=framesize:%d %d-%d\r\n", payload_type, diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 2a012869a8..a84d3808bf 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -84,7 +84,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) SWFContext *swf = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst = NULL, *ast = NULL, *st = 0; - int tag, len, i, frame, v; + int tag, len, i, frame, v, res; for(;;) { uint64_t pos = avio_tell(pb); @@ -147,7 +147,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { frame = avio_rl16(pb); - av_get_packet(pb, pkt, len-2); + if ((res = av_get_packet(pb, pkt, len-2)) < 0) + return res; pkt->pos = pos; pkt->pts = frame; pkt->stream_index = st->index; @@ -160,9 +161,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { if (st->codec->codec_id == CODEC_ID_MP3) { avio_skip(pb, 4); - av_get_packet(pb, pkt, len-4); + if ((res = av_get_packet(pb, pkt, len-4)) < 0) + return res; } else { // ADPCM, PCM - av_get_packet(pb, pkt, len); + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; } pkt->pos = pos; pkt->stream_index = st->index; @@ -187,7 +190,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = vst; } avio_rl16(pb); /* BITMAP_ID */ - av_new_packet(pkt, len-2); + if ((res = av_new_packet(pkt, len-2)) < 0) + return res; avio_read(pb, pkt->data, 4); if (AV_RB32(pkt->data) == 0xffd8ffd9 || AV_RB32(pkt->data) == 0xffd9ffd8) { |