Пример #1
0
enum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat(struct AVCodecContext * avctx, const AVPixelFormat * fmt)
{
  ICallbackHWAccel *cb = static_cast<ICallbackHWAccel*>(avctx->opaque);
  CDVDVideoCodecFFmpeg* ctx  = dynamic_cast<CDVDVideoCodecFFmpeg*>(cb);

  const char* pixFmtName = av_get_pix_fmt_name(*fmt);

  ctx->m_processInfo.SetVideoDimensions(avctx->coded_width, avctx->coded_height);

  // if frame threading is enabled hw accel is not allowed
  // 2nd condition:
  // fix an ffmpeg issue here, it calls us with an invalid profile
  // then a 2nd call with a valid one
  if(ctx->m_decoderState != STATE_HW_SINGLE ||
     (avctx->codec_id == AV_CODEC_ID_VC1 && avctx->profile == FF_PROFILE_UNKNOWN))
  {
    AVPixelFormat defaultFmt = avcodec_default_get_format(avctx, fmt);
    pixFmtName = av_get_pix_fmt_name(defaultFmt);
    ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
    ctx->m_processInfo.SetSwDeinterlacingMethods();
    return defaultFmt;
  }

  // hardware decoder de-selected, restore standard ffmpeg
  if (ctx->HasHardware())
  {
    ctx->SetHardware(nullptr);
    avctx->get_buffer2 = avcodec_default_get_buffer2;
    avctx->slice_flags = 0;
    av_buffer_unref(&avctx->hw_frames_ctx);
  }

  const AVPixelFormat * cur = fmt;
  while (*cur != AV_PIX_FMT_NONE)
  {
    pixFmtName = av_get_pix_fmt_name(*cur);

    auto hwaccels = CDVDFactoryCodec::GetHWAccels();
    for (auto &hwaccel : hwaccels)
    {
      IHardwareDecoder *pDecoder(CDVDFactoryCodec::CreateVideoCodecHWAccel(hwaccel, ctx->m_hints,
                                                                           ctx->m_processInfo, *cur));
      if (pDecoder)
      {
        if (pDecoder->Open(avctx, ctx->m_pCodecContext, *cur))
        {
          ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
          ctx->SetHardware(pDecoder);
          return *cur;
        }
      }
      SAFE_RELEASE(pDecoder);
    }
    cur++;
  }

  ctx->m_processInfo.SetVideoPixelFormat(pixFmtName ? pixFmtName : "");
  ctx->m_decoderState = STATE_HW_FAILED;
  return avcodec_default_get_format(avctx, fmt);
}
Пример #2
0
static AVPixelFormat
getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats)
{
    auto accel = static_cast<HardwareAccel*>(codecCtx->opaque);
    if (!accel) {
        // invalid state, try to recover
        return avcodec_default_get_format(codecCtx, formats);
    }

    for (int i = 0; formats[i] != AV_PIX_FMT_NONE; i++) {
        if (formats[i] == accel->format()) {
            accel->setWidth(codecCtx->coded_width);
            accel->setHeight(codecCtx->coded_height);
            accel->setProfile(codecCtx->profile);
            accel->setCodecCtx(codecCtx);
            if (accel->init())
                return accel->format();
            break;
        }
    }

    accel->fail(true);
    RING_WARN("Falling back to software decoding");
    codecCtx->get_format = avcodec_default_get_format;
    codecCtx->get_buffer2 = avcodec_default_get_buffer2;
    for (int i = 0; formats[i] != AV_PIX_FMT_NONE; i++) {
        auto desc = av_pix_fmt_desc_get(formats[i]);
        if (desc && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
            return formats[i];
        }
    }

    return AV_PIX_FMT_NONE;
}
Пример #3
0
AVPixelFormat VideoDecoderFFmpegHWPrivate::getFormat(struct AVCodecContext *p_context, const AVPixelFormat *pi_fmt)
{
    bool can_hwaccel = false;
    for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(NONE); i++) {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        qDebug("available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name);
        if (hwaccel)
            can_hwaccel = true;
    }
    if (!can_hwaccel)
        goto end;
    for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(NONE); i++) {
        if (vaPixelFormat() != pi_fmt[i])
            continue;
        /* We try to call setup when possible to detect errors when possible (later is too late) */
        if (p_context->width > 0 && p_context->height > 0
         && !setup(p_context)) {
            qWarning("acceleration setup failure");
            break;
        }
        qDebug("Using %s for hardware decoding.", qPrintable(description));
        p_context->draw_horiz_band = NULL; //??
        return pi_fmt[i];
    }
    close();
