[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