Example #1
0
static int rl2_decode_frame(AVCodecContext *avctx,
                              void *data, int *data_size,
                              AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    Rl2Context *s = avctx->priv_data;

    if(s->frame.data[0])
        avctx->release_buffer(avctx, &s->frame);

    /** get buffer */
    s->frame.reference= 0;
    if(avctx->get_buffer(avctx, &s->frame)) {
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }

    /** run length decode */
    rl2_rle_decode(s,buf,buf_size,s->frame.data[0],s->frame.linesize[0],s->video_base);

    /** make the palette available on the way out */
    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;

    /** report that the buffer was completely consumed */
    return buf_size;
}
Example #2
0
/**
 * Initialize the decoder
 * @param avctx decoder context
 * @return 0 success, -1 on error
 */
static av_cold int rl2_decode_init(AVCodecContext *avctx)
{
	Rl2Context *s = avctx->priv_data;
	int back_size;
	int i;
	s->avctx = avctx;
	avctx->pix_fmt = PIX_FMT_PAL8;

	/** parse extra data */
	if(!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE)
	{
		av_log(avctx, AV_LOG_ERROR, "invalid extradata size\n");
		return -1;
	}

	/** get frame_offset */
	s->video_base = AV_RL16(&avctx->extradata[0]);
	s->clr_count = AV_RL32(&avctx->extradata[2]);

	if(s->video_base >= avctx->width * avctx->height)
	{
		av_log(avctx, AV_LOG_ERROR, "invalid video_base\n");
		return -1;
	}

	/** initialize palette */
	for(i=0; i<AVPALETTE_COUNT; i++)
		s->palette[i] = AV_RB24(&avctx->extradata[6 + i * 3]);

	/** decode background frame if present */
	back_size = avctx->extradata_size - EXTRADATA1_SIZE;

	if(back_size > 0)
	{
		unsigned char* back_frame = av_mallocz(avctx->width*avctx->height);
		if(!back_frame)
			return -1;
		rl2_rle_decode(s,avctx->extradata + EXTRADATA1_SIZE,back_size,
		               back_frame,avctx->width,0);
		s->back_frame = back_frame;
	}
	return 0;
}