end:
    qWarning("hardware acceleration is not available" );
    /* Fallback to default behaviour */
    return avcodec_default_get_format(p_context, pi_fmt);
}
Пример #4
0
AVPixelFormat VideoDecoderFFmpegHWPrivate::getFormat(struct AVCodecContext *p_context, const AVPixelFormat *pi_fmt)
{
    bool can_hwaccel = false;
    for (size_t i = 0; pi_fmt[i] != QTAV_PIX_FMT_C(NONE); i++) {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        qDebug("available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name);
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        goto end;

    /* Profile and level information is needed now.
     * TODO: avoid code duplication with avcodec.c */
#if 0
    if (p_context->profile != FF_PROFILE_UNKNOWN)
        p_dec->fmt_in.i_profile = p_context->profile;
    if (p_context->level != FF_LEVEL_UNKNOWN)
        p_dec->fmt_in.i_level = p_context->level;
#endif
    for (size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++) {
        if (vaPixelFormat() != pi_fmt[i])
            continue;

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if (p_context->width > 0 && p_context->height > 0
         && !setup(p_context)) {
            qWarning("acceleration setup failure");
            break;
        }

        qDebug("Using %s for hardware decoding.", qPrintable(description));

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        //p_sys->b_direct_rendering = false;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    close();
    //vlc_va_Delete(p_va);
end:
    qWarning("acceleration not available" );
    /* Fallback to default behaviour */
    return avcodec_default_get_format(p_context, pi_fmt);
}
Пример #5
0
enum PixelFormat hb_ffmpeg_get_format( AVCodecContext *p_context, const enum PixelFormat *pi_fmt )
{
    int i;
    for( i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++ )
    {
        hb_log( "dxva2:Available decoder output format %d (%s)", pi_fmt[i], hb_get_pix_fmt_name(pi_fmt[i]) ? : "Unknown" );
        if( pi_fmt[i] == AV_PIX_FMT_DXVA2_VLD )
        {
            return pi_fmt[i];
        }
    }
    return avcodec_default_get_format( p_context, pi_fmt );
}
Пример #6
0
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_codec,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_codec->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_sys->p_va )
    {
        VaDelete( p_sys->p_va );
        p_sys->p_va = NULL;
    }

    /* Try too look for a supported hw acceleration */
    for( int i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        static const char *ppsz_name[PIX_FMT_NB] = {
            [PIX_FMT_VDPAU_H264] = "PIX_FMT_VDPAU_H264",
            [PIX_FMT_VAAPI_IDCT] = "PIX_FMT_VAAPI_IDCT",
            [PIX_FMT_VAAPI_VLD] = "PIX_FMT_VAAPI_VLD",
            [PIX_FMT_VAAPI_MOCO] = "PIX_FMT_VAAPI_MOCO",
            [PIX_FMT_YUYV422] = "PIX_FMT_YUYV422",
            [PIX_FMT_YUV420P] = "PIX_FMT_YUV420P",
        };
        msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i], ppsz_name[pi_fmt[i]] ?: "Unknown" );

        /* Only VLD supported */
        if( pi_fmt[i] == PIX_FMT_VAAPI_VLD )
        {
            msg_Dbg( p_dec, "Trying VA API" );
            p_sys->p_va = VaNew( p_sys->i_codec_id );
            if( p_sys->p_va )
            {
                /* FIXME this will disabled direct rendering
                 * even if a new pixel format is renegociated
                 *
                 * FIXME Try to call VaSetup when possible
                 * to detect errors when possible (later is too late) */
                p_sys->b_direct_rendering = false;
                p_sys->p_context->draw_horiz_band = NULL;
                return pi_fmt[i];
            }
            msg_Warn( p_dec, "Failed to open VA API" );
        }
    }

    /* Fallback to default behaviour */
    return avcodec_default_get_format( p_codec, pi_fmt );
}
Пример #7
0
static enum PixelFormat
libav_get_format(struct AVCodecContext *ctx, const enum PixelFormat *fmt)
{
  media_codec_t *mc = ctx->opaque;
  if(mc->close != NULL) {
    mc->close(mc);
    mc->close = NULL;
  }

#if ENABLE_VDPAU
  if(!vdpau_init_libav_decode(mc, ctx)) {
    return AV_PIX_FMT_VDPAU;
  }
#endif
  mc->get_buffer2 = &avcodec_default_get_buffer2;
  return avcodec_default_get_format(ctx, fmt);
}
Пример #8
0
enum AVPixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
                                                , const AVPixelFormat * fmt )
{
  CDVDVideoCodecFFmpeg* ctx  = (CDVDVideoCodecFFmpeg*)avctx->opaque;

  // if frame threading is enabled hw accel is not allowed
  if(ctx->m_decoderState != STATE_HW_SINGLE)
  {
    return avcodec_default_get_format(avctx, fmt);
  }

  // fix an ffmpeg issue here, it calls us with an invalid profile
  // then a 2nd call with a valid one
  if (avctx->codec_id == AV_CODEC_ID_VC1 && avctx->profile == FF_PROFILE_UNKNOWN)
  {
    return avcodec_default_get_format(avctx, fmt);
  }

  // hardware decoder de-selected, restore standard ffmpeg
  if (ctx->GetHardware())
  {
    ctx->SetHardware(NULL);
    avctx->get_buffer2 = avcodec_default_get_buffer2;
    avctx->slice_flags = 0;
    avctx->hwaccel_context = 0;
  }

  const AVPixelFormat * cur = fmt;
  while(*cur != AV_PIX_FMT_NONE)
  {
#ifdef HAVE_LIBVDPAU
    if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDPAU))
    {
      CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height);
      VDPAU::CDecoder* vdp = new VDPAU::CDecoder();
      if(vdp->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))
      {
        ctx->SetHardware(vdp);
        return *cur;
      }
      else
        vdp->Release();
    }
