예제 #1
0
static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)
{
    int width = 0;
    int height = 0;
    int32_t value = 0;
    char *format = NULL;

    if (!s->format) {
        av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n");
        return AVERROR(EINVAL);
    }

    format = ff_AMediaFormat_toString(s->format);
    if (!format) {
        return AVERROR_EXTERNAL;
    }
    av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format);
    av_freep(&format);

    /* Mandatory fields */
    if (!ff_AMediaFormat_getInt32(s->format, "width", &value)) {
        format = ff_AMediaFormat_toString(s->format);
        av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", "width", format);
        av_freep(&format);
        return AVERROR_EXTERNAL;
    }
    s->width = value;

    if (!ff_AMediaFormat_getInt32(s->format, "height", &value)) {
        format = ff_AMediaFormat_toString(s->format);
        av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", "height", format);
        av_freep(&format);
        return AVERROR_EXTERNAL;
    }
    s->height = value;

    if (!ff_AMediaFormat_getInt32(s->format, "stride", &value)) {
        format = ff_AMediaFormat_toString(s->format);
        av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", "stride", format);
        av_freep(&format);
        return AVERROR_EXTERNAL;
    }
    s->stride = value > 0 ? value : s->width;

    if (!ff_AMediaFormat_getInt32(s->format, "slice-height", &value)) {
        format = ff_AMediaFormat_toString(s->format);
        av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", "slice-height", format);
        av_freep(&format);
        return AVERROR_EXTERNAL;
    }
    s->slice_height = value > 0 ? value : s->height;

    if (strstr(s->codec_name, "OMX.Nvidia.")) {
        s->slice_height = FFALIGN(s->height, 16);
    } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) {
        s->slice_height = avctx->height;
        s->stride = avctx->width;
    }

    if (!ff_AMediaFormat_getInt32(s->format, "color-format", &value)) {
        format = ff_AMediaFormat_toString(s->format);
        av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", "color-format", format);
        av_freep(&format);
        return AVERROR_EXTERNAL;
    }
    s->color_format = value;

    s->pix_fmt = avctx->pix_fmt = mcdec_map_color_format(avctx, s, value);
    if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
        av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n");
        return AVERROR(EINVAL);
    }

    /* Optional fields */
    if (ff_AMediaFormat_getInt32(s->format, "crop-top", &value))
        s->crop_top = value;

    if (ff_AMediaFormat_getInt32(s->format, "crop-bottom", &value))
        s->crop_bottom = value;

    if (ff_AMediaFormat_getInt32(s->format, "crop-left", &value))
        s->crop_left = value;

    if (ff_AMediaFormat_getInt32(s->format, "crop-right", &value))
        s->crop_right = value;

    width = s->crop_right + 1 - s->crop_left;
    height = s->crop_bottom + 1 - s->crop_top;

    av_log(avctx, AV_LOG_INFO,
        "Output crop parameters top=%d bottom=%d left=%d right=%d, "
        "resulting dimensions width=%d height=%d\n",
        s->crop_top, s->crop_bottom, s->crop_left, s->crop_right,
        width, height);

    return ff_set_dimensions(avctx, width, height);
}
예제 #2
0
static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)
{
    int ret = 0;
    int width = 0;
    int height = 0;
    char *format = NULL;

    if (!s->format) {
        av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n");
        return AVERROR(EINVAL);
    }

    format = ff_AMediaFormat_toString(s->format);
    if (!format) {
        return AVERROR_EXTERNAL;
    }
    av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format);

    /* Mandatory fields */
    AMEDIAFORMAT_GET_INT32(s->width,  "width", 1);
    AMEDIAFORMAT_GET_INT32(s->height, "height", 1);

    AMEDIAFORMAT_GET_INT32(s->stride, "stride", 1);
    s->stride = s->stride > 0 ? s->stride : s->width;

    AMEDIAFORMAT_GET_INT32(s->slice_height, "slice-height", 1);
    s->slice_height = s->slice_height > 0 ? s->slice_height : s->height;

    if (strstr(s->codec_name, "OMX.Nvidia.")) {
        s->slice_height = FFALIGN(s->height, 16);
    } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) {
        s->slice_height = avctx->height;
        s->stride = avctx->width;
    }

    AMEDIAFORMAT_GET_INT32(s->color_format, "color-format", 1);
    avctx->pix_fmt = mcdec_map_color_format(avctx, s, s->color_format);
    if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
        av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n");
        ret = AVERROR(EINVAL);
        goto fail;
    }

    /* Optional fields */
    AMEDIAFORMAT_GET_INT32(s->crop_top,    "crop-top",    0);
    AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0);
    AMEDIAFORMAT_GET_INT32(s->crop_left,   "crop-left",   0);
    AMEDIAFORMAT_GET_INT32(s->crop_right,  "crop-right",  0);

    width = s->crop_right + 1 - s->crop_left;
    height = s->crop_bottom + 1 - s->crop_top;

    AMEDIAFORMAT_GET_INT32(s->display_width,  "display-width",  0);
    AMEDIAFORMAT_GET_INT32(s->display_height, "display-height", 0);

    if (s->display_width && s->display_height) {
        AVRational sar = av_div_q(
            (AVRational){ s->display_width, s->display_height },
            (AVRational){ width, height });
        ff_set_sar(avctx, sar);
    }

    av_log(avctx, AV_LOG_INFO,
        "Output crop parameters top=%d bottom=%d left=%d right=%d, "
        "resulting dimensions width=%d height=%d\n",
        s->crop_top, s->crop_bottom, s->crop_left, s->crop_right,
        width, height);

    av_freep(&format);
    return ff_set_dimensions(avctx, width, height);
fail:
    av_freep(&format);
    return ret;
}