Skip to content

Commit

Permalink
decoder: added CS override opt for FF JPEGs
Browse files Browse the repository at this point in the history
FFmpeg encoded JPEGs with COM CS=ITU601 are limited-range BT.601. Allow
override when the caller knows that it is actually limiee-range BT.709
as eg. UltraGrid does.
  • Loading branch information
MartinPulec committed Oct 8, 2024
1 parent 7c35c3a commit 85c0526
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
# change version also in configure.ac
project(gpujpeg VERSION 0.25.4 LANGUAGES C CUDA)
project(gpujpeg VERSION 0.25.5 LANGUAGES C CUDA)

# options
set(BUILD_OPENGL OFF CACHE STRING "Build with OpenGL support, options are: AUTO ON OFF")
Expand Down
7 changes: 5 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
2024-10-08 - 0.25.5
----------
- add gpujpeg_decoder_create_with_params() (+ struct
- added gpujpeg_decoder_create_with_params() (+ struct
gpujpeg_decoder_init_parameters, gpujpeg_decoder_default_init_parameters())
- added gpujpeg_decoder_init_parameters.ff_cs_itu601_is_709 flag to
override colorspace to limited 709 if FFmpeg-specific comment CS=ITU601
is present (as 709 is used by UltraGrid)

2024-10-07 - 0.25.4
----------
Expand All @@ -10,7 +13,7 @@
2024-06-05 - 0.25.3
----------
- added gpujpeg_color_space_by_name
- addeg gpujpeg_print_pixel_format
- added gpujpeg_print_pixel_format

2024-04-09 - 0.25.2
----------
Expand Down
2 changes: 2 additions & 0 deletions libgpujpeg/gpujpeg_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ struct gpujpeg_decoder_init_parameters
cudaStream_t stream; ///< stream CUDA stream to be used, cudaStreamDefault (0x00) is default
int verbose; ///< verbosity level (-1 - quiet, 0 - normal, 1 - verbose)
bool perf_stats; ///< print performance statistics on output
bool ff_cs_itu601_is_709; ///< if FFmpeg specific COM marker "CS=ITU601" present, interpret the data as
///< limited-range BT.709 not BT.601
};