#endif
#ifdef HAS_DX
  if(DXVA::CDecoder::Supports(*cur) && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDXVA2) &&
     !ctx->m_hints.dvd && !ctx->m_hints.stills)
  {
    CLog::Log(LOGNOTICE, "CDVDVideoCodecFFmpeg::GetFormat - Creating DXVA(%ix%i)", avctx->width, avctx->height);
    DXVA::CDecoder* dec = new DXVA::CDecoder();
    if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))
    {
      ctx->SetHardware(dec);
      return *cur;
    }
    else
      dec->Release();
  }
#endif
#ifdef HAVE_LIBVA
    // mpeg4 vaapi decoding is disabled
    if(*cur == AV_PIX_FMT_VAAPI_VLD && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVAAPI))
    {
      VAAPI::CDecoder* dec = new VAAPI::CDecoder();
      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount) == true)
      {
        ctx->SetHardware(dec);
        return *cur;
      }
      else
        dec->Release();
    }
#endif

#ifdef TARGET_DARWIN
    if (*cur == AV_PIX_FMT_VIDEOTOOLBOX && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVTB))
    {
      VTB::CDecoder* dec = new VTB::CDecoder();
      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))
      {
        ctx->SetHardware(dec);
        return *cur;
      }
      else
        dec->Release();
    }
