diff options
author | Damiano Galassi <[email protected]> | 2016-11-07 11:46:40 +0100 |
---|---|---|
committer | Damiano Galassi <[email protected]> | 2016-11-08 10:06:48 +0100 |
commit | dfd46b588bfe5bbb668376ede16ef7337e510213 (patch) | |
tree | 9671917b3708233d9bd9851e14404e851525ef3d /libhb/decavcodec.c | |
parent | 844c4c85da94733967ba6a795fe881f62768d50b (diff) |
Select the appropriate coefficients for yuv<->rgb conversions.
Diffstat (limited to 'libhb/decavcodec.c')
-rw-r--r-- | libhb/decavcodec.c | 135 |
1 files changed, 74 insertions, 61 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 3f66b83d4..e021880b6 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -53,6 +53,10 @@ static void decavcodecClose( hb_work_object_t * ); static int decavcodecaInfo( hb_work_object_t *, hb_work_info_t * ); static int decavcodecaBSInfo( hb_work_object_t *, const hb_buffer_t *, hb_work_info_t * ); +static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate); +static int get_color_transfer(int color_trc); +static int get_color_matrix(int colorspace, hb_geometry_t geometry); + hb_work_object_t hb_decavcodeca = { .id = WORK_DECAVCODEC, @@ -863,11 +867,16 @@ static hb_buffer_t *copy_frame( hb_work_private_t *pv ) { if (pv->sws_context != NULL) sws_freeContext(pv->sws_context); + + hb_geometry_t geometry = {context->width, context->height}; + int color_matrix = get_color_matrix(context->colorspace, geometry); + pv->sws_context = hb_sws_get_context(context->width, context->height, context->pix_fmt, w, h, AV_PIX_FMT_YUV420P, - SWS_LANCZOS|SWS_ACCURATE_RND); + SWS_LANCZOS|SWS_ACCURATE_RND, + hb_ff_get_colorspace(color_matrix)); pv->sws_width = context->width; pv->sws_height = context->height; pv->sws_pix_fmt = context->pix_fmt; @@ -1676,103 +1685,107 @@ static void compute_frame_duration( hb_work_private_t *pv ) } } -static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info ) +static int get_color_prim(int color_primaries, hb_geometry_t geometry, hb_rational_t rate) { - hb_work_private_t *pv = w->private_data; - - int clock_min, clock_max, clock; - hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); - - memset( info, 0, sizeof(*info) ); - - if (pv->context == NULL) - return 0; - - info->bitrate = pv->context->bit_rate; - // HandBrake's video pipeline uses yuv420 color. This means all - // dimensions must be even. So we must adjust the dimensions - // of incoming video if not even. - info->geometry.width = pv->context->width & ~1; - info->geometry.height = pv->context->height & ~1; - - info->geometry.par.num = pv->context->sample_aspect_ratio.num; - info->geometry.par.den = pv->context->sample_aspect_ratio.den; - - compute_frame_duration( pv ); - info->rate.num = clock; - info->rate.den = pv->duration * (clock / 90000.); - - info->profile = pv->context->profile; - info->level = pv->context->level; - info->name = pv->context->codec->name; - - switch( pv->context->color_primaries ) + switch (color_primaries) { case AVCOL_PRI_BT709: - info->color_prim = HB_COLR_PRI_BT709; - break; + return HB_COLR_PRI_BT709; case AVCOL_PRI_BT470BG: - info->color_prim = HB_COLR_PRI_EBUTECH; - break; + return HB_COLR_PRI_EBUTECH; case AVCOL_PRI_BT470M: case AVCOL_PRI_SMPTE170M: case AVCOL_PRI_SMPTE240M: - info->color_prim = HB_COLR_PRI_SMPTEC; - break; + return HB_COLR_PRI_SMPTEC; default: { - if ((info->geometry.width >= 1280 || info->geometry.height >= 720)|| - (info->geometry.width > 720 && info->geometry.height > 576 )) + if ((geometry.width >= 1280 || geometry.height >= 720)|| + (geometry.width > 720 && geometry.height > 576 )) // ITU BT.709 HD content - info->color_prim = HB_COLR_PRI_BT709; - else if( info->rate.den == 1080000 ) + return HB_COLR_PRI_BT709; + else if (rate.den == 1080000) // ITU BT.601 DVD or SD TV content (PAL) - info->color_prim = HB_COLR_PRI_EBUTECH; + return HB_COLR_PRI_EBUTECH; else // ITU BT.601 DVD or SD TV content (NTSC) - info->color_prim = HB_COLR_PRI_SMPTEC; - break; + return HB_COLR_PRI_SMPTEC; } } +} - switch( pv->context->color_trc ) +static int get_color_transfer(int color_trc) +{ + switch (color_trc) { case AVCOL_TRC_SMPTE240M: - info->color_transfer = HB_COLR_TRA_SMPTE240M; - break; + return HB_COLR_TRA_SMPTE240M; default: // ITU BT.601, BT.709, anything else - info->color_transfer = HB_COLR_TRA_BT709; - break; + return HB_COLR_TRA_BT709; } +} - switch( pv->context->colorspace ) +static int get_color_matrix(int colorspace, hb_geometry_t geometry) +{ + switch (colorspace) { case AVCOL_SPC_BT709: - info->color_matrix = HB_COLR_MAT_BT709; - break; + return HB_COLR_MAT_BT709; 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; + return HB_COLR_MAT_SMPTE170M; case AVCOL_SPC_SMPTE240M: - info->color_matrix = HB_COLR_MAT_SMPTE240M; - break; + return HB_COLR_MAT_SMPTE240M; default: { - if ((info->geometry.width >= 1280 || info->geometry.height >= 720)|| - (info->geometry.width > 720 && info->geometry.height > 576 )) + if ((geometry.width >= 1280 || geometry.height >= 720)|| + (geometry.width > 720 && geometry.height > 576 )) // ITU BT.709 HD content - info->color_matrix = HB_COLR_MAT_BT709; + return 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 HB_COLR_MAT_SMPTE170M; } } +} + + +static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info ) +{ + hb_work_private_t *pv = w->private_data; + + int clock_min, clock_max, clock; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + + memset( info, 0, sizeof(*info) ); + + if (pv->context == NULL) + return 0; + + info->bitrate = pv->context->bit_rate; + // HandBrake's video pipeline uses yuv420 color. This means all + // dimensions must be even. So we must adjust the dimensions + // of incoming video if not even. + info->geometry.width = pv->context->width & ~1; + info->geometry.height = pv->context->height & ~1; + + info->geometry.par.num = pv->context->sample_aspect_ratio.num; + info->geometry.par.den = pv->context->sample_aspect_ratio.den; + + compute_frame_duration( pv ); + info->rate.num = clock; + info->rate.den = pv->duration * (clock / 90000.); + + info->profile = pv->context->profile; + info->level = pv->context->level; + info->name = pv->context->codec->name; + + info->color_prim = get_color_prim(pv->context->color_primaries, info->geometry, info->rate); + info->color_transfer = get_color_transfer(pv->context->color_trc); + info->color_matrix = get_color_matrix(pv->context->colorspace, info->geometry); info->video_decode_support = HB_DECODE_SUPPORT_SW; switch (pv->context->codec_id) |