summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/common.h22
-rw-r--r--libhb/decavcodec.c68
-rw-r--r--libhb/decmpeg2.c76
-rw-r--r--libhb/encx264.c35
-rw-r--r--libhb/muxmp4.c33
-rw-r--r--libhb/scan.c3
-rw-r--r--test/test.c21
7 files changed, 224 insertions, 34 deletions
diff --git a/libhb/common.h b/libhb/common.h
index e8ca7e1fd..57d44450b 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -298,10 +298,26 @@ struct hb_job_s
char *x264_tune;
char *h264_level;
int areBframes;
+
int color_matrix_code;
int color_prim;
int color_transfer;
int color_matrix;
+// see https://developer.apple.com/quicktime/icefloe/dispatch019.html#colr
+#define HB_COLR_PRI_BT709 1
+#define HB_COLR_PRI_UNDEF 2
+#define HB_COLR_PRI_EBUTECH 5 // use for bt470bg
+#define HB_COLR_PRI_SMPTEC 6 // smpte170m; also use for bt470m and smpte240m
+// 0, 3-4, 7-65535: reserved
+#define HB_COLR_TRA_BT709 1 // also use for bt470m, bt470bg and smpte170m
+#define HB_COLR_TRA_UNDEF 2
+#define HB_COLR_TRA_SMPTE240M 7
+// 0, 3-6, 8-65535: reserved
+#define HB_COLR_MAT_BT709 1
+#define HB_COLR_MAT_UNDEF 2
+#define HB_COLR_MAT_SMPTE170M 6 // also use for fcc and bt470bg
+#define HB_COLR_MAT_SMPTE240M 7
+// 0, 3-5, 8-65535: reserved
/* List of audio settings. */
hb_list_t * list_audio;
@@ -685,6 +701,9 @@ struct hb_title_s
int height;
int pixel_aspect_width;
int pixel_aspect_height;
+ int color_prim;
+ int color_transfer;
+ int color_matrix;
int rate;
int rate_base;
int crop[4];
@@ -785,6 +804,9 @@ typedef struct hb_work_info_s
int height;
int pixel_aspect_width;
int pixel_aspect_height;
+ int color_prim;
+ int color_transfer;
+ int color_matrix;
};
struct { // info only valid for audio decoders
int channel_layout;
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index 1bba19990..33b45fa12 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -1336,11 +1336,77 @@ static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
info->level = pv->context->level;
info->name = pv->context->codec->name;
+ switch( pv->context->color_primaries )
+ {
+ case AVCOL_PRI_BT709:
+ info->color_prim = HB_COLR_PRI_BT709;
+ break;
+ case AVCOL_PRI_BT470BG:
+ info->color_prim = HB_COLR_PRI_EBUTECH;
+ break;
+ case AVCOL_PRI_BT470M:
+ case AVCOL_PRI_SMPTE170M:
+ case AVCOL_PRI_SMPTE240M:
+ info->color_prim = HB_COLR_PRI_SMPTEC;
+ break;
+ default:
+ {
+ if( ( info->width >= 1280 || info->height >= 720 ) ||
+ ( info->width > 720 && info->height > 576 ) )
+ // ITU BT.709 HD content
+ info->color_prim = HB_COLR_PRI_BT709;
+ else if( info->rate_base == 1080000 )
+ // ITU BT.601 DVD or SD TV content (PAL)
+ info->color_prim = HB_COLR_PRI_EBUTECH;
+ else
+ // ITU BT.601 DVD or SD TV content (NTSC)
+ info->color_prim = HB_COLR_PRI_SMPTEC;
+ break;
+ }
+ }
+
+ /* AVCOL_TRC_BT709 -> HB_COLR_TRA_BT709
+ * AVCOL_TRC_GAMMA22 (bt470m) -> HB_COLR_TRA_BT709
+ * AVCOL_TRC_GAMMA28 (bt470bg) -> HB_COLR_TRA_BT709
+ * AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_NB:
+ * -> ITU BT.709 -> HB_COLR_TRA_BT709
+ * -> ITU BT.601 -> HB_COLR_TRA_BT709
+ * TODO: AVCOL_TRC_SMPTE240M -> HB_COLR_TRA_SMPTE240M but it's not yet in Libav */
+ info->color_transfer = HB_COLR_TRA_BT709;
+
+ switch( pv->context->colorspace )
+ {
+ case AVCOL_SPC_BT709:
+ info->color_matrix = HB_COLR_MAT_BT709;
+ break;
+ case AVCOL_SPC_FCC:
+ case AVCOL_SPC_BT470BG:
+ case AVCOL_SPC_SMPTE170M:
+ case AVCOL_SPC_RGB: // libswscale rgb2yuv
+ info->color_matrix = HB_COLR_MAT_SMPTE170M;
+ break;
+ case AVCOL_SPC_SMPTE240M:
+ info->color_matrix = HB_COLR_MAT_SMPTE240M;
+ break;
+ default:
+ {
+ if( ( info->width >= 1280 || info->height >= 720 ) ||
+ ( info->width > 720 && info->height > 576 ) )
+ // ITU BT.709 HD content
+ info->color_matrix = HB_COLR_MAT_BT709;
+ else
+ // ITU BT.601 DVD or SD TV content (PAL)
+ // ITU BT.601 DVD or SD TV content (NTSC)
+ info->color_matrix = HB_COLR_MAT_SMPTE170M;
+ break;
+ }
+ }
+
return 1;
}
static int decavcodecvBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
- hb_work_info_t *info )
+ hb_work_info_t *info )
{
return 0;
}
diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c
index 7379964cf..82ba78e31 100644
--- a/libhb/decmpeg2.c
+++ b/libhb/decmpeg2.c
@@ -894,6 +894,82 @@ static int decmpeg2Info( hb_work_object_t *w, hb_work_info_t *info )
info->profile = m->info->sequence->profile_level_id >> 4;
info->level = m->info->sequence->profile_level_id & 0xf;
info->name = "mpeg2";
+
+ if( pv->libmpeg2->info->sequence->flags & SEQ_FLAG_COLOUR_DESCRIPTION )
+ {
+ switch( pv->libmpeg2->info->sequence->colour_primaries )
+ {
+ case 1: // ITU-R Recommendation 709
+ info->color_prim = HB_COLR_PRI_BT709;
+ break;
+ case 5: // ITU-R Recommendation 624-4 System B, G
+ info->color_prim = HB_COLR_PRI_EBUTECH;
+ break;
+ case 4: // ITU-R Recommendation 624-4 System M
+ case 6: // SMPTE 170M
+ case 7: // SMPTE 240M
+ info->color_prim = HB_COLR_PRI_SMPTEC;
+ break;
+ default:
+ info->color_prim = HB_COLR_PRI_UNDEF;
+ break;
+ }
+ switch( pv->libmpeg2->info->sequence->transfer_characteristics )
+ {
+ case 1: // ITU-R Recommendation 709
+ case 4: // ITU-R Recommendation 624-4 System M
+ case 5: // ITU-R Recommendation 624-4 System B, G
+ case 6: // SMPTE 170M
+ info->color_transfer = HB_COLR_TRA_BT709;
+ break;
+ case 7: // SMPTE 240M
+ info->color_transfer = HB_COLR_TRA_SMPTE240M;
+ break;
+ default:
+ info->color_transfer = HB_COLR_TRA_UNDEF;
+ break;
+ }
+ switch( pv->libmpeg2->info->sequence->matrix_coefficients )
+ {
+ case 1: // ITU-R Recommendation 709
+ info->color_matrix = HB_COLR_MAT_BT709;
+ break;
+ case 4: // FCC
+ case 5: // ITU-R Recommendation 624-4 System B, G
+ case 6: // SMPTE 170M
+ info->color_matrix = HB_COLR_MAT_SMPTE170M;
+ break;
+ case 7: // SMPTE 240M
+ info->color_matrix = HB_COLR_MAT_SMPTE240M;
+ break;
+ default:
+ info->color_matrix = HB_COLR_MAT_UNDEF;
+ break;
+ }
+ }
+ else if( ( info->width >= 1280 || info->height >= 720 ) ||
+ ( info->width > 720 && info->height > 576 ) )
+ {
+ // ITU BT.709 HD content
+ info->color_prim = HB_COLR_PRI_BT709;
+ info->color_transfer = HB_COLR_TRA_BT709;
+ info->color_matrix = HB_COLR_MAT_BT709;
+ }
+ else if( info->rate_base == 1080000 )
+ {
+ // ITU BT.601 DVD or SD TV content (PAL)
+ info->color_prim = HB_COLR_PRI_EBUTECH;
+ info->color_transfer = HB_COLR_TRA_BT709;
+ info->color_matrix = HB_COLR_MAT_SMPTE170M;
+ }
+ else
+ {
+ // ITU BT.601 DVD or SD TV content (NTSC)
+ info->color_prim = HB_COLR_PRI_SMPTEC;
+ info->color_transfer = HB_COLR_TRA_BT709;
+ info->color_matrix = HB_COLR_MAT_SMPTE170M;
+ }
+
return 1;
}
return 0;
diff --git a/libhb/encx264.c b/libhb/encx264.c
index f48aa499a..7345ab20e 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -139,27 +139,40 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
/* set up the VUI color model & gamma to match what the COLR atom
* set in muxmp4.c says. See libhb/muxmp4.c for notes. */
- if( job->color_matrix_code == 3 )
+ if( job->color_matrix_code == 4 )
{
// Custom
param.vui.i_colorprim = job->color_prim;
param.vui.i_transfer = job->color_transfer;
param.vui.i_colmatrix = job->color_matrix;
}
- else if( ( job->color_matrix_code == 2 ) ||
- ( job->color_matrix_code == 0 && ( job->title->width >= 1280 || job->title->height >= 720 ) ) )
+ else if( job->color_matrix_code == 3 )
{
// ITU BT.709 HD content
- param.vui.i_colorprim = 1;
- param.vui.i_transfer = 1;
- param.vui.i_colmatrix = 1;
+ param.vui.i_colorprim = HB_COLR_PRI_BT709;
+ param.vui.i_transfer = HB_COLR_TRA_BT709;
+ param.vui.i_colmatrix = HB_COLR_MAT_BT709;
+ }
+ else if( job->color_matrix_code == 2 )
+ {
+ // ITU BT.601 DVD or SD TV content (PAL)
+ param.vui.i_colorprim = HB_COLR_PRI_EBUTECH;
+ param.vui.i_transfer = HB_COLR_TRA_BT709;
+ param.vui.i_colmatrix = HB_COLR_MAT_SMPTE170M;
+ }
+ else if( job->color_matrix_code == 1 )
+ {
+ // ITU BT.601 DVD or SD TV content (NTSC)
+ param.vui.i_colorprim = HB_COLR_PRI_SMPTEC;
+ param.vui.i_transfer = HB_COLR_TRA_BT709;
+ param.vui.i_colmatrix = HB_COLR_MAT_SMPTE170M;
}
else
{
- // ITU BT.601 DVD or SD TV content
- param.vui.i_colorprim = 6;
- param.vui.i_transfer = 1;
- param.vui.i_colmatrix = 6;
+ // detected during scan
+ param.vui.i_colorprim = job->title->color_prim;
+ param.vui.i_transfer = job->title->color_transfer;
+ param.vui.i_colmatrix = job->title->color_matrix;
}
/* place job->advanced_opts in an hb_dict_t for convenience */
@@ -185,7 +198,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
/* Reload colorimetry settings in case custom values were set
* in the advanced_opts string */
- job->color_matrix_code = 3;
+ job->color_matrix_code = 4;
job->color_prim = param.vui.i_colorprim;
job->color_transfer = param.vui.i_transfer;
job->color_matrix = param.vui.i_colmatrix;
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
index 31c235961..cad1d3944 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -214,29 +214,34 @@ static int MP4Init( hb_mux_object_t * m )
hb_error("muxmp4.c: Unsupported video encoder!");
}
- // COLR atom for color and gamma correction.
- // Per the notes at:
- // http://developer.apple.com/quicktime/icefloe/dispatch019.html#colr
- // http://forum.doom9.org/showthread.php?t=133982#post1090068
- // the user can set it from job->color_matrix_code, otherwise by default
- // we say anything that's likely to be HD content is ITU BT.709 and
- // DVD, SD TV & other content is ITU BT.601. We look at the title height
- // rather than the job height here to get uncropped input dimensions.
- if( job->color_matrix_code == 3 )
+ /* COLR atom for color and gamma correction. Per the notes at:
+ * http://developer.apple.com/quicktime/icefloe/dispatch019.html#colr
+ * http://forum.doom9.org/showthread.php?t=133982#post1090068
+ * The user can set it from job->color_matrix_code. */
+ if( job->color_matrix_code == 4 )
{
// Custom
MP4AddColr(m->file, mux_data->track, job->color_prim, job->color_transfer, job->color_matrix);
}
- else if( ( job->color_matrix_code == 2 ) ||
- ( job->color_matrix_code == 0 && ( job->title->width >= 1280 || job->title->height >= 720 ) ) )
+ else if( job->color_matrix_code == 3 )
{
// ITU BT.709 HD content
- MP4AddColr(m->file, mux_data->track, 1, 1, 1);
+ MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_BT709, HB_COLR_TRA_BT709, HB_COLR_MAT_BT709);
+ }
+ else if( job->color_matrix_code == 2 )
+ {
+ // ITU BT.601 DVD or SD TV content (PAL)
+ MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_EBUTECH, HB_COLR_TRA_BT709, HB_COLR_MAT_SMPTE170M);
+ }
+ else if( job->color_matrix_code == 1 )
+ {
+ // ITU BT.601 DVD or SD TV content (NTSC)
+ MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_SMPTEC, HB_COLR_TRA_BT709, HB_COLR_MAT_SMPTE170M);
}
else
{
- // ITU BT.601 DVD or SD TV content
- MP4AddColr(m->file, mux_data->track, 6, 1, 6);
+ // detected during scan
+ MP4AddColr(m->file, mux_data->track, title->color_prim, title->color_transfer, title->color_matrix);
}
if( job->anamorphic.mode )
diff --git a/libhb/scan.c b/libhb/scan.c
index 29c9caaee..1ad8659b7 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -869,6 +869,9 @@ skip_preview:
title->pixel_aspect_width = vid_info.pixel_aspect_width;
title->pixel_aspect_height = vid_info.pixel_aspect_height;
}
+ title->color_prim = vid_info.color_prim;
+ title->color_transfer = vid_info.color_transfer;
+ title->color_matrix = vid_info.color_matrix;
// compute the aspect ratio based on the storage dimensions and the
// pixel aspect ratio (if supplied) or just storage dimensions if no PAR.
diff --git a/test/test.c b/test/test.c
index f8d375b64..504a3507d 100644
--- a/test/test.c
+++ b/test/test.c
@@ -2898,9 +2898,9 @@ static void ShowHelp()
" --modulus Set the number you want the scaled pixel dimensions\n"
" <number> to divide cleanly by. Does not affect strict\n"
" anamorphic mode, which is always mod 2 (default: 16)\n"
- " -M --color-matrix Set the color space signaled by the output\n"
- " <601 or 709> (Bt.601 is mostly for SD content, Bt.709 for HD,\n"
- " default: set by resolution)\n"
+ " -M, --color-matrix Set the color space signaled by the output\n"
+ " Values: 709, pal, ntsc, 601 (same as ntsc)\n"
+ " (default: detected from source)\n"
"\n"
"### Filters---------------------------------------------------------\n\n"
@@ -3725,11 +3725,16 @@ static int ParseOptions( int argc, char ** argv )
acodec_fallback = strdup( optarg );
break;
case 'M':
- if( atoi( optarg ) == 601 )
- color_matrix_code = 1;
- else if( atoi( optarg ) == 709 )
- color_matrix_code = 2;
- break;
+ if( optarg != NULL )
+ {
+ if( !strcmp( optarg, "601" ) ||
+ !strcmp( optarg, "ntsc" ) )
+ color_matrix_code = 1;
+ else if( !strcmp( optarg, "pal" ) )
+ color_matrix_code = 2;
+ else if( !strcmp( optarg, "709" ) )
+ color_matrix_code = 3;
+ } break;
case MIN_DURATION:
min_title_duration = strtol( optarg, NULL, 0 );
break;