diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index d81fa9dd0f..ea19b819cc 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1635,6 +1635,12 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) return -1; } + if (s->avctx->hwaccel && + (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) { + if (s->avctx->hwaccel->end_frame(s->avctx) < 0) + av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode first field\n"); + } + for (i = 0; i < 4; i++) { s->current_picture.f.data[i] = s->current_picture_ptr->f.data[i]; if (s->picture_structure == PICT_BOTTOM_FIELD) { diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 030f76bfb9..e6ff764f61 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -132,7 +132,7 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer return -1; slice_param->macroblock_offset = macroblock_offset; slice_param->slice_horizontal_position = s->mb_x; - slice_param->slice_vertical_position = s->mb_y; + slice_param->slice_vertical_position = s->mb_y >> (s->picture_structure != PICT_FRAME); slice_param->quantiser_scale_code = quantiser_scale_code; slice_param->intra_slice_flag = intra_slice_flag; return 0; diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 440609928f..b7240a2d51 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -385,7 +385,7 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext av_free(s); return NULL; } - } else { + } else if (st) { switch(st->codec->codec_id) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: diff --git a/libavformat/rtpdec_amr.c b/libavformat/rtpdec_amr.c index de824904aa..86033cf8d2 100644 --- a/libavformat/rtpdec_amr.c +++ b/libavformat/rtpdec_amr.c @@ -169,6 +169,9 @@ static int amr_parse_sdp_line(AVFormatContext *s, int st_index, const char *p; int ret; + if (st_index < 0) + return 0; + /* Parse an fmtp line this one: * a=fmtp:97 octet-align=1; interleaving=0 * That is, a normal fmtp: line followed by semicolon & space diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c index 65b466669d..84503f1749 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -130,6 +130,8 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index, PayloadContext *asf, const char *line) { + if (stream_index < 0) + return 0; if (av_strstart(line, "stream:", &line)) { RTSPState *rt = s->priv_data; diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c index 01514c1bef..0366ba0205 100644 --- a/libavformat/rtpdec_h264.c +++ b/libavformat/rtpdec_h264.c @@ -357,10 +357,15 @@ static void h264_free_context(PayloadContext *data) static int parse_h264_sdp_line(AVFormatContext *s, int st_index, PayloadContext *h264_data, const char *line) { - AVStream *stream = s->streams[st_index]; - AVCodecContext *codec = stream->codec; + AVStream *stream; + AVCodecContext *codec; const char *p = line; + if (st_index < 0) + return 0; + + stream = s->streams[st_index]; + codec = stream->codec; assert(h264_data->cookie == MAGIC_COOKIE); if (av_strstart(p, "framesize:", &p)) { diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c index a642b5a079..cc24c82c50 100644 --- a/libavformat/rtpdec_latm.c +++ b/libavformat/rtpdec_latm.c @@ -168,6 +168,9 @@ static int latm_parse_sdp_line(AVFormatContext *s, int st_index, { const char *p; + if (st_index < 0) + return 0; + if (av_strstart(line, "fmtp:", &p)) return ff_parse_fmtp(s->streams[st_index], data, p, parse_fmtp); diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index 9b388782b3..b11cc79842 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -223,6 +223,9 @@ static int parse_sdp_line(AVFormatContext *s, int st_index, { const char *p; + if (st_index < 0) + return 0; + if (av_strstart(line, "fmtp:", &p)) return ff_parse_fmtp(s->streams[st_index], data, p, parse_fmtp); diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c index 6aeea2fd3c..771a13d9d2 100644 --- a/libavformat/rtpdec_xiph.c +++ b/libavformat/rtpdec_xiph.c @@ -372,10 +372,13 @@ static int xiph_parse_fmtp_pair(AVStream* stream, } static int xiph_parse_sdp_line(AVFormatContext *s, int st_index, - PayloadContext *data, const char *line) + PayloadContext *data, const char *line) { const char *p; + if (st_index < 0) + return 0; + if (av_strstart(line, "fmtp:", &p)) { return ff_parse_fmtp(s->streams[st_index], data, p, xiph_parse_fmtp_pair); diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 9961b5a33c..fb6df692ac 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -374,6 +374,10 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) { /* no corresponding stream */ + } else if (rt->server_type == RTSP_SERVER_WMS && + codec_type == AVMEDIA_TYPE_DATA) { + /* RTX stream, a stream that carries all the other actual + * audio/video streams. Don't expose this to the callers. */ } else { st = avformat_new_stream(s, NULL); if (!st) @@ -430,9 +434,11 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ get_word(buf1, sizeof(buf1), &p); payload_type = atoi(buf1); - st = s->streams[s->nb_streams - 1]; rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1]; - sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p); + if (rtsp_st->stream_index >= 0) { + st = s->streams[rtsp_st->stream_index]; + sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p); + } } else if (av_strstart(p, "fmtp:", &p) || av_strstart(p, "framesize:", &p)) { /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ @@ -467,14 +473,15 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, if (rt->server_type == RTSP_SERVER_WMS) ff_wms_parse_sdp_a_line(s, p); if (s->nb_streams > 0) { - if (rt->server_type == RTSP_SERVER_REAL) - ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p); - rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1]; + + if (rt->server_type == RTSP_SERVER_REAL) + ff_real_parse_sdp_a_line(s, rtsp_st->stream_index, p); + if (rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) rtsp_st->dynamic_handler->parse_sdp_a_line(s, - s->nb_streams - 1, + rtsp_st->stream_index, rtsp_st->dynamic_protocol_context, buf); } } @@ -1245,8 +1252,9 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, * UDP. When trying to set it up for TCP streams, the server * will return an error. Therefore, we skip those streams. */ if (rt->server_type == RTSP_SERVER_WMS && - s->streams[rtsp_st->stream_index]->codec->codec_type == - AVMEDIA_TYPE_DATA) + (rtsp_st->stream_index < 0 || + s->streams[rtsp_st->stream_index]->codec->codec_type == + AVMEDIA_TYPE_DATA)) continue; snprintf(transport, sizeof(transport) - 1, "%s/TCP;", trans_pref); @@ -1378,7 +1386,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, goto fail; } - if (reply->timeout > 0) + if (rt->nb_rtsp_streams && reply->timeout > 0) rt->timeout = reply->timeout; if (rt->server_type == RTSP_SERVER_REAL) diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index ea2d517e3c..9c7df96a8f 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -159,8 +159,9 @@ static int rtsp_read_header(AVFormatContext *s) if (ret) return ret; - rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache)); - if (!rt->real_setup_cache) + rt->real_setup_cache = !s->nb_streams ? NULL : + av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache)); + if (!rt->real_setup_cache && s->nb_streams) return AVERROR(ENOMEM); rt->real_setup = rt->real_setup_cache + s->nb_streams;