Skip to content

Commit ff90bd4

Browse files
committed
lavc/qsvdec: use MSDK parser to make MJPEG work
This is a temporary solution same as qsv-3.3.1 branch. Uptream verison will use ffmpeg mjpeg parser Signed-off-by: Zhong Li <zhong.li@intel.com>
1 parent dd3c350 commit ff90bd4

3 files changed

Lines changed: 77 additions & 32 deletions

File tree

libavcodec/qsvdec.c

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,22 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses
9797
return 0;
9898
}
9999

100-
static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
100+
static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
101101
{
102102
const AVPixFmtDescriptor *desc;
103103
mfxSession session = NULL;
104104
int iopattern = 0;
105105
mfxVideoParam param = { 0 };
106106
int ret;
107+
mfxBitstream bs = { { { 0 } } };
108+
109+
if (avpkt->size) {
110+
bs.Data = avpkt->data;
111+
bs.DataLength = avpkt->size;
112+
bs.MaxLength = bs.DataLength;
113+
bs.TimeStamp = avpkt->pts;
114+
}else
115+
return AVERROR_INVALIDDATA;
107116

108117
desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
109118
if (!desc)
@@ -150,35 +159,48 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
150159
if (ret < 0)
151160
return ret;
152161

153-
param.mfx.CodecId = ret;
154-
param.mfx.CodecProfile = ff_qsv_profile_to_mfx(avctx->codec_id, avctx->profile);
155-
param.mfx.CodecLevel = avctx->level == FF_LEVEL_UNKNOWN ? MFX_LEVEL_UNKNOWN : avctx->level;
156-
157-
param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth;
158-
param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
159-
param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8;
160-
param.mfx.FrameInfo.FourCC = q->fourcc;
161-
param.mfx.FrameInfo.Width = avctx->coded_width;
162-
param.mfx.FrameInfo.Height = avctx->coded_height;
163-
param.mfx.FrameInfo.CropW = avctx->width;
164-
param.mfx.FrameInfo.CropH = avctx->height;
165-
param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
166-
167-
switch (avctx->field_order) {
168-
case AV_FIELD_PROGRESSIVE:
169-
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
170-
break;
171-
case AV_FIELD_TT:
172-
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
173-
break;
174-
case AV_FIELD_BB:
175-
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_BFF;
176-
break;
177-
default:
178-
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_UNKNOWN;
179-
break;
162+
if (avctx->codec_id == AV_CODEC_ID_MJPEG){
163+
param.mfx.CodecId = ret;
164+
ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, &param);
165+
if (ret < 0)
166+
return ff_qsv_print_error(avctx, ret,
167+
"Error decoding stream header");
168+
avctx->width = param.mfx.FrameInfo.CropW;
169+
avctx->height = param.mfx.FrameInfo.CropH;
170+
avctx->coded_width = param.mfx.FrameInfo.Width;
171+
avctx->coded_height = param.mfx.FrameInfo.Height;
172+
avctx->level = param.mfx.CodecProfile;
173+
avctx->profile = param.mfx.CodecLevel;
174+
}else {
175+
param.mfx.CodecId = ret;
176+
param.mfx.CodecProfile = ff_qsv_profile_to_mfx(avctx->codec_id, avctx->profile);
177+
param.mfx.CodecLevel = avctx->level == FF_LEVEL_UNKNOWN ? MFX_LEVEL_UNKNOWN : avctx->level;
178+
179+
param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth;
180+
param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
181+
param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8;
182+
param.mfx.FrameInfo.FourCC = q->fourcc;
183+
param.mfx.FrameInfo.Width = avctx->coded_width;
184+
param.mfx.FrameInfo.Height = avctx->coded_height;
185+
param.mfx.FrameInfo.CropW = avctx->width;
186+
param.mfx.FrameInfo.CropH = avctx->height;
187+
param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
188+
189+
switch (avctx->field_order) {
190+
case AV_FIELD_PROGRESSIVE:
191+
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
192+
break;
193+
case AV_FIELD_TT:
194+
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
195+
break;
196+
case AV_FIELD_BB:
197+
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_BFF;
198+
break;
199+
default:
200+
param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_UNKNOWN;
201+
break;
202+
}
180203
}
181-
182204
param.IOPattern = q->iopattern;
183205
param.AsyncDepth = q->async_depth;
184206
param.ExtParam = q->ext_buffers;
@@ -498,9 +520,25 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
498520

499521
avctx->field_order = q->parser->field_order;
500522
/* TODO: flush delayed frames on reinit */
501-
if (q->parser->format != q->orig_pix_fmt ||
523+
524+
if (!q->initialized && avctx->codec_id == AV_CODEC_ID_MJPEG){
525+
enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
526+
AV_PIX_FMT_NV12,
527+
AV_PIX_FMT_NONE };
528+
ret = ff_get_format(avctx, pix_fmts);
529+
if (ret < 0)
530+
goto reinit_fail;
531+
532+
avctx->pix_fmt = ret;
533+
534+
ret = qsv_decode_init(avctx, q, pkt);
535+
if (ret < 0)
536+
goto reinit_fail;
537+
q->initialized = 1;
538+
} else if (avctx->codec_id != AV_CODEC_ID_MJPEG &&
539+
(q->parser->format != q->orig_pix_fmt ||
502540
FFALIGN(q->parser->coded_width, 16) != FFALIGN(avctx->coded_width, 16) ||
503-
FFALIGN(q->parser->coded_height, 16) != FFALIGN(avctx->coded_height, 16)) {
541+
FFALIGN(q->parser->coded_height, 16) != FFALIGN(avctx->coded_height, 16))) {
504542
enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_QSV,
505543
AV_PIX_FMT_NONE,
506544
AV_PIX_FMT_NONE };
@@ -539,7 +577,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
539577
avctx->coded_height = FFALIGN(q->parser->coded_height, 32);
540578
}
541579

542-
ret = qsv_decode_init(avctx, q);
580+
ret = qsv_decode_init(avctx, q, pkt);
543581
if (ret < 0)
544582
goto reinit_fail;
545583
}
@@ -554,4 +592,5 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q,
554592
void ff_qsv_decode_flush(AVCodecContext *avctx, QSVContext *q)
555593
{
556594
q->orig_pix_fmt = AV_PIX_FMT_NONE;
595+
q->initialized = 0;
557596
}

libavcodec/qsvdec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ typedef struct QSVContext {
6060
uint32_t fourcc;
6161
mfxFrameInfo frame_info;
6262

63+
int initialized;
64+
6365
// options set by the caller
6466
int async_depth;
6567
int iopattern;

libavcodec/qsvdec_other.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx)
8989
return AVERROR(ENOMEM);
9090
}
9191
#endif
92+
#if CONFIG_MJPEG_QSV_DECODER
93+
if (avctx->codec_id == AV_CODEC_ID_MJPEG)
94+
s->qsv.initialized = 0;
95+
#endif
9296

9397
s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
9498
if (!s->packet_fifo) {

0 commit comments

Comments
 (0)