[FFmpeg-devel] [PATCH] CD+G Demuxer & Decoder

Vitor Sessak vitor1001
Tue Dec 1 14:58:30 CET 2009


Michael Tison wrote:
> Hi,
> 
> Attached is another revised patch.

A few comments:

> +static av_cold int cdg_decode_init(AVCodecContext *avctx)
> +{
> +    CDGraphicsContext *cc = avctx->priv_data;
> +
> +    cdg_init_frame(&cc->frame);
> +
> +    cc->hscroll = 0;
> +    cc->vscroll = 0;

Unneeded, cc is already memset to 0 before calling decode_init().

> +
> +static void cdg_load_color_table(CDGraphicsContext *cc, CdgPacket *cp,
> +                                 int low)
> +{

I think a s/color.table/palette/ would be closer to usual multimedia 
terminology.

> +static void cdg_fill_rect_buf(int out_tl_x, int out_tl_y,
> +                              uint8_t *out,
> +                              int in_tl_x, int in_tl_y,
> +                              uint8_t *in, int w, int h, int lsize)
> +{
> +    int x, y;
> +    in = in + in_tl_x + in_tl_y * lsize;
> +    out = out + out_tl_x + out_tl_y * lsize;
> +    for (y = 0; y < h; y++)
> +       for (x = 0; x < w; x++)
> +           out[x + y * lsize] = in[x + y * lsize];
> +}
> +

The inner loop is a memcpy().

> +static void cdg_fill_rect_preset(int tl_x, int tl_y,
> +                                 uint8_t *out, int color,
> +                                 int w, int h, int lsize)
> +{
> +    int x, y;
> +
> +    for (y = tl_y; y < tl_y + h; y++)
> +       for (x = tl_x; x < tl_x + w; x++)
> +           out[x + y * lsize] = color;
> +}

The inner loop is a memset().

> +static void cdg_scroll(CDGraphicsContext *cc, CdgPacket *cp,
> +                      AVFrame *new_frame, int roll_over)
> +{
> +    int color;
> +    int hscmd, h_off, vscmd, v_off, dh_off, dv_off;
> +    int vinc = 0, hinc = 0, x, y;
> +    int ai;
> +    int lsize    = cc->frame.linesize[0];
> +    uint8_t *in  = cc->frame.data[0];
> +    uint8_t *out = new_frame->data[0];
> +
> +    assert(cc->frame.linesize[0] == new_frame->linesize[0]);
> +
> +    cdg_get_scroll_data(cp, &color, &hscmd, &h_off, &vscmd, &v_off);
> +
> +    /// find the difference and save the offset for cdg_tile_block usage
> +    dh_off = h_off - cc->hscroll;
> +    dv_off = v_off - cc->vscroll;
> +    cc->hscroll = h_off;
> +    cc->vscroll = v_off;
> +
> +    if (vscmd == UP)
> +       vinc = -12;
> +    if (vscmd == DOWN)
> +       vinc = 12;
> +    if (hscmd == LEFT)
> +       hinc = -6;
> +    if (hscmd == RIGHT)
> +       hinc = 6;
> +    vinc += dv_off;
> +    hinc += dh_off;
> +
> +    if (!hinc && !vinc)
> +       return;
> +
> +    memcpy(new_frame->data[1], cc->frame.data[1],
> +          CDG_COLOR_TABLE_SIZE * 4);
> +
> +    for (y = 0; y < CDG_FULL_HEIGHT; y++) {
> +       for (x = 0; x < lsize; x++) {
> +           ai = x + hinc + lsize * (y + vinc);
> +           if (ai >= 0 && ai < CDG_FULL_HEIGHT * lsize)
> +               out[ai] = in[x + y * lsize];
> +       }
> +    }

for (x = FFMAX(0, hinc); x < FFMIN(lsize, hinc); x++)
and similar for y and them there is no need for the slow branch in the 
inner loop.

> +static int cdg_decode_frame(AVCodecContext *avctx,
> +                            void *data, int *data_size, AVPacket *avpkt)
> +{
> +    const uint8_t *buf = avpkt->data;
> +    int buf_size = avpkt->size;
> +    AVFrame new_frame;
> +    CDGraphicsContext *cc = avctx->priv_data;
> +    CdgPacket cp;
> +
> +    if (avctx->reget_buffer(avctx, &cc->frame)) {
> +       av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
> +       return -1;
> +    }
> +
> +    cp.command     = bytestream_get_byte(&buf);
> +    cp.instruction = bytestream_get_byte(&buf);
> +    bytestream_get_buffer(&buf, (uint8_t *) & cp.parityQ, 2);
> +    bytestream_get_buffer(&buf, (uint8_t *) & cp.data,   16);
> +    bytestream_get_buffer(&buf, (uint8_t *) & cp.parityP, 2);

Are those casts needed?

-Vitor



More information about the ffmpeg-devel mailing list