static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; QPContext *s = ctx->priv; AVBufferRef *out_qp_table_buf; AVFrame *out; const int8_t *in_qp_table; int type, stride, ret; if (!s->qp_expr_str || ctx->is_disabled) return ff_filter_frame(outlink, in); out_qp_table_buf = av_buffer_alloc(s->h * s->qstride); if (!out_qp_table_buf) { ret = AVERROR(ENOMEM); goto fail; } out = av_frame_clone(in); if (!out) { av_buffer_unref(&out_qp_table_buf); ret = AVERROR(ENOMEM); goto fail; } in_qp_table = av_frame_get_qp_table(in, &stride, &type); av_frame_set_qp_table(out, out_qp_table_buf, s->qstride, type); if (s->evaluate_per_mb) { int y, x; for (y = 0; y < s->h; y++) for (x = 0; x < s->qstride; x++) { int qp = in_qp_table ? in_qp_table[x + stride * y] : NAN; double var_values[] = { !!in_qp_table, qp, x, y, s->qstride, s->h, 0}; static const char *var_names[] = { "known", "qp", "x", "y", "w", "h", NULL }; double temp_val; int ret; ret = av_expr_parse_and_eval(&temp_val, s->qp_expr_str, var_names, var_values, NULL, NULL, NULL, NULL, 0, 0, ctx); if (ret < 0) return ret; out_qp_table_buf->data[x + s->qstride * y] = lrintf(temp_val); } } else if (in_qp_table) { int y, x; for (y = 0; y < s->h; y++) for (x = 0; x < s->qstride; x++) out_qp_table_buf->data[x + s->qstride * y] = s->lut[129 + ((int8_t)in_qp_table[x + stride * y])]; } else { int y, x, qp = s->lut[0]; for (y = 0; y < s->h; y++) for (x = 0; x < s->qstride; x++) out_qp_table_buf->data[x + s->qstride * y] = qp; } ret = ff_filter_frame(outlink, out); fail: av_frame_free(&in); return ret; }
bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) { if (!m_pFrame) return false; pDvdVideoPicture->iWidth = m_pFrame->width; pDvdVideoPicture->iHeight = m_pFrame->height; /* crop of 10 pixels if demuxer asked it */ if(m_pCodecContext->coded_width && m_pCodecContext->coded_width < (int)pDvdVideoPicture->iWidth && m_pCodecContext->coded_width > (int)pDvdVideoPicture->iWidth - 10) pDvdVideoPicture->iWidth = m_pCodecContext->coded_width; if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pDvdVideoPicture->iHeight && m_pCodecContext->coded_height > (int)pDvdVideoPicture->iHeight - 10) pDvdVideoPicture->iHeight = m_pCodecContext->coded_height; double aspect_ratio; /* use variable in the frame */ AVRational pixel_aspect = m_pFrame->sample_aspect_ratio; if (pixel_aspect.num == 0) aspect_ratio = 0; else aspect_ratio = av_q2d(pixel_aspect) * pDvdVideoPicture->iWidth / pDvdVideoPicture->iHeight; if (aspect_ratio <= 0.0) aspect_ratio = (float)pDvdVideoPicture->iWidth / (float)pDvdVideoPicture->iHeight; /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it. pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight; pDvdVideoPicture->iDisplayWidth = ((int)RINT(pDvdVideoPicture->iHeight * aspect_ratio)) & -3; if (pDvdVideoPicture->iDisplayWidth > pDvdVideoPicture->iWidth) { pDvdVideoPicture->iDisplayWidth = pDvdVideoPicture->iWidth; pDvdVideoPicture->iDisplayHeight = ((int)RINT(pDvdVideoPicture->iWidth / aspect_ratio)) & -3; } pDvdVideoPicture->pts = DVD_NOPTS_VALUE; AVDictionaryEntry * entry = av_dict_get(av_frame_get_metadata(m_pFrame), "stereo_mode", NULL, 0); if(entry && entry->value) { strncpy(pDvdVideoPicture->stereo_mode, (const char*)entry->value, sizeof(pDvdVideoPicture->stereo_mode)); pDvdVideoPicture->stereo_mode[sizeof(pDvdVideoPicture->stereo_mode)-1] = '\0'; } pDvdVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict; pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0; pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0; if (m_codecControlFlags & DVD_CODEC_CTRL_DROP) pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location; pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries; pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc; pDvdVideoPicture->color_matrix = m_pCodecContext->colorspace; if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG || m_pCodecContext->pix_fmt == AV_PIX_FMT_YUVJ420P) pDvdVideoPicture->color_range = 1; else pDvdVideoPicture->color_range = 0; int qscale_type; pDvdVideoPicture->qp_table = av_frame_get_qp_table(m_pFrame, &pDvdVideoPicture->qstride, &qscale_type); switch (qscale_type) { case FF_QSCALE_TYPE_MPEG1: pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1; break; case FF_QSCALE_TYPE_MPEG2: pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG2; break; case FF_QSCALE_TYPE_H264: pDvdVideoPicture->qscale_type = DVP_QSCALE_H264; break; default: pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN; } if (pDvdVideoPicture->iRepeatPicture) pDvdVideoPicture->dts = DVD_NOPTS_VALUE; else pDvdVideoPicture->dts = m_dts; m_dts = DVD_NOPTS_VALUE; int64_t bpts = av_frame_get_best_effort_timestamp(m_pFrame); if (bpts != AV_NOPTS_VALUE) { pDvdVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; if (pDvdVideoPicture->pts == m_decoderPts) { pDvdVideoPicture->iRepeatPicture = -0.5; pDvdVideoPicture->pts = DVD_NOPTS_VALUE; pDvdVideoPicture->dts = DVD_NOPTS_VALUE; } } else pDvdVideoPicture->pts = DVD_NOPTS_VALUE; if (pDvdVideoPicture->pts != DVD_NOPTS_VALUE) m_decoderPts = pDvdVideoPicture->pts; if (m_requestSkipDeint) { pDvdVideoPicture->iFlags |= DVD_CODEC_CTRL_SKIPDEINT; m_skippedDeint++; } m_requestSkipDeint = false; pDvdVideoPicture->iFlags |= m_codecControlFlags; if (!m_started) pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; return true; }
bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) { if (!m_pFrame) return false; pVideoPicture->iWidth = m_pFrame->width; pVideoPicture->iHeight = m_pFrame->height; /* crop of 10 pixels if demuxer asked it */ if(m_pCodecContext->coded_width && m_pCodecContext->coded_width < (int)pVideoPicture->iWidth && m_pCodecContext->coded_width > (int)pVideoPicture->iWidth - 10) pVideoPicture->iWidth = m_pCodecContext->coded_width; if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pVideoPicture->iHeight && m_pCodecContext->coded_height > (int)pVideoPicture->iHeight - 10) pVideoPicture->iHeight = m_pCodecContext->coded_height; double aspect_ratio; /* use variable in the frame */ AVRational pixel_aspect = m_pFrame->sample_aspect_ratio; if (pixel_aspect.num == 0) aspect_ratio = 0; else aspect_ratio = av_q2d(pixel_aspect) * pVideoPicture->iWidth / pVideoPicture->iHeight; if (aspect_ratio <= 0.0) aspect_ratio = (float)pVideoPicture->iWidth / (float)pVideoPicture->iHeight; if (m_DAR != aspect_ratio) { m_DAR = aspect_ratio; m_processInfo.SetVideoDAR(static_cast<float>(m_DAR)); } /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it. pVideoPicture->iDisplayHeight = pVideoPicture->iHeight; pVideoPicture->iDisplayWidth = ((int)RINT(pVideoPicture->iHeight * aspect_ratio)) & -3; if (pVideoPicture->iDisplayWidth > pVideoPicture->iWidth) { pVideoPicture->iDisplayWidth = pVideoPicture->iWidth; pVideoPicture->iDisplayHeight = ((int)RINT(pVideoPicture->iWidth / aspect_ratio)) & -3; } pVideoPicture->pts = DVD_NOPTS_VALUE; AVDictionaryEntry * entry = av_dict_get(m_pFrame->metadata, "stereo_mode", NULL, 0); if(entry && entry->value) { pVideoPicture->stereoMode = (const char*)entry->value; } else pVideoPicture->stereoMode.clear(); pVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict; pVideoPicture->iFlags = 0; pVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0; pVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0; if (m_codecControlFlags & DVD_CODEC_CTRL_DROP) { pVideoPicture->iFlags |= DVP_FLAG_DROPPED; } pVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location; pVideoPicture->color_primaries = m_pCodecContext->color_primaries; pVideoPicture->color_transfer = m_pCodecContext->color_trc; pVideoPicture->color_space = m_pCodecContext->colorspace; pVideoPicture->colorBits = 8; // determine how number of bits of encoded video if (m_pCodecContext->pix_fmt == AV_PIX_FMT_YUV420P12) pVideoPicture->colorBits = 12; else if (m_pCodecContext->pix_fmt == AV_PIX_FMT_YUV420P10) pVideoPicture->colorBits = 10; else if (m_pCodecContext->codec_id == AV_CODEC_ID_HEVC && m_pCodecContext->profile == FF_PROFILE_HEVC_MAIN_10) pVideoPicture->colorBits = 10; else if (m_pCodecContext->codec_id == AV_CODEC_ID_H264 && (m_pCodecContext->profile == FF_PROFILE_H264_HIGH_10|| m_pCodecContext->profile == FF_PROFILE_H264_HIGH_10_INTRA)) pVideoPicture->colorBits = 10; if (m_pCodecContext->color_range == AVCOL_RANGE_JPEG || m_pCodecContext->pix_fmt == AV_PIX_FMT_YUVJ420P) pVideoPicture->color_range = 1; else pVideoPicture->color_range = 0; pVideoPicture->qp_table = av_frame_get_qp_table(m_pFrame, &pVideoPicture->qstride, &pVideoPicture->qscale_type); pVideoPicture->pict_type = m_pFrame->pict_type; // metadata pVideoPicture->hasDisplayMetadata = false; pVideoPicture->hasLightMetadata = false; AVFrameSideData *sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); if (sd) { pVideoPicture->displayMetadata = *(AVMasteringDisplayMetadata *)sd->data; pVideoPicture->hasDisplayMetadata = true; } sd = av_frame_get_side_data(m_pFrame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); if (sd) { pVideoPicture->lightMetadata = *(AVContentLightMetadata *)sd->data; pVideoPicture->hasLightMetadata = true; } if (pVideoPicture->iRepeatPicture) pVideoPicture->dts = DVD_NOPTS_VALUE; else pVideoPicture->dts = m_dts; m_dts = DVD_NOPTS_VALUE; int64_t bpts = m_pFrame->best_effort_timestamp; if (bpts != AV_NOPTS_VALUE) { pVideoPicture->pts = (double)bpts * DVD_TIME_BASE / AV_TIME_BASE; if (pVideoPicture->pts == m_decoderPts) { pVideoPicture->iRepeatPicture = -0.5; pVideoPicture->pts = DVD_NOPTS_VALUE; pVideoPicture->dts = DVD_NOPTS_VALUE; } } else pVideoPicture->pts = DVD_NOPTS_VALUE; if (pVideoPicture->pts != DVD_NOPTS_VALUE) m_decoderPts = pVideoPicture->pts; if (m_requestSkipDeint) { pVideoPicture->iFlags |= DVD_CODEC_CTRL_SKIPDEINT; m_skippedDeint++; } m_requestSkipDeint = false; pVideoPicture->iFlags |= m_codecControlFlags; return true; }