Menu

[a3e420]: / src / VideoDecoder.cpp  Maximize  Restore  History

Download this file

124 lines (108 with data), 4.1 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012 Wang Bin <wbsecg1@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include <QtAV/VideoDecoder.h>
#include <private/AVDecoder_p.h>
#include <QtAV/ImageConverterFF.h>
#include <QtAV/Packet.h>
#include <QtAV/QtAV_Compat.h>
#include <QtCore/QSize>
#if CONFIG_EZX
#define PIX_FMT PIX_FMT_BGR565
#else
#define PIX_FMT PIX_FMT_RGB32 //PIX_FMT_YUV420P
#endif //CONFIG_EZX
namespace QtAV {
class VideoDecoderPrivate : public AVDecoderPrivate
{
public:
VideoDecoderPrivate():width(0),height(0)
{
conv = new ImageConverterFF(); //TODO: set in AVPlayer
conv->setOutFormat(PIX_FMT_RGB32);
}
~VideoDecoderPrivate() {
if (conv) {
delete conv;
conv = 0;
}
}
int width, height;
ImageConverter* conv;
};
VideoDecoder::VideoDecoder()
:AVDecoder(*new VideoDecoderPrivate())
{
}
//TODO: use ipp, cuda decode and yuv functions. is sws_scale necessary?
bool VideoDecoder::decode(const QByteArray &encoded)
{
if (!isAvailable())
return false;
DPTR_D(VideoDecoder);
AVPacket packet;
av_new_packet(&packet, encoded.size());
memcpy(packet.data, encoded.data(), encoded.size());
//TODO: use AVPacket directly instead of Packet?
//AVStream *stream = format_context->streams[stream_idx];
//TODO: some decoders might in addition need other fields like flags&AV_PKT_FLAG_KEY
int ret = avcodec_decode_video2(d.codec_ctx, d.frame, &d.got_frame_ptr, &packet);
//TODO: decoded format is YUV420P, YUV422P?
av_free_packet(&packet);
if (ret < 0) {
qWarning("[VideoDecoder] %s", av_err2str(ret));
return false;
}
if (!d.got_frame_ptr) {
qWarning("no frame could be decompressed: %s", av_err2str(ret));
return false;
}
if (d.width <= 0 || d.height <= 0) {
qDebug("decoded video size not seted. use original size [%d x %d]"
, d.codec_ctx->width, d.codec_ctx->height);
if (!d.codec_ctx->width || !d.codec_ctx->height)
return false;
resizeVideo(d.codec_ctx->width, d.codec_ctx->height);
}
//If not YUV420P or ImageConverter supported format pair, convert to YUV420P first. or directly convert to RGB?(no hwa)
//TODO: move convertion out. decoder only do some decoding
//if not yuv420p or conv supported convertion pair(in/out), convert to yuv420p first using ff, then use other yuv2rgb converter
d.conv->setInFormat(d.codec_ctx->pix_fmt);
d.conv->setInSize(d.codec_ctx->width, d.codec_ctx->height);
d.conv->convert(d.frame->data, d.frame->linesize);
d.decoded = d.conv->outData();
return true;
}
void VideoDecoder::resizeVideo(const QSize &size)
{
resizeVideo(size.width(), size.height());
}
void VideoDecoder::resizeVideo(int width, int height)
{
if (width == 0 || height == 0)
return;
DPTR_D(VideoDecoder);
d.conv->setOutSize(width, height);
d.width = width;
d.height = height;
}
int VideoDecoder::width() const
{
return d_func().width;
}
int VideoDecoder::height() const
{
return d_func().height;
}
} //namespace QtAV