mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-13 02:53:42 +00:00
unified picture_t with api
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include "../../tools.h"
|
||||
#include "../../picture.h"
|
||||
#include "../../device.h"
|
||||
|
||||
|
||||
@@ -43,7 +44,6 @@ struct _jpeg_dest_manager_t {
|
||||
struct jpeg_destination_mgr mgr; // Default manager
|
||||
JOCTET *buffer; // Start of buffer
|
||||
struct picture_t *picture;
|
||||
unsigned char *picture_data_cursor;
|
||||
};
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ void cpu_encoder_compress_buffer(struct device_t *dev, unsigned index, unsigned
|
||||
jpeg.err = jpeg_std_error(&jpeg_error);
|
||||
jpeg_create_compress(&jpeg);
|
||||
|
||||
_jpeg_set_picture(&jpeg, &dev->run->pictures[index]);
|
||||
_jpeg_set_picture(&jpeg, dev->run->pictures[index]);
|
||||
|
||||
jpeg.image_width = dev->run->width;
|
||||
jpeg.image_height = dev->run->height;
|
||||
@@ -108,7 +108,7 @@ void cpu_encoder_compress_buffer(struct device_t *dev, unsigned index, unsigned
|
||||
jpeg_finish_compress(&jpeg);
|
||||
jpeg_destroy_compress(&jpeg);
|
||||
|
||||
assert(dev->run->pictures[index].used > 0);
|
||||
assert(dev->run->pictures[index]->used > 0);
|
||||
}
|
||||
|
||||
static void _jpeg_set_picture(j_compress_ptr jpeg, struct picture_t *picture) {
|
||||
@@ -125,7 +125,6 @@ static void _jpeg_set_picture(j_compress_ptr jpeg, struct picture_t *picture) {
|
||||
dest->mgr.empty_output_buffer = _jpeg_empty_output_buffer;
|
||||
dest->mgr.term_destination = _jpeg_term_destination;
|
||||
dest->picture = picture;
|
||||
dest->picture_data_cursor = picture->data;
|
||||
|
||||
picture->used = 0;
|
||||
}
|
||||
@@ -277,13 +276,8 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg) {
|
||||
// Called whenever local jpeg buffer fills up
|
||||
|
||||
struct _jpeg_dest_manager_t *dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
|
||||
size_t new_used = dest->picture->used + JPEG_OUTPUT_BUFFER_SIZE;
|
||||
|
||||
assert(new_used <= dest->picture->allocated);
|
||||
|
||||
memcpy(dest->picture_data_cursor, dest->buffer, JPEG_OUTPUT_BUFFER_SIZE);
|
||||
dest->picture_data_cursor += JPEG_OUTPUT_BUFFER_SIZE;
|
||||
dest->picture->used = new_used;
|
||||
picture_append_data(dest->picture, dest->buffer, JPEG_OUTPUT_BUFFER_SIZE);
|
||||
|
||||
dest->mgr.next_output_byte = dest->buffer;
|
||||
dest->mgr.free_in_buffer = JPEG_OUTPUT_BUFFER_SIZE;
|
||||
@@ -293,18 +287,13 @@ static boolean _jpeg_empty_output_buffer(j_compress_ptr jpeg) {
|
||||
|
||||
static void _jpeg_term_destination(j_compress_ptr jpeg) {
|
||||
// Called by jpeg_finish_compress after all data has been written.
|
||||
// Usually needs to flush buffer
|
||||
// Usually needs to flush buffer.
|
||||
|
||||
struct _jpeg_dest_manager_t *dest = (struct _jpeg_dest_manager_t *)jpeg->dest;
|
||||
size_t final = JPEG_OUTPUT_BUFFER_SIZE - dest->mgr.free_in_buffer;
|
||||
size_t new_used = dest->picture->used + final;
|
||||
|
||||
assert(new_used <= dest->picture->allocated);
|
||||
|
||||
// Write any data remaining in the buffer
|
||||
memcpy(dest->picture_data_cursor, dest->buffer, final);
|
||||
dest->picture_data_cursor += final;
|
||||
dest->picture->used = new_used;
|
||||
// Write any data remaining in the buffer.
|
||||
picture_append_data(dest->picture, dest->buffer, final);
|
||||
}
|
||||
|
||||
#undef JPEG_OUTPUT_BUFFER_SIZE
|
||||
|
||||
@@ -36,13 +36,14 @@
|
||||
#include "../../tools.h"
|
||||
#include "../../logging.h"
|
||||
#include "../../xioctl.h"
|
||||
#include "../../picture.h"
|
||||
#include "../../device.h"
|
||||
|
||||
#include "huffman.h"
|
||||
|
||||
|
||||
void _copy_plus_huffman(const struct hw_buffer_t *src, struct picture_t *dest);
|
||||
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(struct device_t *dev, unsigned quality) {
|
||||
@@ -66,15 +67,30 @@ 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) {
|
||||
assert(0 && "Unsupported input format for HW encoder");
|
||||
}
|
||||
_copy_plus_huffman(&dev->run->hw_buffers[index], dev->run->pictures[index]);
|
||||
}
|
||||
|
||||
# define PICTURE(_next) dev->run->pictures[index]._next
|
||||
# define HW_BUFFER(_next) dev->run->hw_buffers[index]._next
|
||||
void _copy_plus_huffman(const struct hw_buffer_t *src, struct picture_t *dest) {
|
||||
if (!_is_huffman(src->data)) {
|
||||
const unsigned char *src_ptr = src->data;
|
||||
const unsigned char *src_end = src->data + src->used;
|
||||
size_t paste;
|
||||
|
||||
assert(PICTURE(allocated) >= HW_BUFFER(used) + sizeof(HUFFMAN_TABLE));
|
||||
PICTURE(used) = _memcpy_with_huffman(PICTURE(data), HW_BUFFER(data), HW_BUFFER(used));
|
||||
while ((((src_ptr[0] << 8) | src_ptr[1]) != 0xFFC0) && (src_ptr < src_end)) {
|
||||
src_ptr += 1;
|
||||
}
|
||||
if (src_ptr >= src_end) {
|
||||
dest->used = 0; // Error
|
||||
return;
|
||||
}
|
||||
paste = src_ptr - src->data;
|
||||
|
||||
# undef HW_BUFFER
|
||||
# undef PICTURE
|
||||
picture_set_data(dest, src->data, paste);
|
||||
picture_append_data(dest, HUFFMAN_TABLE, sizeof(HUFFMAN_TABLE));
|
||||
picture_append_data(dest, src_ptr, src->used - paste);
|
||||
} else {
|
||||
picture_set_data(dest, src->data, src->used);
|
||||
}
|
||||
}
|
||||
|
||||
static bool _is_huffman(const unsigned char *data) {
|
||||
@@ -91,27 +107,3 @@ static bool _is_huffman(const unsigned char *data) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "../../logging.h"
|
||||
#include "../../tools.h"
|
||||
#include "../../picture.h"
|
||||
#include "../../device.h"
|
||||
|
||||
#include "formatters.h"
|
||||
@@ -174,7 +175,6 @@ int omx_encoder_prepare(struct omx_encoder_t *omx, struct device_t *dev, unsigne
|
||||
}
|
||||
|
||||
int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct device_t *dev, unsigned index) {
|
||||
# define PICTURE(_next) dev->run->pictures[index]._next
|
||||
# define HW_BUFFER(_next) dev->run->hw_buffers[index]._next
|
||||
# define IN(_next) omx->input_buffer->_next
|
||||
# define OUT(_next) omx->output_buffer->_next
|
||||
@@ -188,7 +188,7 @@ int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct device_t *dev,
|
||||
return -1;
|
||||
}
|
||||
|
||||
PICTURE(used) = 0;
|
||||
dev->run->pictures[index]->used = 0;
|
||||
omx->output_available = false;
|
||||
omx->input_required = true;
|
||||
|
||||
@@ -200,9 +200,7 @@ int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct device_t *dev,
|
||||
if (omx->output_available) {
|
||||
omx->output_available = false;
|
||||
|
||||
assert(PICTURE(used) + OUT(nFilledLen) <= PICTURE(allocated));
|
||||
memcpy(PICTURE(data) + PICTURE(used), OUT(pBuffer) + OUT(nOffset), OUT(nFilledLen));
|
||||
PICTURE(used) += OUT(nFilledLen);
|
||||
picture_append_data(dev->run->pictures[index], OUT(pBuffer) + OUT(nOffset), OUT(nFilledLen));
|
||||
|
||||
if (OUT(nFlags) & OMX_BUFFERFLAG_ENDOFFRAME) {
|
||||
OUT(nFlags) = 0;
|
||||
@@ -244,7 +242,6 @@ int omx_encoder_compress_buffer(struct omx_encoder_t *omx, struct device_t *dev,
|
||||
# undef OUT
|
||||
# undef IN
|
||||
# undef HW_BUFFER
|
||||
# undef PICTURE
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -313,7 +310,7 @@ static int _omx_setup_input(struct omx_encoder_t *omx, struct device_t *dev) {
|
||||
# undef ALIGN_HEIGHT
|
||||
portdef.format.image.bFlagErrorConcealment = OMX_FALSE;
|
||||
portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
|
||||
portdef.nBufferSize = dev->run->max_raw_image_size;
|
||||
portdef.nBufferSize = picture_get_generous_size(dev->run->width, dev->run->height);
|
||||
|
||||
# define MAP_FORMAT(_v4l2_format, _omx_format) \
|
||||
case _v4l2_format: { portdef.format.image.eColorFormat = _omx_format; break; }
|
||||
|
||||
Reference in New Issue
Block a user