[FFmpeg-devel] [PATCH 4/6] lavc: support multiple frames in a singe AVPacket in avcodec_decode_subtitle2
Marton Balint
cus at passwd.hu
Mon Oct 14 21:17:16 CEST 2013
On Sat, 5 Oct 2013, Marton Balint wrote:
> This feature is also known as CODEC_CAP_SUBFRAMES support. The patch also adds
> CODEC_CAP_DELAY support to avcodec_decode_subtitle2.
>
> For DVB teletext decoding, a single teletext packet can contain multiple
> teletext pages. In order to support that, we extend the API the same way it is
> used now for audio decoding.
Is there anybody, who is actually against this patch?
Thanks,
Marton
>
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
> doc/APIchanges | 4 ++++
> ffmpeg.c | 2 +-
> libavcodec/avcodec.h | 13 +++++++++++++
> libavcodec/utils.c | 11 +++++++++--
> libavcodec/version.h | 2 +-
> libavformat/utils.c | 1 -
> 6 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index dc43313..1706c97 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -15,6 +15,10 @@ libavutil: 2012-10-22
>
> API changes, most recent first:
>
> +2013-10-xx - xxxxxxx - lavc 55.35.100 - avcodec.h
> + Add CODEC_CAP_DELAY and CODEC_CAP_SUBFRAMES support to
> + avcodec_decode_subtitle2.
> +
> 2013-10-03 - xxxxxxx - lavc 55.34.100 - avcodec.h
> Add av_codec_get_max_lowres()
>
> diff --git a/ffmpeg.c b/ffmpeg.c
> index d1c841f..47c94aa 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -1897,7 +1897,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
>
> // touch data and size only if not EOF
> if (pkt) {
> - if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
> + if(ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
> ret = avpkt.size;
> avpkt.data += ret;
> avpkt.size -= ret;
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 2917a2f..5447a8e 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -3875,11 +3875,24 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
> * Return a negative value on error, otherwise return the number of bytes used.
> * If no subtitle could be decompressed, got_sub_ptr is zero.
> * Otherwise, the subtitle is stored in *sub.
> + *
> + * Some decoders may support multiple frames in a single AVPacket. Such
> + * decoders would then just decode the first frame. In this case,
> + * avcodec_decode_subtitle2 has to be called again with an AVPacket containing
> + * the remaining data in order to decode the second frame, etc...
> + * Even if no frames are returned, or a frame is returned but no data is
> + * consumed, the packet needs to be fed to the decoder with remaining data
> + * until it is completely consumed or an error occurs.
> + *
> * Note that CODEC_CAP_DR1 is not available for subtitle codecs. This is for
> * simplicity, because the performance difference is expect to be negligible
> * and reusing a get_buffer written for video codecs would probably perform badly
> * due to a potentially very different allocation pattern.
> *
> + * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
> + * between input and output, these need to be fed with avpkt->data=NULL,
> + * avpkt->size=0 at the end to return the remaining frames.
> + *
> * @param avctx the codec context
> * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored, must be
> freed with avsubtitle_free if *got_sub_ptr is set.
> diff --git a/libavcodec/utils.c b/libavcodec/utils.c
> index 20de48e..ea30c39 100644
> --- a/libavcodec/utils.c
> +++ b/libavcodec/utils.c
> @@ -2330,15 +2330,22 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
> {
> int i, ret = 0;
>
> + *got_sub_ptr = 0;
> +
> + if (!avpkt->data && avpkt->size) {
> + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
> + return AVERROR(EINVAL);
> + }
> + if (!avctx->codec)
> + return AVERROR(EINVAL);
> if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
> av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
> return AVERROR(EINVAL);
> }
>
> - *got_sub_ptr = 0;
> avcodec_get_subtitle_defaults(sub);
>
> - if (avpkt->size) {
> + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
> AVPacket pkt_recoded;
> AVPacket tmp = *avpkt;
> int did_split = av_packet_split_side_data(&tmp);
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index 7f9682e..63a2d8f 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -29,7 +29,7 @@
> #include "libavutil/avutil.h"
>
> #define LIBAVCODEC_VERSION_MAJOR 55
> -#define LIBAVCODEC_VERSION_MINOR 34
> +#define LIBAVCODEC_VERSION_MINOR 35
> #define LIBAVCODEC_VERSION_MICRO 100
>
> #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 61405d7..becac14 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -2512,7 +2512,6 @@ static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, A
> case AVMEDIA_TYPE_SUBTITLE:
> ret = avcodec_decode_subtitle2(st->codec, &subtitle,
> &got_picture, &pkt);
> - ret = pkt.size;
> break;
> default:
> break;
> --
> 1.8.1.4
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
More information about the ffmpeg-devel
mailing list