#endif

#ifdef HAS_MMAL
    if (*cur == AV_PIX_FMT_YUV420P)
    {
      MMAL::CDecoder* dec = new MMAL::CDecoder();
      ctx->m_pCodecContext->hwaccel_context = (void *)ctx->m_options.m_opaque_pointer;
      if(dec->Open(avctx, ctx->m_pCodecContext, *cur, ctx->m_uSurfacesCount))
      {
        ctx->SetHardware(dec);
        return *cur;
      }
      else
        dec->Release();
    }
#endif
    cur++;
  }

  ctx->m_decoderState = STATE_HW_FAILED;
  return avcodec_default_get_format(avctx, fmt);
}
Пример #9
0
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    vlc_va_t *p_va = p_sys->p_va;

    if( p_va != NULL )
        vlc_va_Delete( p_va );

    /* Enumerate available formats */
    bool can_hwaccel = false;
    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        goto end;

    /* Profile and level information is needed now.
     * TODO: avoid code duplication with avcodec.c */
    if( p_context->profile != FF_PROFILE_UNKNOWN)
        p_dec->fmt_in.i_profile = p_context->profile;
    if( p_context->level != FF_LEVEL_UNKNOWN)
        p_dec->fmt_in.i_level = p_context->level;

    p_va = vlc_va_New( VLC_OBJECT(p_dec), p_context, &p_dec->fmt_in );
    if( p_va == NULL )
        goto end;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        if( p_va->pix_fmt != pi_fmt[i] )
            continue;

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if( p_context->width > 0 && p_context->height > 0
         && vlc_va_Setup( p_va, &p_context->hwaccel_context,
                          &p_dec->fmt_out.video.i_chroma,
                          p_context->width, p_context->height ) )
        {
            msg_Err( p_dec, "acceleration setup failure" );
            break;
        }

        if( p_va->description )
            msg_Info( p_dec, "Using %s for hardware decoding.",
                      p_va->description );

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        p_sys->b_direct_rendering = false;
        p_sys->p_va = p_va;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    vlc_va_Delete( p_va );

