[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