Add checksum SEI packages to the bit-stream.

This commit is contained in:
Ari Koivula 2013-09-05 15:59:51 +03:00
parent 0c0f72c908
commit 2b4f98e83d
3 changed files with 85 additions and 1 deletions

View file

@ -34,6 +34,9 @@
int16_t g_lambda_cost[55];
uint32_t* g_auiSigLastScan[3][7];
/* Local functions. */
static void add_checksum(encoder_control* encoder);
void initSigLastScan(uint32_t* pBuffD, uint32_t* pBuffH, uint32_t* pBuffV, int32_t iWidth, int32_t iHeight)
{
uint32_t uiNumScanPos = iWidth * iWidth;
@ -370,6 +373,8 @@ void encode_one_frame(encoder_control* encoder)
filter_deblock(encoder);
}
/* Calculate checksum */
add_checksum(encoder);
/* Clear prediction data */
/* ToDo: store as reference data */
@ -380,6 +385,37 @@ void encode_one_frame(encoder_control* encoder)
}
/*!
\brief Add a checksum SEI message to the bitstream.
\param encoder The encoder.
\returns Void
*/
static void add_checksum(encoder_control* encoder)
{
unsigned char checksum[3][16];
uint32_t checksum_val;
unsigned int i;
picture_checksum(&(encoder->in.cur_pic), checksum);
WRITE_U(encoder->stream, 132, 8, "sei_type");
WRITE_U(encoder->stream, 13, 8, "size");
WRITE_U(encoder->stream, 2, 8, "hash_type"); /* 2 = checksum*/
for (i = 0; i < 3; ++i) {
/* Pack bits into a single 32 bit uint instead of pushing them one byte at a time. */
checksum_val = (checksum[i][0] << 24) + (checksum[i][1] << 16) + (checksum[i][2] << 8) + (checksum[i][3]);
WRITE_U(encoder->stream, checksum_val, 32, 'picture_checksum');
}
bitstream_align(encoder->stream);
bitstream_flush(encoder->stream);
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_SUFFIT_SEI_NUT, 0);
bitstream_clear_buffer(encoder->stream);
}
void encode_pic_parameter_set(encoder_control* encoder)
{
#ifdef _DEBUG

View file

@ -85,4 +85,50 @@ void nal_write(FILE* output, uint8_t* buffer, uint32_t buffer_len, uint8_t nal_r
fwrite(&emulation_prevention_three_byte, 1, 1, output);
}
}
/*!
\brief Calculate checksum for one color of the picture.
\param data Beginning of the pixel data for the picture.
\param height Height of the picture.
\param width Width of the picture.
\param stride Width of one row in the pixel array.
\returns Void
*/
static void array_checksum(uint8_t* data, const int height, const int width, const int stride, unsigned char checksum_out[])
{
unsigned char mask;
unsigned int checksum = 0;
int y, x;
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
mask = (x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8);
checksum += (data[(y * stride) + x] & 0xff) ^ mask;
checksum &= 0xffffffff;
}
}
/* Unpack uint into byte-array.*/
checksum_out[0] = (checksum >> 24) & 0xff;
checksum_out[1] = (checksum >> 16) & 0xff;
checksum_out[2] = (checksum >> 8) & 0xff;
checksum_out[3] = (checksum) & 0xff;
}
/*!
\brief Calculate checksums for all colors of the picture.
\param pic The picture that checksum is calculated for.
\param checksum_out Result of the calculation.
\returns Void
*/
void picture_checksum(const picture* pic, unsigned char checksum_out[][16])
{
int stride = pic->width; /* ToDo: != width, if there is a luma margin. */
array_checksum(pic->yRecData, pic->height, pic->width, pic->width, checksum_out[0]);
/* The number of chroma pixels is half that of luma. */
array_checksum(pic->uRecData, pic->height >> 1, pic->width >> 1, pic->width >> 1, checksum_out[1]);
array_checksum(pic->vRecData, pic->height >> 1, pic->width >> 1, pic->width >> 1, checksum_out[2]);
}

View file

@ -22,9 +22,11 @@ enum { NAL_TRAIL_N = 0, NAL_TRAIL_R = 1,
NAL_RSV_IRAP_VCL23 = 23,
/* Parameter sets */
NAL_VID_PARAMETER_SET = 32, NAL_SEQ_PARAMETER_SET = 33, NAL_PIC_PARAMETER_SET = 34
NAL_VID_PARAMETER_SET = 32, NAL_SEQ_PARAMETER_SET = 33, NAL_PIC_PARAMETER_SET = 34,
NAL_SUFFIT_SEI_NUT = 40
};
void nal_write(FILE* output, uint8_t* buffer, uint32_t buffer_len, uint8_t nal_ref, uint8_t nal_type, uint8_t temporal_id);
void picture_checksum(const picture* pic, unsigned char* checksum_out);
#endif