Lavc: set range/colorspec to codec

This commit is contained in:
Martin Pulec
2020-09-25 15:27:04 +02:00
parent c5980d9557
commit 23ca8f37bd
3 changed files with 63 additions and 29 deletions

View File

@@ -2369,36 +2369,36 @@ const struct uv_to_av_conversion *get_uv_to_av_conversions() {
* conversions below the others. * conversions below the others.
*/ */
static const struct uv_to_av_conversion uv_to_av_conversions[] = { static const struct uv_to_av_conversion uv_to_av_conversions[] = {
{ v210, AV_PIX_FMT_YUV420P10LE, v210_to_yuv420p10le }, { v210, AV_PIX_FMT_YUV420P10LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, v210_to_yuv420p10le },
{ v210, AV_PIX_FMT_YUV422P10LE, v210_to_yuv422p10le }, { v210, AV_PIX_FMT_YUV422P10LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, v210_to_yuv422p10le },
{ v210, AV_PIX_FMT_YUV444P10LE, v210_to_yuv444p10le }, { v210, AV_PIX_FMT_YUV444P10LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, v210_to_yuv444p10le },
{ v210, AV_PIX_FMT_YUV444P16LE, v210_to_yuv444p16le }, { v210, AV_PIX_FMT_YUV444P16LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, v210_to_yuv444p16le },
{ R10k, AV_PIX_FMT_YUV444P10LE, r10k_to_yuv444p10le }, { R10k, AV_PIX_FMT_YUV444P10LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r10k_to_yuv444p10le },
{ R10k, AV_PIX_FMT_YUV444P12LE, r10k_to_yuv444p12le }, { R10k, AV_PIX_FMT_YUV444P12LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r10k_to_yuv444p12le },
{ R10k, AV_PIX_FMT_YUV444P16LE, r10k_to_yuv444p16le }, { R10k, AV_PIX_FMT_YUV444P16LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r10k_to_yuv444p16le },
{ R12L, AV_PIX_FMT_YUV444P16LE, r12l_to_yuv444p10le }, { R12L, AV_PIX_FMT_YUV444P16LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r12l_to_yuv444p10le },
{ R12L, AV_PIX_FMT_YUV444P16LE, r12l_to_yuv444p12le }, { R12L, AV_PIX_FMT_YUV444P16LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r12l_to_yuv444p12le },
{ R12L, AV_PIX_FMT_YUV444P16LE, r12l_to_yuv444p16le }, { R12L, AV_PIX_FMT_YUV444P16LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r12l_to_yuv444p16le },
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 15, 100) // FFMPEG commit c2869b4640f #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 15, 100) // FFMPEG commit c2869b4640f
{ v210, AV_PIX_FMT_P010LE, v210_to_p010le }, { v210, AV_PIX_FMT_P010LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, v210_to_p010le },
#endif #endif
{ UYVY, AV_PIX_FMT_YUV422P, uyvy_to_yuv422p }, { UYVY, AV_PIX_FMT_YUV422P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv422p },
{ UYVY, AV_PIX_FMT_YUVJ422P, uyvy_to_yuv422p }, { UYVY, AV_PIX_FMT_YUVJ422P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv422p },
{ UYVY, AV_PIX_FMT_YUV420P, uyvy_to_yuv420p }, { UYVY, AV_PIX_FMT_YUV420P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv420p },
{ UYVY, AV_PIX_FMT_YUVJ420P, uyvy_to_yuv420p }, { UYVY, AV_PIX_FMT_YUVJ420P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv420p },
{ UYVY, AV_PIX_FMT_NV12, uyvy_to_nv12 }, { UYVY, AV_PIX_FMT_NV12, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_nv12 },
{ UYVY, AV_PIX_FMT_YUV444P, uyvy_to_yuv444p }, { UYVY, AV_PIX_FMT_YUV444P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv444p },
{ UYVY, AV_PIX_FMT_YUVJ444P, uyvy_to_yuv444p }, { UYVY, AV_PIX_FMT_YUVJ444P, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, uyvy_to_yuv444p },
{ RGB, AV_PIX_FMT_BGR0, rgb_to_bgr0 }, { RGB, AV_PIX_FMT_BGR0, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, rgb_to_bgr0 },
{ RGB, AV_PIX_FMT_GBRP, rgb_to_gbrp }, { RGB, AV_PIX_FMT_GBRP, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, rgb_to_gbrp },
{ RGBA, AV_PIX_FMT_GBRP, rgba_to_gbrp }, { RGBA, AV_PIX_FMT_GBRP, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, rgba_to_gbrp },
{ R10k, AV_PIX_FMT_BGR0, r10k_to_bgr0 }, { R10k, AV_PIX_FMT_BGR0, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, r10k_to_bgr0 },
{ R10k, AV_PIX_FMT_GBRP10LE, r10k_to_gbrp10le }, { R10k, AV_PIX_FMT_GBRP10LE, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, r10k_to_gbrp10le },
{ R10k, AV_PIX_FMT_YUV422P10LE, r10k_to_yuv422p10le }, { R10k, AV_PIX_FMT_YUV422P10LE, AVCOL_SPC_BT709, AVCOL_RANGE_MPEG, r10k_to_yuv422p10le },
#ifdef HAVE_12_AND_14_PLANAR_COLORSPACES #ifdef HAVE_12_AND_14_PLANAR_COLORSPACES
{ R12L, AV_PIX_FMT_GBRP12LE, r12l_to_gbrp12le }, { R12L, AV_PIX_FMT_GBRP12LE, AVCOL_SPC_RGB, AVCOL_RANGE_JPEG, r12l_to_gbrp12le },
#endif #endif
{ 0, 0, 0 } { 0, 0, 0, 0, 0 }
}; };
return uv_to_av_conversions; return uv_to_av_conversions;
} }
@@ -2415,6 +2415,19 @@ pixfmt_callback_t get_uv_to_av_conversion(codec_t uv_codec, int av_codec) {
return NULL; return NULL;
} }
void get_av_pixfmt_details(codec_t uv_codec, int av_codec, enum AVColorSpace *colorspace, enum AVColorRange *color_range)
{
for (const struct uv_to_av_conversion *conversions = get_uv_to_av_conversions();
conversions->func != 0; conversions++) {
if (conversions->dst == av_codec &&
conversions->src == uv_codec) {
*colorspace = conversions->colorspace;
*color_range = conversions->color_range;
return;
}
}
}
/** /**
* @brief returns list of available conversion. Terminated by uv_to_av_conversion::uv_codec == VIDEO_CODEC_NONE * @brief returns list of available conversion. Terminated by uv_to_av_conversion::uv_codec == VIDEO_CODEC_NONE
*/ */