/**
Expand Down
3 changes: 2 additions & 1 deletion src/gpujpeg_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ gpujpeg_decoder_create(cudaStream_t stream)
struct gpujpeg_decoder_init_parameters
gpujpeg_decoder_default_init_parameters()
{
return (struct gpujpeg_decoder_init_parameters){cudaStreamDefault, 0, false};
return (struct gpujpeg_decoder_init_parameters){cudaStreamDefault, 0, false, false};
}
/**
* Create JPEG decoder
Expand All @@ -174,6 +174,7 @@ gpujpeg_decoder_create_with_params(const struct gpujpeg_decoder_init_parameters
}
decoder->coder.param.verbose = params->verbose;
decoder->coder.param.perf_stats = params->perf_stats;
decoder->ff_cs_itu601_is_709 = params->ff_cs_itu601_is_709;
return decoder;
}

Expand Down
4 changes: 4 additions & 0 deletions src/gpujpeg_decoder_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#ifndef GPUJPEG_DECODER_INTERNAL_H
#define GPUJPEG_DECODER_INTERNAL_H

#include <stdbool.h>

#include "../libgpujpeg/gpujpeg_common.h"
#include "gpujpeg_common_internal.h"
#include "gpujpeg_table.h"
Expand Down Expand Up @@ -68,6 +70,8 @@ struct gpujpeg_decoder

enum gpujpeg_pixel_format req_pixel_format;
enum gpujpeg_color_space req_color_space;
bool ff_cs_itu601_is_709; ///< if FFmpeg specific COM marker "CS=ITU601" present, interpret the data as
///< limited-range BT.709 not BT.601
};

#endif // GPUJPEG_DECODER_INTERNAL_H
Expand Down
22 changes: 14 additions & 8 deletions src/gpujpeg_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <ctype.h>
#include <inttypes.h>
#include <string.h>
#include <stdbool.h>

#include "../libgpujpeg/gpujpeg_decoder.h"
#include "gpujpeg_decoder_internal.h"
Expand Down Expand Up @@ -578,7 +579,8 @@ gpujpeg_reader_read_app14(uint8_t** image, const uint8_t* image_end, enum gpujpe
}

static int
gpujpeg_reader_read_com(uint8_t** image, const uint8_t* image_end, enum gpujpeg_color_space *color_space)
gpujpeg_reader_read_com(uint8_t** image, const uint8_t* image_end, bool ff_cs_itu601_is_709,
enum gpujpeg_color_space* color_space)
{
if(image_end - *image < 2) {
fprintf(stderr, "[GPUJPEG] [Error] Could not read com length\n");
Expand All @@ -596,7 +598,7 @@ gpujpeg_reader_read_com(uint8_t** image, const uint8_t* image_end, enum gpujpeg_
const size_t com_length = length - 2; // check both with '\0' and without:
if ( (com_length == sizeof cs_itu601 || com_length == sizeof cs_itu601 - 1) &&
strncmp((char*)*image, cs_itu601, com_length) == 0 ) {
*color_space = GPUJPEG_YCBCR_BT601;
*color_space = ff_cs_itu601_is_709 ? GPUJPEG_YCBCR_BT709 : GPUJPEG_YCBCR_BT601;
}

*image += length - 2;
Expand Down Expand Up @@ -1232,7 +1234,9 @@ gpujpeg_reader_read_sos(struct gpujpeg_decoder* decoder, struct gpujpeg_reader*
* @retval @ref Errors
*/
static int
gpujpeg_reader_read_common_markers(uint8_t **image, const uint8_t* image_end, int marker, int log_level, enum gpujpeg_color_space *color_space, int *restart_interval, _Bool *in_spiff)
gpujpeg_reader_read_common_markers(uint8_t** image, const uint8_t* image_end, int marker, int log_level,
bool ff_cs_itu601_is_709, enum gpujpeg_color_space* color_space,
int* restart_interval, bool* in_spiff)
{
int rc = 0;
switch (marker)
Expand Down Expand Up @@ -1310,7 +1314,7 @@ gpujpeg_reader_read_common_markers(uint8_t **image, const uint8_t* image_end, in
return -1;

case GPUJPEG_MARKER_COM:
if ( gpujpeg_reader_read_com(image, image_end, color_space) != 0 ) {
if ( gpujpeg_reader_read_com(image, image_end, ff_cs_itu601_is_709, color_space) != 0 ) {
return -1;
}
break;
Expand Down Expand Up @@ -1420,8 +1424,9 @@ gpujpeg_reader_read_image(struct gpujpeg_decoder* decoder, uint8_t* image, size_
}

// Read more info according to the marker
int rc = gpujpeg_reader_read_common_markers(&image, image_end, marker, decoder->coder.param.verbose, &header_color_space, &reader.param.restart_interval, &in_spiff);
if (rc < 0) {
int rc = gpujpeg_reader_read_common_markers(&image, image_end, marker, decoder->coder.param.verbose, decoder->ff_cs_itu601_is_709,
&header_color_space, &reader.param.restart_interval, &in_spiff);
if ( rc < 0 ) {
return rc;
}
if (rc == 0) { // already processed
Expand Down Expand Up @@ -1547,8 +1552,9 @@ gpujpeg_reader_get_image_info(uint8_t *image, size_t image_size, struct gpujpeg_
}

// Read more info according to the marker
int rc = gpujpeg_reader_read_common_markers(&image, image_end, marker, param->verbose, &header_color_space, &param->restart_interval, &in_spiff);
if (rc < 0) {
int rc = gpujpeg_reader_read_common_markers(&image, image_end, marker, param->verbose, false,
&header_color_space, &param->restart_interval, &in_spiff);
if ( rc < 0 ) {
return rc;
}
if (rc == 0) { // already processed
Expand Down

0 comments on commit 85c0526

Please sign in to comment.