[FFmpeg-devel] [PATCH]Basic XSUB encoder (take 3)

Reimar Döffinger Reimar.Doeffinger
Thu Feb 5 00:42:12 CET 2009


On Thu, Feb 05, 2009 at 12:07:56AM +0100, Bj?rn Axelsson wrote:
> +/** Encode a single color run. At most 16 bits will be used. */
> +void put_xsub_rle(PutBitContext *pb, int len, int color)

static

> +{
> +    if (len <= 255)
> +        put_bits(pb, 2 + ((ff_log2_tab[len] >> 1) << 2), len);
> +    else
> +        put_bits(pb, 14, 0);
> +    put_bits(pb, 2, color);

If you add a
> if (!len) return;
you would not need most of the PADDING checks.
Not sure if it is better, but this could also be written as
> int bits = 14;
> if (len > 255)
>     len = 0;
> else
>     bits = 2 + ((ff_log2_tab[len] >> 1) << 2);
> put_bits(pb, bits, len);


> +            // One run + padding will need 3 bytes in worst case
> +            if (bufsize - ((put_bits_count(&pb) + 7) >> 3) < 3)

The worst case is 3 runs + padding.

> +    // Buffer large enough to hold static header?
> +    if (bufsize < 27 + 7*2 + 4*3) {
> +        av_log(avctx, AV_LOG_ERROR, "Buffer too small for XSUB header.\n");
> +        return -1;
> +    }
[...]
> +    // Bitmap
> +    q = hdr;
> +    if (xsub_encode_rle(&q, bufsize - (q-buf),
> +                h->rects[0]->pict.data[0],
> +                h->rects[0]->pict.linesize[0]*2,
> +                h->rects[0]->w, (h->rects[0]->h + 1) / 2))
> +        return -1;
> +    bytestream_put_le16(&rlelenptr, q-hdr); // Length of first field
> +
> +    if (xsub_encode_rle(&q, bufsize - (q-buf),
> +            h->rects[0]->pict.data[0] + h->rects[0]->pict.linesize[0],
> +            h->rects[0]->pict.linesize[0]*2,
> +            h->rects[0]->w, h->rects[0]->h / 2))
> +        return -1;
> +
> +    // Enforce total height to be be multiple of 2
> +    if (h->rects[0]->h & 1) {
> +        if (bufsize - (q - buf) < 2)
> +            return -1;
> +        bytestream_put_le16(&q, PADDING_COLOR); // RLE empty line
> +    }

you can avoid this check by doing at the very beginning
> bufsize -= 27 + 7*2 + 4*3 + 2;
> if (bufsize <= 0) {
...
and using
> xsub_encode_rle(&q, bufsize - (q-hdr),

It would be possible to save one byte for small subtitles by using
put_xsub_rle to write the final line, but that might get ugly -
at least unless you pass the put_bits context to xsub_encode_rle.




More information about the ffmpeg-devel mailing list