Skip to content

Commit

Permalink
add VideoFrame.colorRange. set from ffmpeg decoder
Browse files Browse the repository at this point in the history
not set if a frame is converted. so no range transform in
ColorTransform.
TODO: ImageConverter set correct range, and set range in
VideoFrame.convert()
  • Loading branch information
wang-bin committed Feb 17, 2016
1 parent d15c94f commit 2105182
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 9 deletions.
12 changes: 11 additions & 1 deletion src/AVCompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,21 @@ enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame)
{
if (!frame)
return AVCOL_SPC_NB;
#if LIBAV_MODULE_CHECK(LIBAVUTIL, 54, 3, 0) //has AVFrame.colorspace
#if LIBAV_MODULE_CHECK(LIBAVUTIL, 53, 16, 0) //8c02adc
return frame->colorspace;
#endif
return AVCOL_SPC_NB;
}

enum AVColorSpace av_frame_get_color_range(const AVFrame *frame)
{
if (!frame)
return AVCOL_RANGE_UNSPECIFIED;
#if LIBAV_MODULE_CHECK(LIBAVUTIL, 53, 16, 0) //8c02adc
return frame->color_range;
#endif
return AVCOL_RANGE_UNSPECIFIED;
}
#endif //!FFMPEG_MODULE_CHECK(LIBAVUTIL, 52, 28, 101)
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 38, 100)
int av_pix_fmt_count_planes(AVPixelFormat pix_fmt)
Expand Down
2 changes: 2 additions & 0 deletions src/QtAV/VideoFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class Q_AV_EXPORT VideoFrame : public Frame
// TODO: pixel aspect ratio
ColorSpace colorSpace() const;
void setColorSpace(ColorSpace value);
ColorRange colorRange() const;
void setColorRange(ColorRange value);

// no padded bytes
int effectiveBytesPerLine(int plane) const;
Expand Down
3 changes: 2 additions & 1 deletion src/QtAV/private/AVCompat.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ const AVPixFmtDescriptor *av_pix_fmt_desc_get(AVPixelFormat pix_fmt);
const AVPixFmtDescriptor *av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev);
AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc);
#endif // !AV_MODULE_CHECK(LIBAVUTIL, 52, 3, 0, 13, 100)
#if !FFMPEG_MODULE_CHECK(LIBAVUTIL, 52, 48, 101) // since ffmpeg2.1
#if !FFMPEG_MODULE_CHECK(LIBAVUTIL, 52, 48, 101) // since ffmpeg2.1, libavutil53.16.0 (FF_API_AVFRAME_COLORSPACE), git 8c02adc
enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame);
enum AVColorRange av_frame_get_color_range(const AVFrame *frame);
#endif
/*
* lavu 52.9.0 git 2c328a907978b61949fd20f7c991803174337855
Expand Down
16 changes: 16 additions & 0 deletions src/VideoFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class VideoFramePrivate : public FramePrivate
, width(0)
, height(0)
, color_space(ColorSpace_Unknown)
, color_range(ColorRange_Unknown)
, displayAspectRatio(0)
, format(VideoFormat::Format_Invalid)
{}
Expand All @@ -126,6 +127,7 @@ class VideoFramePrivate : public FramePrivate
, width(w)
, height(h)
, color_space(ColorSpace_Unknown)
, color_range(ColorRange_Unknown)
, displayAspectRatio(0)
, format(fmt)
{
Expand All @@ -139,6 +141,7 @@ class VideoFramePrivate : public FramePrivate
~VideoFramePrivate() {}
int width, height;
ColorSpace color_space;
ColorRange color_range;
float displayAspectRatio;
VideoFormat format;
QScopedPointer<QImage> qt_image;
Expand Down Expand Up @@ -242,6 +245,7 @@ VideoFrame VideoFrame::clone() const
f.setTimestamp(d->timestamp);
f.setDisplayAspectRatio(d->displayAspectRatio);
f.setColorSpace(d->color_space);
f.setColorRange(d->color_range);
return f;
}

Expand Down Expand Up @@ -333,6 +337,16 @@ void VideoFrame::setColorSpace(ColorSpace value)
d_func()->color_space = value;
}

ColorRange VideoFrame::colorRange() const
{
return d_func()->color_range;
}

void VideoFrame::setColorRange(ColorRange value)
{
d_func()->color_range = value;
}

int VideoFrame::effectiveBytesPerLine(int plane) const
{
Q_D(const VideoFrame);
Expand Down Expand Up @@ -400,6 +414,7 @@ VideoFrame VideoFrame::to(const VideoFormat &fmt, const QSize& dstSize, const QR
} else {
f.setColorSpace(ColorSpace_Unknown);
}
// TODO: color range
f.setTimestamp(timestamp());
f.setDisplayAspectRatio(displayAspectRatio());
f.d_ptr->metadata = d->metadata; // need metadata?
Expand Down Expand Up @@ -531,6 +546,7 @@ VideoFrame VideoFrameConverter::convert(const VideoFrame &frame, int fffmt) cons
} else {
f.setColorSpace(ColorSpace_Unknown);
}
// TODO: color range
return f;
}

Expand Down
8 changes: 2 additions & 6 deletions src/codec/video/VideoDecoderFFmpeg.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2013-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
* This file is part of QtAV (from 2013)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -235,10 +235,6 @@ VideoDecoderId VideoDecoderFFmpeg::id() const
VideoFrame VideoDecoderFFmpeg::frame()
{
DPTR_D(VideoDecoderFFmpeg);
/*qDebug("color space: %d, range: %d, prim: %d, t: %d"
, d.codec_ctx->colorspace, d.codec_ctx->color_range
, d.codec_ctx->color_primaries, d.codec_ctx->color_trc);
*/
if (d.frame->width <= 0 || d.frame->height <= 0 || !d.codec_ctx)
return VideoFrame();
// it's safe if width, height, pixfmt will not change, only data change
Expand Down
22 changes: 21 additions & 1 deletion src/codec/video/VideoDecoderFFmpegBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,33 @@
namespace QtAV {

extern ColorSpace colorSpaceFromFFmpeg(AVColorSpace cs);
extern ColorRange colorRangeFromFFmpeg(AVColorRange cr);

void VideoDecoderFFmpegBasePrivate::updateColorDetails(VideoFrame *f)
{
ColorSpace cs = colorSpaceFromFFmpeg(av_frame_get_colorspace(frame));
if (cs != ColorSpace_Unknown)
if (cs == ColorSpace_Unknown)
cs = colorSpaceFromFFmpeg(codec_ctx->colorspace);
f->setColorSpace(cs);
ColorRange cr = colorRangeFromFFmpeg(av_frame_get_color_range(frame));
if (cr == ColorRange_Unknown) {
// check yuvj format. TODO: deprecated, check only for old ffmpeg?
const AVPixelFormat pixfmt = (AVPixelFormat)frame->format;
switch (pixfmt) {
case QTAV_PIX_FMT_C(YUVJ411P):
case QTAV_PIX_FMT_C(YUVJ420P):
case QTAV_PIX_FMT_C(YUVJ422P):
case QTAV_PIX_FMT_C(YUVJ440P):
case QTAV_PIX_FMT_C(YUVJ444P):
cr = ColorRange_Full;
break;
default:
break;
}
}
if (cr == ColorRange_Unknown)
cr = colorRangeFromFFmpeg(codec_ctx->color_range);
f->setColorRange(cr);
}

qreal VideoDecoderFFmpegBasePrivate::getDAR(AVFrame *f)
Expand Down

0 comments on commit 2105182

Please sign in to comment.