}
}
-int ff_qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
+static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
{
mfxVideoParam param = { { 0 } };
mfxBitstream bs = { { { 0 } } };
AV_PIX_FMT_NV12,
AV_PIX_FMT_NONE };
+ ret = ff_get_format(avctx, pix_fmts);
+ if (ret < 0)
+ return ret;
+
+ avctx->pix_fmt = ret;
+
q->iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
- if (!q->session) {
- if (avctx->hwaccel_context) {
- AVQSVContext *qsv = avctx->hwaccel_context;
+ if (avctx->hwaccel_context) {
+ AVQSVContext *qsv = avctx->hwaccel_context;
- q->session = qsv->session;
- q->iopattern = qsv->iopattern;
- q->ext_buffers = qsv->ext_buffers;
- q->nb_ext_buffers = qsv->nb_ext_buffers;
- }
- if (!q->session) {
+ q->session = qsv->session;
+ q->iopattern = qsv->iopattern;
+ q->ext_buffers = qsv->ext_buffers;
+ q->nb_ext_buffers = qsv->nb_ext_buffers;
+ }
+ if (!q->session) {
+ if (!q->internal_qs.session) {
ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
q->load_plugins);
if (ret < 0)
return ret;
-
- q->session = q->internal_qs.session;
}
+
+ q->session = q->internal_qs.session;
}
if (avpkt->size) {
return ff_qsv_error(ret);
}
- ret = ff_get_format(avctx, pix_fmts);
- if (ret < 0)
- return ret;
-
- avctx->pix_fmt = ret;
avctx->profile = param.mfx.CodecProfile;
avctx->level = param.mfx.CodecLevel;
avctx->coded_width = param.mfx.FrameInfo.Width;
{
QSVFrame *cur;
- MFXVideoDECODE_Close(q->session);
+ if (q->session)
+ MFXVideoDECODE_Close(q->session);
cur = q->work_frames;
while (cur) {
int flush = !avpkt->size || q->reinit_pending;
if (!q->engine_ready) {
- ret = ff_qsv_decode_init(avctx, q, avpkt);
+ ret = qsv_decode_init(avctx, q, avpkt);
if (ret)
return ret;
}
return ret;
}
+/*
+ This function resets decoder and corresponded buffers before seek operation
+*/
+void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
+{
+ QSVFrame *cur;
+ AVPacket pkt;
+ int ret = 0;
+ mfxVideoParam param = { { 0 } };
+
+ if (q->reinit_pending) {
+ close_decoder(q);
+ } else if (q->engine_ready) {
+ ret = MFXVideoDECODE_GetVideoParam(q->session, ¶m);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
+ }
+
+ ret = MFXVideoDECODE_Reset(q->session, ¶m);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
+ }
+
+ /* Free all frames*/
+ cur = q->work_frames;
+ while (cur) {
+ q->work_frames = cur->next;
+ av_frame_free(&cur->frame);
+ av_freep(&cur);
+ cur = q->work_frames;
+ }
+ }
+
+ /* Reset output surfaces */
+ av_fifo_reset(q->async_fifo);
+
+ /* Reset input packets fifo */
+ while (av_fifo_size(q->pkt_fifo)) {
+ av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
+ av_packet_unref(&pkt);
+ }
+
+ /* Reset input bitstream fifo */
+ av_fifo_reset(q->input_fifo);
+}
int ff_qsv_decode_close(QSVContext *q)
{