Ejemplo n.º 1
0
/**
 * \brief mjpeg encode an image
 *
 * This routine will take a 3-plane YUV422 image and encoded it with MJPEG
 * base line format, as suitable as input for the Zoran hardare MJPEG chips.
 *
 * It requires that the \a j parameter points the structure set up by the
 * jpeg_enc_init() routine.
 *
 * \param j pointer to jpeg_enc_t structure as created by jpeg_enc_init()
 * \param y_data pointer to Y component plane, packed one byte/pixel
 * \param u_data pointer to U component plane, packed one byte per every
 *		 other pixel
 * \param v_data pointer to V component plane, packed one byte per every
 *		 other pixel
 * \param bufr pointer to the buffer where the mjpeg encoded code is stored
 *
 * \returns the number of bytes stored into \a bufr
 *
 * If \a j->s->mjpeg_write_tables is set, it will also emit the mjpeg tables,
 * otherwise it will just emit the data. The \a j->s->mjpeg_write_tables
 * variable will be reset to 0 by the routine.
 */
static int jpeg_enc_frame(jpeg_enc_t *j, uint8_t *y_data,
		   uint8_t *u_data, uint8_t *v_data, uint8_t *bufr) {
	int mb_x, mb_y, overflow;
	/* initialize the buffer */

	init_put_bits(&j->s->pb, bufr, 1024*256);

	// Emit the mjpeg header blocks
	ff_mjpeg_encode_picture_header(j->s);

	j->s->header_bits = put_bits_count(&j->s->pb);

	j->s->last_dc[0] = 128;
	j->s->last_dc[1] = 128;
	j->s->last_dc[2] = 128;

	for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) {
		for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) {
			/*
			 * Fill one DCT block (8x8 pixels) from
			 * 2 Y macroblocks and one U and one V
			 */
			fill_block(j, mb_x, mb_y, y_data, u_data, v_data);
			emms_c(); /* is this really needed? */

			j->s->block_last_index[0] =
				j->s->dct_quantize(j->s, j->s->block[0],
						0, 8, &overflow);
			if (overflow) clip_coeffs(j->s, j->s->block[0],
					j->s->block_last_index[0]);
			j->s->block_last_index[1] =
				j->s->dct_quantize(j->s, j->s->block[1],
						1, 8, &overflow);
			if (overflow) clip_coeffs(j->s, j->s->block[1],
					j->s->block_last_index[1]);

			if (!j->bw) {
				j->s->block_last_index[4] =
					j->s->dct_quantize(j->s, j->s->block[2],
							4, 8, &overflow);
				if (overflow) clip_coeffs(j->s, j->s->block[2],
						j->s->block_last_index[2]);
				j->s->block_last_index[5] =
					j->s->dct_quantize(j->s, j->s->block[3],
							5, 8, &overflow);
				if (overflow) clip_coeffs(j->s, j->s->block[3],
						j->s->block_last_index[3]);
			}
			zr_mjpeg_encode_mb(j);
		}
	}
	emms_c();
	ff_mjpeg_encode_picture_trailer(j->s);
	flush_put_bits(&j->s->pb);

	//FIXME
	//if (j->s->mjpeg_write_tables == 1)
	//	j->s->mjpeg_write_tables = 0;

	return put_bits_ptr(&(j->s->pb)) - j->s->pb.buf;
}
Ejemplo n.º 2
0
int jpeg_enc_frame(jpeg_enc_t *j, unsigned char *y_data,
                   unsigned char *u_data, unsigned char *v_data, char *bufr) {
    int i, k, mb_x, mb_y, overflow;
    short int *dest;
    unsigned char *source;
    /* initialize the buffer */

    init_put_bits(&j->s->pb, bufr, 1024*256);

    ff_mjpeg_encode_picture_header(j->s);

    j->s->header_bits = put_bits_count(&j->s->pb);

    j->s->last_dc[0] = 128;
    j->s->last_dc[1] = 128;
    j->s->last_dc[2] = 128;

    for (mb_y = 0; mb_y < j->s->mb_height; mb_y++) {
        for (mb_x = 0; mb_x < j->s->mb_width; mb_x++) {
            /* conversion 8 to 16 bit and filling of blocks
             * must be mmx optimized */
            /* fill 2 Y macroblocks and one U and one V */
            source = mb_y * 8 * j->y_rs +
                     16 * j->y_ps * mb_x + y_data;
            dest = j->s->block[0];
            for (i = 0; i < 8; i++) {
                for (k = 0; k < 8; k++) {
                    dest[k] = source[k*j->y_ps];
                }
                dest += 8;
                source += j->y_rs;
            }
            source = mb_y * 8 * j->y_rs +
                     (16*mb_x + 8)*j->y_ps + y_data;
            dest = j->s->block[1];
            for (i = 0; i < 8; i++) {
                for (k = 0; k < 8; k++) {
                    dest[k] = source[k*j->y_ps];
                }
                dest += 8;
                source += j->y_rs;
            }
            if (!j->bw && j->cheap_upsample) {
                source = mb_y*4*j->u_rs +
                         8*mb_x*j->u_ps + u_data;
                dest = j->s->block[2];
                for (i = 0; i < 4; i++) {
                    for (k = 0; k < 8; k++) {
                        dest[k] = source[k*j->u_ps];
                        dest[k+8] = source[k*j->u_ps];
                    }
                    dest += 16;
                    source += j->u_rs;
                }
                source = mb_y*4*j->v_rs +
                         8*mb_x*j->v_ps + v_data;
                dest = j->s->block[3];
                for (i = 0; i < 4; i++) {
                    for (k = 0; k < 8; k++) {
                        dest[k] = source[k*j->v_ps];
                        dest[k+8] = source[k*j->v_ps];
                    }
                    dest += 16;
                    source += j->u_rs;
                }
            } else if (!j->bw && !j->cheap_upsample) {
                source = mb_y*8*j->u_rs +
                         8*mb_x*j->u_ps + u_data;
                dest = j->s->block[2];
                for (i = 0; i < 8; i++) {
                    for (k = 0; k < 8; k++)
                        dest[k] = source[k*j->u_ps];
                    dest += 8;
                    source += j->u_rs;
                }
                source = mb_y*8*j->v_rs +
                         8*mb_x*j->v_ps + v_data;
                dest = j->s->block[3];
                for (i = 0; i < 8; i++) {
                    for (k = 0; k < 8; k++)
                        dest[k] = source[k*j->v_ps];
                    dest += 8;
                    source += j->u_rs;
                }
            }
            emms_c(); /* is this really needed? */

            j->s->block_last_index[0] =
                j->s->dct_quantize(j->s, j->s->block[0],
                                   0, 8, &overflow);
            if (overflow) clip_coeffs(j->s, j->s->block[0],
                                          j->s->block_last_index[0]);
            j->s->block_last_index[1] =
                j->s->dct_quantize(j->s, j->s->block[1],
                                   1, 8, &overflow);
            if (overflow) clip_coeffs(j->s, j->s->block[1],
                                          j->s->block_last_index[1]);

            if (!j->bw) {
                j->s->block_last_index[4] =
                    j->s->dct_quantize(j->s, j->s->block[2],
                                       4, 8, &overflow);
                if (overflow) clip_coeffs(j->s, j->s->block[2],
                                              j->s->block_last_index[2]);
                j->s->block_last_index[5] =
                    j->s->dct_quantize(j->s, j->s->block[3],
                                       5, 8, &overflow);
                if (overflow) clip_coeffs(j->s, j->s->block[3],
                                              j->s->block_last_index[3]);
            }
            zr_mjpeg_encode_mb(j);
        }
    }
    emms_c();
    ff_mjpeg_encode_picture_trailer(j->s);
    flush_put_bits(&j->s->pb);

    //FIXME
    //if (j->s->mjpeg_write_tables == 1)
    //	j->s->mjpeg_write_tables = 0;

    return pbBufPtr(&(j->s->pb)) - j->s->pb.buf;
}