| 990 | } |
| 991 | |
| 992 | static int qsv_process_data(AVCodecContext *avctx, QSVContext *q, |
| 993 | AVFrame *frame, int *got_frame, const AVPacket *pkt) |
| 994 | { |
| 995 | int ret; |
| 996 | mfxVideoParam param = { 0 }; |
| 997 | enum AVPixelFormat pix_fmt = AV_PIX_FMT_NV12; |
| 998 | |
| 999 | if (!pkt->size) |
| 1000 | return qsv_decode(avctx, q, frame, got_frame, pkt); |
| 1001 | |
| 1002 | /* TODO: flush delayed frames on reinit */ |
| 1003 | |
| 1004 | // sw_pix_fmt, coded_width/height should be set for ff_get_format(), |
| 1005 | // assume sw_pix_fmt is NV12 and coded_width/height to be 1280x720, |
| 1006 | // the assumption may be not correct but will be updated after header decoded if not true. |
| 1007 | if (q->orig_pix_fmt != AV_PIX_FMT_NONE) |
| 1008 | pix_fmt = q->orig_pix_fmt; |
| 1009 | if (!avctx->coded_width) |
| 1010 | avctx->coded_width = 1280; |
| 1011 | if (!avctx->coded_height) |
| 1012 | avctx->coded_height = 720; |
| 1013 | |
| 1014 | /* decode zero-size pkt to flush the buffered pkt before reinit */ |
| 1015 | if (q->reinit_flag) { |
| 1016 | AVPacket zero_pkt = {0}; |
| 1017 | ret = qsv_decode(avctx, q, frame, got_frame, &zero_pkt); |
| 1018 | if (ret < 0 || *got_frame) |
| 1019 | return ret; |
| 1020 | } |
| 1021 | |
| 1022 | if (q->reinit_flag || !q->session || !q->initialized) { |
| 1023 | mfxFrameAllocRequest request; |
| 1024 | memset(&request, 0, sizeof(request)); |
| 1025 | |
| 1026 | q->reinit_flag = 0; |
| 1027 | ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m); |
| 1028 | if (ret < 0) { |
| 1029 | if (ret == AVERROR(EAGAIN)) |
| 1030 | av_log(avctx, AV_LOG_VERBOSE, "More data is required to decode header\n"); |
| 1031 | else |
| 1032 | av_log(avctx, AV_LOG_ERROR, "Error decoding header\n"); |
| 1033 | goto reinit_fail; |
| 1034 | } |
| 1035 | param.IOPattern = q->iopattern; |
| 1036 | |
| 1037 | q->orig_pix_fmt = avctx->pix_fmt = pix_fmt = ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC); |
| 1038 | |
| 1039 | avctx->coded_width = param.mfx.FrameInfo.Width; |
| 1040 | avctx->coded_height = param.mfx.FrameInfo.Height; |
| 1041 | |
| 1042 | ret = MFXVideoDECODE_QueryIOSurf(q->session, ¶m, &request); |
| 1043 | if (ret < 0) |
| 1044 | return ff_qsv_print_error(avctx, ret, "Error querying IO surface"); |
| 1045 | |
| 1046 | q->suggest_pool_size = request.NumFrameSuggested; |
| 1047 | |
| 1048 | ret = qsv_decode_preinit(avctx, q, pix_fmt, ¶m); |
| 1049 | if (ret < 0) |
no test coverage detected