View File

@@ -189,10 +189,16 @@ typedef uv_to_av_convert *pixfmt_callback_t;
struct uv_to_av_conversion { struct uv_to_av_conversion {
codec_t src; codec_t src;
enum AVPixelFormat dst; enum AVPixelFormat dst;
pixfmt_callback_t func; enum AVColorSpace colorspace; ///< destination colorspace
enum AVColorRange color_range; ///< destination color range
pixfmt_callback_t func; ///< conversion function
}; };
const struct uv_to_av_conversion *get_uv_to_av_conversions(void); const struct uv_to_av_conversion *get_uv_to_av_conversions(void);
pixfmt_callback_t get_uv_to_av_conversion(codec_t uv_codec, int av_codec); pixfmt_callback_t get_uv_to_av_conversion(codec_t uv_codec, int av_codec);
/**
* Returns AV format details for given pair UV,AV codec (must be unique then)
*/
void get_av_pixfmt_details(codec_t uv_codec, int av_codec, enum AVColorSpace *colorspace, enum AVColorRange *color_range);
typedef void av_to_uv_convert(char * __restrict dst_buffer, AVFrame * __restrict in_frame, int width, int height, int pitch, int * __restrict rgb_shift); typedef void av_to_uv_convert(char * __restrict dst_buffer, AVFrame * __restrict in_frame, int width, int height, int pitch, int * __restrict rgb_shift);
typedef av_to_uv_convert *av_to_uv_convert_p; typedef av_to_uv_convert *av_to_uv_convert_p;

View File

@@ -937,7 +937,7 @@ static bool try_open_codec(struct state_video_compress_libav *s,
AVPixelFormat &pix_fmt, AVPixelFormat &pix_fmt,
struct video_desc desc, struct video_desc desc,
codec_t ug_codec, codec_t ug_codec,
AVCodec *codec) const AVCodec *codec)
{ {
// avcodec_alloc_context3 allocates context and sets default value // avcodec_alloc_context3 allocates context and sets default value
s->codec_ctx = avcodec_alloc_context3(codec); s->codec_ctx = avcodec_alloc_context3(codec);
@@ -967,6 +967,13 @@ static bool try_open_codec(struct state_video_compress_libav *s,
pix_fmt = AV_PIX_FMT_NV12; pix_fmt = AV_PIX_FMT_NV12;
} }
#endif #endif
if (const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get(pix_fmt)) { // defaults
s->codec_ctx->colorspace = (desc->flags & AV_PIX_FMT_FLAG_RGB) != 0U ? AVCOL_SPC_RGB : AVCOL_SPC_BT709;
s->codec_ctx->color_range = (desc->flags & AV_PIX_FMT_FLAG_RGB) != 0U ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
}
get_av_pixfmt_details(ug_codec, pix_fmt, &s->codec_ctx->colorspace, &s->codec_ctx->color_range);
/* open it */ /* open it */
pthread_mutex_lock(s->lavcd_global_lock); pthread_mutex_lock(s->lavcd_global_lock);
if (avcodec_open2(s->codec_ctx, codec, NULL) < 0) { if (avcodec_open2(s->codec_ctx, codec, NULL) < 0) {
@@ -976,8 +983,16 @@ static bool try_open_codec(struct state_video_compress_libav *s,
pthread_mutex_unlock(s->lavcd_global_lock); pthread_mutex_unlock(s->lavcd_global_lock);
return false; return false;
} }
pthread_mutex_unlock(s->lavcd_global_lock); pthread_mutex_unlock(s->lavcd_global_lock);
// setting again for JPEG encoder because avcodec_open2 overrides color_range from MPEG to JPEG for YUVJ* pix_fmts
if (pix_fmt == AV_PIX_FMT_YUVJ420P || pix_fmt == AV_PIX_FMT_YUVJ411P || pix_fmt == AV_PIX_FMT_YUVJ422P || pix_fmt == AV_PIX_FMT_YUVJ440P || pix_fmt == AV_PIX_FMT_YUVJ444P) {
if (const AVPixFmtDescriptor * desc = av_pix_fmt_desc_get(pix_fmt)) { // defaults
s->codec_ctx->colorspace = (desc->flags & AV_PIX_FMT_FLAG_RGB) != 0U ? AVCOL_SPC_RGB : AVCOL_SPC_BT709;
s->codec_ctx->color_range = (desc->flags & AV_PIX_FMT_FLAG_RGB) != 0U ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
}
get_av_pixfmt_details(ug_codec, pix_fmt, &s->codec_ctx->colorspace, &s->codec_ctx->color_range);
}
return true; return true;
} }