* commit 'c6f1dc8e4cd967ae056698eafb891a08003c211c': rtpdec: Move setting the parsing flags to the actual depacketizers rtpdec: Split handling of mpeg12 audio/video to a separate depacketizer Conflicts: libavformat/rtpdec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.2
| @@ -37,6 +37,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ | |||
| rtpdec_ilbc.o \ | |||
| rtpdec_jpeg.o \ | |||
| rtpdec_latm.o \ | |||
| rtpdec_mpeg12.o \ | |||
| rtpdec_mpeg4.o \ | |||
| rtpdec_mpegts.o \ | |||
| rtpdec_qcelp.o \ | |||
| @@ -74,6 +74,8 @@ void av_register_rtp_dynamic_payload_handlers(void) | |||
| ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler); | |||
| ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler); | |||
| @@ -500,18 +502,6 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, | |||
| rtp_init_statistics(&s->statistics, 0); | |||
| if (st) { | |||
| switch (st->codec->codec_id) { | |||
| case AV_CODEC_ID_MPEG1VIDEO: | |||
| case AV_CODEC_ID_MPEG2VIDEO: | |||
| case AV_CODEC_ID_MP2: | |||
| case AV_CODEC_ID_MP3: | |||
| case AV_CODEC_ID_MPEG4: | |||
| case AV_CODEC_ID_H263: | |||
| case AV_CODEC_ID_H264: | |||
| st->need_parsing = AVSTREAM_PARSE_FULL; | |||
| break; | |||
| case AV_CODEC_ID_VORBIS: | |||
| st->need_parsing = AVSTREAM_PARSE_HEADERS; | |||
| break; | |||
| case AV_CODEC_ID_ADPCM_G722: | |||
| /* According to RFC 3551, the stream clock rate is 8000 | |||
| * even if the sample rate is 16000. */ | |||
| @@ -583,12 +573,13 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam | |||
| static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, | |||
| const uint8_t *buf, int len) | |||
| { | |||
| unsigned int ssrc, h; | |||
| unsigned int ssrc; | |||
| int payload_type, seq, flags = 0; | |||
| int ext; | |||
| AVStream *st; | |||
| uint32_t timestamp; | |||
| int rv = 0; | |||
| int h; | |||
| ext = buf[0] & 0x10; | |||
| payload_type = buf[1] & 0x7f; | |||
| @@ -649,45 +640,9 @@ static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, | |||
| } else if (st) { | |||
| /* At this point, the RTP header has been stripped; | |||
| * This is ASSUMING that there is only 1 CSRC, which isn't wise. */ | |||
| switch (st->codec->codec_id) { | |||
| case AV_CODEC_ID_MP2: | |||
| case AV_CODEC_ID_MP3: | |||
| /* better than nothing: skip MPEG audio RTP header */ | |||
| if (len <= 4) | |||
| return -1; | |||
| h = AV_RB32(buf); | |||
| len -= 4; | |||
| buf += 4; | |||
| if (av_new_packet(pkt, len) < 0) | |||
| return AVERROR(ENOMEM); | |||
| memcpy(pkt->data, buf, len); | |||
| break; | |||
| case AV_CODEC_ID_MPEG1VIDEO: | |||
| case AV_CODEC_ID_MPEG2VIDEO: | |||
| /* better than nothing: skip MPEG video RTP header */ | |||
| if (len <= 4) | |||
| return -1; | |||
| h = AV_RB32(buf); | |||
| buf += 4; | |||
| len -= 4; | |||
| if (h & (1 << 26)) { | |||
| /* MPEG-2 */ | |||
| if (len <= 4) | |||
| return -1; | |||
| buf += 4; | |||
| len -= 4; | |||
| } | |||
| if (av_new_packet(pkt, len) < 0) | |||
| return AVERROR(ENOMEM); | |||
| memcpy(pkt->data, buf, len); | |||
| break; | |||
| default: | |||
| if (av_new_packet(pkt, len) < 0) | |||
| return AVERROR(ENOMEM); | |||
| memcpy(pkt->data, buf, len); | |||
| break; | |||
| } | |||
| if (av_new_packet(pkt, len) < 0) | |||
| return AVERROR(ENOMEM); | |||
| memcpy(pkt->data, buf, len); | |||
| pkt->stream_index = st->index; | |||
| } else { | |||
| return AVERROR(EINVAL); | |||
| @@ -49,6 +49,8 @@ extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_mpegts_dynamic_handler; | |||
| extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfa_handler; | |||
| @@ -23,6 +23,14 @@ | |||
| #include "rtpdec_formats.h" | |||
| #include "libavutil/intreadwrite.h" | |||
| static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; | |||
| return 0; | |||
| } | |||
| int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, | |||
| AVStream *st, AVPacket *pkt, uint32_t *timestamp, | |||
| const uint8_t *buf, int len, uint16_t seq, int flags) | |||
| @@ -92,6 +100,7 @@ RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = { | |||
| .enc_name = "H263-1998", | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_H263, | |||
| .init = h263_init, | |||
| .parse_packet = ff_h263_handle_packet, | |||
| }; | |||
| @@ -99,5 +108,6 @@ RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = { | |||
| .enc_name = "H263-2000", | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_H263, | |||
| .init = h263_init, | |||
| .parse_packet = ff_h263_handle_packet, | |||
| }; | |||
| @@ -55,6 +55,14 @@ static void h263_free_context(PayloadContext *data) | |||
| av_free(data); | |||
| } | |||
| static int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; | |||
| return 0; | |||
| } | |||
| static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, | |||
| AVStream *st, AVPacket *pkt, uint32_t *timestamp, | |||
| const uint8_t *buf, int len, uint16_t seq, | |||
| @@ -198,6 +206,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, | |||
| RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = { | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_H263, | |||
| .init = h263_init, | |||
| .parse_packet = h263_handle_packet, | |||
| .alloc = h263_new_context, | |||
| .free = h263_free_context, | |||
| @@ -338,6 +338,14 @@ static void h264_free_context(PayloadContext *data) | |||
| av_free(data); | |||
| } | |||
| static int h264_init(AVFormatContext *s, int st_index, PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; | |||
| return 0; | |||
| } | |||
| static int parse_h264_sdp_line(AVFormatContext *s, int st_index, | |||
| PayloadContext *h264_data, const char *line) | |||
| { | |||
| @@ -383,6 +391,7 @@ RTPDynamicProtocolHandler ff_h264_dynamic_handler = { | |||
| .enc_name = "H264", | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_H264, | |||
| .init = h264_init, | |||
| .parse_sdp_a_line = parse_h264_sdp_line, | |||
| .alloc = h264_new_context, | |||
| .free = h264_free_context, | |||
| @@ -0,0 +1,72 @@ | |||
| /* | |||
| * Common code for the RTP depacketization of MPEG-1/2 formats. | |||
| * Copyright (c) 2002 Fabrice Bellard | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg 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. | |||
| * | |||
| * FFmpeg 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 FFmpeg; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #include "rtpdec_formats.h" | |||
| #include "libavutil/intreadwrite.h" | |||
| static int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; | |||
| return 0; | |||
| } | |||
| static int mpeg_parse_packet(AVFormatContext *ctx, PayloadContext *data, | |||
| AVStream *st, AVPacket *pkt, uint32_t *timestamp, | |||
| const uint8_t *buf, int len, uint16_t seq, | |||
| int flags) | |||
| { | |||
| unsigned int h; | |||
| if (len <= 4) | |||
| return AVERROR_INVALIDDATA; | |||
| h = AV_RB32(buf); | |||
| buf += 4; | |||
| len -= 4; | |||
| if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && h & (1 << 26)) { | |||
| /* MPEG-2 */ | |||
| if (len <= 4) | |||
| return AVERROR_INVALIDDATA; | |||
| buf += 4; | |||
| len -= 4; | |||
| } | |||
| if (av_new_packet(pkt, len) < 0) | |||
| return AVERROR(ENOMEM); | |||
| memcpy(pkt->data, buf, len); | |||
| pkt->stream_index = st->index; | |||
| return 0; | |||
| } | |||
| RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler = { | |||
| .codec_type = AVMEDIA_TYPE_AUDIO, | |||
| .codec_id = AV_CODEC_ID_MP3, | |||
| .init = mpeg_init, | |||
| .parse_packet = mpeg_parse_packet, | |||
| .static_payload_id = 14, | |||
| }; | |||
| RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler = { | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_MPEG2VIDEO, | |||
| .init = mpeg_init, | |||
| .parse_packet = mpeg_parse_packet, | |||
| .static_payload_id = 32, | |||
| }; | |||
| @@ -252,10 +252,19 @@ static int parse_sdp_line(AVFormatContext *s, int st_index, | |||
| return 0; | |||
| } | |||
| static int init_video(AVFormatContext *s, int st_index, PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; | |||
| return 0; | |||
| } | |||
| RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = { | |||
| .enc_name = "MP4V-ES", | |||
| .codec_type = AVMEDIA_TYPE_VIDEO, | |||
| .codec_id = AV_CODEC_ID_MPEG4, | |||
| .init = init_video, | |||
| .parse_sdp_a_line = parse_sdp_line, | |||
| }; | |||
| @@ -69,6 +69,16 @@ static void xiph_free_context(PayloadContext * data) | |||
| av_free(data); | |||
| } | |||
| static int xiph_vorbis_init(AVFormatContext *ctx, int st_index, | |||
| PayloadContext *data) | |||
| { | |||
| if (st_index < 0) | |||
| return 0; | |||
| ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_HEADERS; | |||
| return 0; | |||
| } | |||
| static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data, | |||
| AVStream *st, AVPacket *pkt, uint32_t *timestamp, | |||
| const uint8_t *buf, int len, uint16_t seq, | |||
| @@ -391,6 +401,7 @@ RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = { | |||
| .enc_name = "vorbis", | |||
| .codec_type = AVMEDIA_TYPE_AUDIO, | |||
| .codec_id = AV_CODEC_ID_VORBIS, | |||
| .init = xiph_vorbis_init, | |||
| .parse_sdp_a_line = xiph_parse_sdp_line, | |||
| .alloc = xiph_new_context, | |||
| .free = xiph_free_context, | |||