mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-14 19:43:42 +00:00
huffman
This commit is contained in:
@@ -2,6 +2,11 @@
|
|||||||
# #
|
# #
|
||||||
# uStreamer - Lightweight and fast MJPG-HTTP streamer. #
|
# uStreamer - Lightweight and fast MJPG-HTTP streamer. #
|
||||||
# #
|
# #
|
||||||
|
# This source file based on code of MJPG-Streamer. #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2005-2006 Laurent Pinchart & Michel Xhaard #
|
||||||
|
# Copyright (C) 2006 Gabriel A. Devenyi #
|
||||||
|
# Copyright (C) 2007 Tom Stöveken #
|
||||||
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
|
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
@@ -20,6 +25,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@@ -30,6 +36,13 @@
|
|||||||
#include "../../xioctl.h"
|
#include "../../xioctl.h"
|
||||||
#include "../../device.h"
|
#include "../../device.h"
|
||||||
|
|
||||||
|
#include "huffman.h"
|
||||||
|
#include "encoder.h"
|
||||||
|
|
||||||
|
|
||||||
|
static bool _is_huffman(const unsigned char *data);
|
||||||
|
static size_t _memcpy_with_huffman(unsigned char *dest, const unsigned char *src, size_t size);
|
||||||
|
|
||||||
|
|
||||||
int hw_encoder_prepare_live(struct device_t *dev, unsigned quality) {
|
int hw_encoder_prepare_live(struct device_t *dev, unsigned quality) {
|
||||||
struct v4l2_jpegcompression comp;
|
struct v4l2_jpegcompression comp;
|
||||||
@@ -52,7 +65,53 @@ void hw_encoder_compress_buffer(struct device_t *dev, unsigned index) {
|
|||||||
if (dev->run->format != V4L2_PIX_FMT_MJPEG && dev->run->format != V4L2_PIX_FMT_JPEG) {
|
if (dev->run->format != V4L2_PIX_FMT_MJPEG && dev->run->format != V4L2_PIX_FMT_JPEG) {
|
||||||
assert(0 && "Unsupported input format for HW JPEG encoder");
|
assert(0 && "Unsupported input format for HW JPEG encoder");
|
||||||
}
|
}
|
||||||
assert(dev->run->pictures[index].allocated >= dev->run->hw_buffers[index].length);
|
|
||||||
memcpy(dev->run->pictures[index].data, dev->run->hw_buffers[index].start, dev->run->hw_buffers[index].length);
|
# define PICTURE(_next) dev->run->pictures[index]._next
|
||||||
dev->run->pictures[index].size = dev->run->hw_buffers[index].length;
|
# define HW_BUFFER(_next) dev->run->hw_buffers[index]._next
|
||||||
|
|
||||||
|
assert(PICTURE(allocated) >= HW_BUFFER(length) + sizeof(HUFFMAN_TABLE));
|
||||||
|
PICTURE(size) = _memcpy_with_huffman(PICTURE(data), HW_BUFFER(start), HW_BUFFER(length));
|
||||||
|
|
||||||
|
# undef HW_BUFFER
|
||||||
|
# undef PICTURE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool _is_huffman(const unsigned char *data) {
|
||||||
|
unsigned count = 0;
|
||||||
|
|
||||||
|
while (((data[0] << 8) | data[1]) != 0xFFDA) {
|
||||||
|
if (count++ > 2048) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (((data[0] << 8) | data[1]) == 0xFFC4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
data += 1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _memcpy_with_huffman(unsigned char *dest, const unsigned char *src, size_t size) {
|
||||||
|
if (!_is_huffman(src)) {
|
||||||
|
const unsigned char *src_ptr = src;
|
||||||
|
const unsigned char *src_end = src + size;
|
||||||
|
size_t paste;
|
||||||
|
|
||||||
|
while ((((src_ptr[0] << 8) | src_ptr[1]) != 0xFFC0) && (src_ptr < src_end)) {
|
||||||
|
src_ptr += 1;
|
||||||
|
}
|
||||||
|
if (src_ptr >= src_end) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
paste = src_ptr - src;
|
||||||
|
|
||||||
|
memcpy(dest, src, paste);
|
||||||
|
memcpy(dest + paste, HUFFMAN_TABLE, sizeof(HUFFMAN_TABLE));
|
||||||
|
memcpy(dest + paste + sizeof(HUFFMAN_TABLE), src_ptr, size - paste);
|
||||||
|
return (size + sizeof(HUFFMAN_TABLE));
|
||||||
|
} else {
|
||||||
|
memcpy(dest, src, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/encoders/hw/huffman.h
Normal file
66
src/encoders/hw/huffman.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
# #
|
||||||
|
# uStreamer - Lightweight and fast MJPG-HTTP streamer. #
|
||||||
|
# #
|
||||||
|
# This source file based on code of MJPG-Streamer. #
|
||||||
|
# #
|
||||||
|
# Copyright (C) 2005-2006 Laurent Pinchart & Michel Xhaard #
|
||||||
|
# Copyright (C) 2006 Gabriel A. Devenyi #
|
||||||
|
# Copyright (C) 2007 Tom Stöveken #
|
||||||
|
# Copyright (C) 2018 Maxim Devaev <mdevaev@gmail.com> #
|
||||||
|
# #
|
||||||
|
# This program is free software: you can redistribute it and/or modify #
|
||||||
|
# it under the terms of the GNU General Public License as published by #
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
|
# (at your option) any later version. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, #
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
|
# GNU General Public License for more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License #
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||||
|
# #
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
static const unsigned char HUFFMAN_TABLE[] = {
|
||||||
|
0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||||
|
0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, 0x03,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||||
|
0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05,
|
||||||
|
0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04,
|
||||||
|
0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22,
|
||||||
|
0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15,
|
||||||
|
0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36,
|
||||||
|
0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
|
||||||
|
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
|
||||||
|
0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
|
||||||
|
0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95,
|
||||||
|
0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
|
||||||
|
0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2,
|
||||||
|
0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5,
|
||||||
|
0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||||
|
0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
|
||||||
|
0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
|
||||||
|
0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
|
||||||
|
0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
|
||||||
|
0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33,
|
||||||
|
0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
|
||||||
|
0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36,
|
||||||
|
0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
|
||||||
|
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
|
||||||
|
0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
|
||||||
|
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
|
||||||
|
0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||||
|
0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
|
||||||
|
0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
|
||||||
|
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||||
|
0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user