[Ffmpeg-devel] [PATCH] C93 demuxer and decoder (GSoC qualification task)
Anssi Hannula
anssi.hannula
Mon Apr 2 14:45:34 CEST 2007
M?ns Rullg?rd wrote:
> Anssi Hannula <anssi.hannula at gmail.com> writes:
>> + if (avctx->reget_buffer(avctx, newpic)) {
>> + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
>> + return -1;
>> + }
>> + if (avctx->reget_buffer(avctx, oldpic)) {
>> + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
>> + return -1;
>> + }
>> +
>> + stride = newpic->linesize[0];
>> + out = newpic->data[0];
>> +
>> + newpic->reference = 1;
>> + if (buf[0] & 0x02) { /* first frame */
>
> #define C93_FIRST_FRAME 2 or something and drop the comment.
OK.
>> + }
>> + }
>> +
>> + bt1 = bt2 = 0;
>> + for (x = y = 0; x < 320 || y < 184; x += 8) {
>> + int offset, y_off, x_off, j, k, col0, col1;
>> + int colbit = 0;
>> + int cols[4];
>> +
>> + if (x >= 320) {
>> + y += 8;
>> + x = 0;
>> + }
>> + if (!bt1) {
>> + bt1 = buf[0] & 0x0F;
>> + bt2 = (buf[0] >> 4) & 0x0F;
>> + buf++;
>> + }
>> +
>> + switch (bt1) {
>> + case C93_8X8_FROM_PREV:
>> + offset = AV_RL16(buf);
>> + buf += 2;
>> + for (j = 0; j < 8; j++)
>> + for (i = 0; i < 8; i++) {
>> + int loc = c93_conv_offset(offset, i, j, 8, stride);
>
> I'm sure this could be calculated more efficiently than by calling
> that function for each iteration.
Will change.
>> + if (loc >= 192 * stride + 320) {
>> + av_log(avctx, AV_LOG_ERROR, "invalid offset %d for"
>> + " mode 2 at %dx%d\n", offset, x, y);
>> + return -1;
>> + }
>> + out[(y+j)*stride+x+i] = oldpic->data[0][loc];
>> + }
>
> Isn't this just another way of saying memcpy()?
Not if data pointed to by 'offset' is close to the right-side border of
frame, so precautions (c93_conv_offset()) have to be taken to ensure we
do not copy data from outside the frame area of oldpic. Should be made
more efficient, though.
> If it can't be
> removed, the outer for loop should also have braces. There's enough
> stuff inside it that braces would make it easier to read.
Ok.
>> + break;
>> +
>> + case C93_4X4_FROM_PREV:
>> + for (k = 0; k < 4; k++) {
>> + y_off = k > 1 ? 4 : 0;
>> + x_off = (k % 2) ? 4 : 0;
>
> k & 1 or make k unsigned (or both).
OK.
>> + offset = AV_RL16(buf);
>> + if (offset >= 320 * 192) {
>> + return -1;
>
> No reason?
Oops, I forgot to av_log the error (invalid offset).
Actually, the offset value should be checked more carefully here, so
that the check inside the loop below could be removed:
>> + }
>> + buf += 2;
>> + for (j = 0; j < 4; j++)
>> + for (i = 0; i < 4; i++) {
>> + int loc = c93_conv_offset(offset, i, j, 4, stride);
>> + if (loc >= 192 * stride + 320) {
>> + av_log(avctx, AV_LOG_ERROR, "invalid offset %d for"
>> + " mode 6 at %dx%d\n", offset, x, y);
>> + return -1;
>> + }
>> + out[(y+j+y_off)*stride+x+i+x_off] =
>> + oldpic->data[0][loc];
>> + }
>> + }
>> + break;
>
> [...]
>
> The other prediction modes are very similar. Try to merge them into
> an inline function. Constant arguments to an inline function allow
> the same optimizations as constants directly in the code.
I'll look into converting the similar ones to inline function(s).
>> + case C93_NOOP:
>> + break;
>> +
>> + case C93_8X8_INTRA:
>> + for (j = 0; j < 8; j++)
>> + for (i = 0; i < 8; i++)
>> + out[(y+j)*stride+x+i] = (buf++)[0];
>
> Replace the inner loop with a memcpy().
Right.
[...]
>> + }
>> + }
>> + }
>> + if (c93->current_frame >= br->frames) {
>> + if (c93->current_block >= 511 || !(br+1)->length)
>
> I prefer br[1].length.
Ok.
[...]
>> + ret = get_buffer(pb, pkt->data + 1, palettesize);
>> + if (ret < palettesize) {
>> + av_free_packet(pkt);
>> + return AVERROR_IO;
>> + }
>> + }
>> + url_fskip(pb, -(palettesize + videosize + 2));
>
> Somehow I don't like the look of that.
Indeed, see my reply to Reimar about a suggestion on how to remove it.
--
Anssi Hannula
More information about the ffmpeg-devel
mailing list