end:
    /* Fallback to default behaviour */
    p_sys->p_va = NULL;
    return avcodec_default_get_format( p_context, pi_fmt );
}
Пример #10
0
Файл: video.c Проект: bobwxb/vlc
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    if (p_sys->p_va != NULL)
    {
        vlc_va_Delete(p_sys->p_va, p_context);
        p_sys->p_va = NULL;
    }

    /* Enumerate available formats */
    enum PixelFormat swfmt = avcodec_default_get_format(p_context, pi_fmt);
    bool can_hwaccel = false;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(pi_fmt[i]);
        if (dsc == NULL)
            continue;
        bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;

        msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
                 hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
        if (hwaccel)
            can_hwaccel = true;
    }

    if (!can_hwaccel)
        return swfmt;

    for( size_t i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        enum PixelFormat hwfmt = pi_fmt[i];

        p_dec->fmt_out.video.i_chroma = vlc_va_GetChroma(hwfmt, swfmt);
        if (p_dec->fmt_out.video.i_chroma == 0)
            continue; /* Unknown brand of hardware acceleration */
        if (lavc_UpdateVideoFormat(p_dec, p_context, true))
            continue; /* Unsupported brand of hardware acceleration */

        vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), p_context, hwfmt,
                                  &p_dec->fmt_in);
        if (va == NULL)
            continue; /* Unsupported codec profile or such */

        /* We try to call vlc_va_Setup when possible to detect errors when
         * possible (later is too late) */
        if( p_context->width > 0 && p_context->height > 0
         && vlc_va_Setup(va, p_context, &p_dec->fmt_out.video.i_chroma))
        {
            msg_Err( p_dec, "acceleration setup failure" );
            vlc_va_Delete(va, p_context);
            continue;
        }

        if (va->description != NULL)
            msg_Info(p_dec, "Using %s for hardware decoding", va->description);

        /* FIXME this will disable direct rendering
         * even if a new pixel format is renegotiated
         */
        p_sys->b_direct_rendering = false;
        p_sys->p_va = va;
        p_context->draw_horiz_band = NULL;
        return pi_fmt[i];
    }

    /* Fallback to default behaviour */
    return swfmt;
}
Пример #11
0
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_codec,
                                          const enum PixelFormat *pi_fmt )
{
    decoder_t *p_dec = p_codec->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_sys->p_va )
    {
        vlc_va_Delete( p_sys->p_va );
        p_sys->p_va = NULL;
    }

    /* Try too look for a supported hw acceleration */
    for( int i = 0; pi_fmt[i] != PIX_FMT_NONE; i++ )
    {
        static const char *ppsz_name[PIX_FMT_NB] = {
            [PIX_FMT_VDPAU_H264] = "PIX_FMT_VDPAU_H264",
            [PIX_FMT_VAAPI_IDCT] = "PIX_FMT_VAAPI_IDCT",
            [PIX_FMT_VAAPI_VLD] = "PIX_FMT_VAAPI_VLD",
            [PIX_FMT_VAAPI_MOCO] = "PIX_FMT_VAAPI_MOCO",
#ifdef HAVE_AVCODEC_DXVA2
            [PIX_FMT_DXVA2_VLD] = "PIX_FMT_DXVA2_VLD",
#endif
            [PIX_FMT_YUYV422] = "PIX_FMT_YUYV422",
            [PIX_FMT_YUV420P] = "PIX_FMT_YUV420P",
        };
        msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i], ppsz_name[pi_fmt[i]] ?: "Unknown" );

        /* Only VLD supported */
        if( pi_fmt[i] == PIX_FMT_VAAPI_VLD )
        {
#ifdef HAVE_AVCODEC_VAAPI
            msg_Dbg( p_dec, "Trying VA API" );
            p_sys->p_va = vlc_va_NewVaapi( p_sys->i_codec_id );
            if( !p_sys->p_va )
                msg_Warn( p_dec, "Failed to open VA API" );
#else
            continue;
#endif
        }
#ifdef HAVE_AVCODEC_DXVA2
        if( pi_fmt[i] == PIX_FMT_DXVA2_VLD )
        {
            msg_Dbg( p_dec, "Trying DXVA2" );
            p_sys->p_va = vlc_va_NewDxva2( VLC_OBJECT(p_dec), p_sys->i_codec_id );
            if( !p_sys->p_va )
                msg_Warn( p_dec, "Failed to open DXVA2" );
        }
#endif

        if( p_sys->p_va &&
            p_sys->p_context->width > 0 && p_sys->p_context->height > 0 )
        {
            /* We try to call vlc_va_Setup when possible to detect errors when
             * possible (later is too late) */
            if( vlc_va_Setup( p_sys->p_va,
                              &p_sys->p_context->hwaccel_context,
                              &p_dec->fmt_out.video.i_chroma,
                              p_sys->p_context->width, p_sys->p_context->height ) )
            {
                msg_Err( p_dec, "vlc_va_Setup failed" );
                vlc_va_Delete( p_sys->p_va );
                p_sys->p_va = NULL;
            }
        }

        if( p_sys->p_va )
        {
            if( p_sys->p_va->description )
                msg_Info( p_dec, "Using %s for hardware decoding.", p_sys->p_va->description );

            /* FIXME this will disabled direct rendering
             * even if a new pixel format is renegociated
             */
            p_sys->b_direct_rendering = false;
            p_sys->p_context->draw_horiz_band = NULL;
            return pi_fmt[i];
        }
    }

    /* Fallback to default behaviour */
    return avcodec_default_get_format( p_codec, pi_fmt );
}