/** * \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; }
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; }