forked from KolibriOS/kolibrios
Fplay: check codec profile
git-svn-id: svn://kolibrios.org@6298 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
08a666b293
commit
d4596e51ef
@ -9,6 +9,7 @@
|
|||||||
#include <va/va.h>
|
#include <va/va.h>
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
#include <va/drm/va_drm.h>
|
#include <va/drm/va_drm.h>
|
||||||
|
#include <alloca.h>
|
||||||
#include <kos32sys.h>
|
#include <kos32sys.h>
|
||||||
#include "winlib/winlib.h"
|
#include "winlib/winlib.h"
|
||||||
#include "fplay.h"
|
#include "fplay.h"
|
||||||
@ -56,7 +57,7 @@ static const struct hw_profile hw_profiles[] = {
|
|||||||
PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple),
|
PE(MPEG4, MPEG4_SIMPLE, MPEG4Simple),
|
||||||
PE(H264, H264_HIGH, H264High),
|
PE(H264, H264_HIGH, H264High),
|
||||||
PE(H264, H264_MAIN, H264Main),
|
PE(H264, H264_MAIN, H264Main),
|
||||||
PE(H264, H264_BASELINE, H264Baseline),
|
PE(H264, H264_CONSTRAINED_BASELINE, H264ConstrainedBaseline),
|
||||||
PE(VC1, VC1_ADVANCED, VC1Advanced),
|
PE(VC1, VC1_ADVANCED, VC1Advanced),
|
||||||
PE(VC1, VC1_MAIN, VC1Main),
|
PE(VC1, VC1_MAIN, VC1Main),
|
||||||
PE(VC1, VC1_SIMPLE, VC1Simple),
|
PE(VC1, VC1_SIMPLE, VC1Simple),
|
||||||
@ -221,10 +222,14 @@ static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
|
|||||||
{
|
{
|
||||||
VAProfile *profiles;
|
VAProfile *profiles;
|
||||||
int n_profiles;
|
int n_profiles;
|
||||||
|
size_t size;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
profiles = calloc(vaMaxNumProfiles(vaapi->display), sizeof(profiles[0]));
|
size = vaMaxNumProfiles(vaapi->display) * sizeof(VAProfile);
|
||||||
|
|
||||||
|
profiles = alloca(size);
|
||||||
|
memset(profiles, 0, size);
|
||||||
|
|
||||||
status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
|
status = vaQueryConfigProfiles(vaapi->display,profiles,&n_profiles);
|
||||||
|
|
||||||
@ -245,10 +250,14 @@ static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntr
|
|||||||
{
|
{
|
||||||
VAEntrypoint *entrypoints;
|
VAEntrypoint *entrypoints;
|
||||||
int n_entrypoints;
|
int n_entrypoints;
|
||||||
|
size_t size;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
entrypoints = calloc(vaMaxNumEntrypoints(vaapi->display), sizeof(entrypoints[0]));
|
size = vaMaxNumEntrypoints(vaapi->display) * sizeof(VAEntrypoint);
|
||||||
|
|
||||||
|
entrypoints = alloca(size);
|
||||||
|
memset(entrypoints, 0, size);
|
||||||
|
|
||||||
status = vaQueryConfigEntrypoints(vaapi->display, profile,
|
status = vaQueryConfigEntrypoints(vaapi->display, profile,
|
||||||
entrypoints, &n_entrypoints);
|
entrypoints, &n_entrypoints);
|
||||||
@ -278,6 +287,10 @@ static int vaapi_init_decoder(vst_t *vst,VAProfile profile,
|
|||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
|
printf("%s profile %x width:%d height:%d\n",
|
||||||
|
__FUNCTION__, profile, picture_width, picture_height);
|
||||||
|
|
||||||
if (!vaapi)
|
if (!vaapi)
|
||||||
{
|
{
|
||||||
FAIL();
|
FAIL();
|
||||||
@ -382,37 +395,39 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx,
|
|||||||
const enum AVPixelFormat *fmt)
|
const enum AVPixelFormat *fmt)
|
||||||
{
|
{
|
||||||
vst_t *vst = (vst_t*)avctx->opaque;
|
vst_t *vst = (vst_t*)avctx->opaque;
|
||||||
VAProfile profile = VAProfileNone;
|
VAProfile profile = avctx->profile;
|
||||||
|
|
||||||
ENTER();
|
|
||||||
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
|
|
||||||
{
|
|
||||||
enum AVCodecID codec = avctx->codec_id;
|
enum AVCodecID codec = avctx->codec_id;
|
||||||
|
|
||||||
if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
|
printf("%s codec %d profile %x\n", __FUNCTION__,avctx->codec_id, avctx->profile);
|
||||||
continue;
|
|
||||||
|
|
||||||
if (codec == AV_CODEC_ID_H264)
|
if (codec == AV_CODEC_ID_H264)
|
||||||
{
|
{
|
||||||
if (profile == FF_PROFILE_H264_CONSTRAINED_BASELINE)
|
if(profile == FF_PROFILE_H264_BASELINE)
|
||||||
profile = FF_PROFILE_H264_MAIN;
|
profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
|
||||||
|
{
|
||||||
|
if (fmt[i] != AV_PIX_FMT_VAAPI_VLD)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int n = 0; hw_profiles[n].av_codec; n++)
|
for (int n = 0; hw_profiles[n].av_codec; n++)
|
||||||
{
|
{
|
||||||
if (hw_profiles[n].av_codec == codec &&
|
if (hw_profiles[n].av_codec == codec &&
|
||||||
hw_profiles[n].ff_profile == avctx->profile)
|
hw_profiles[n].ff_profile == profile)
|
||||||
{
|
{
|
||||||
profile = hw_profiles[n].va_profile;
|
profile = hw_profiles[n].va_profile;
|
||||||
if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
|
if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
|
||||||
{
|
{
|
||||||
avctx->hwaccel_context = v_context;
|
avctx->hwaccel_context = v_context;
|
||||||
return fmt[i]; ;
|
printf("%s format: %x\n",__FUNCTION__, fmt[i]);
|
||||||
|
return fmt[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
printf("%s format PIX_FMT_NONE\n",__FUNCTION__);
|
||||||
return PIX_FMT_NONE;
|
return PIX_FMT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,12 +440,11 @@ struct av_surface
|
|||||||
|
|
||||||
static void av_release_buffer(void *opaque, uint8_t *data)
|
static void av_release_buffer(void *opaque, uint8_t *data)
|
||||||
{
|
{
|
||||||
struct av_surface surface = *(struct av_surface*)data;
|
|
||||||
av_freep(&data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
|
static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
|
||||||
{
|
{
|
||||||
|
static struct av_surface avsurface;
|
||||||
vst_t *vst = (vst_t*)avctx->opaque;
|
vst_t *vst = (vst_t*)avctx->opaque;
|
||||||
void *surface;
|
void *surface;
|
||||||
|
|
||||||
@ -438,12 +452,7 @@ static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags)
|
|||||||
|
|
||||||
pic->data[3] = surface;
|
pic->data[3] = surface;
|
||||||
|
|
||||||
struct av_surface *avsurface;
|
pic->buf[0] = av_buffer_create((uint8_t*)&avsurface, sizeof(avsurface),
|
||||||
surface = av_malloc(sizeof(*avsurface));
|
|
||||||
if (!surface)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
pic->buf[0] = av_buffer_create((uint8_t*)avsurface, sizeof(*avsurface),
|
|
||||||
av_release_buffer, avctx,
|
av_release_buffer, avctx,
|
||||||
AV_BUFFER_FLAG_READONLY);
|
AV_BUFFER_FLAG_READONLY);
|
||||||
return 0;
|
return 0;
|
||||||
@ -577,6 +586,90 @@ void va_create_planar(vst_t *vst, vframe_t *vframe)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum AVCodecID profile_to_codec(VAProfile profile)
|
||||||
|
{
|
||||||
|
enum AVCodecID id;
|
||||||
|
|
||||||
|
switch(profile)
|
||||||
|
{
|
||||||
|
case VAProfileMPEG2Simple:
|
||||||
|
case VAProfileMPEG2Main:
|
||||||
|
id = AV_CODEC_ID_MPEG2VIDEO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAProfileMPEG4Simple:
|
||||||
|
case VAProfileMPEG4AdvancedSimple:
|
||||||
|
case VAProfileMPEG4Main:
|
||||||
|
id = AV_CODEC_ID_MPEG4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAProfileH264Baseline:
|
||||||
|
case VAProfileH264Main:
|
||||||
|
case VAProfileH264High:
|
||||||
|
case VAProfileH264ConstrainedBaseline:
|
||||||
|
case VAProfileH264MultiviewHigh:
|
||||||
|
case VAProfileH264StereoHigh:
|
||||||
|
id = AV_CODEC_ID_H264;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAProfileVC1Simple:
|
||||||
|
case VAProfileVC1Main:
|
||||||
|
case VAProfileVC1Advanced:
|
||||||
|
id = AV_CODEC_ID_VC1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VAProfileHEVCMain:
|
||||||
|
case VAProfileHEVCMain10:
|
||||||
|
id = AV_CODEC_ID_HEVC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
id = AV_CODEC_ID_NONE;
|
||||||
|
};
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VAProfile get_profile(VADisplay dpy, enum AVCodecID codec_id)
|
||||||
|
{
|
||||||
|
VAProfile profile = VAProfileNone, *profile_list = NULL;
|
||||||
|
int num_profiles, max_num_profiles;
|
||||||
|
enum AVCodecID ff_id;
|
||||||
|
VAStatus va_status;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
max_num_profiles = vaMaxNumProfiles(dpy);
|
||||||
|
|
||||||
|
profile_list = alloca(max_num_profiles * sizeof(VAProfile));
|
||||||
|
if (!profile_list)
|
||||||
|
{
|
||||||
|
printf("Failed to allocate memory for profile list\n");
|
||||||
|
goto err_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_status = vaQueryConfigProfiles(dpy, profile_list, &num_profiles);
|
||||||
|
if(!vaapi_check_status(va_status, "vaQueryConfigProfiles()"))
|
||||||
|
goto err_0;
|
||||||
|
|
||||||
|
if(codec_id == AV_CODEC_ID_H263)
|
||||||
|
ff_id = AV_CODEC_ID_H264;
|
||||||
|
else if(codec_id == AV_CODEC_ID_WMV3)
|
||||||
|
ff_id = AV_CODEC_ID_VC1;
|
||||||
|
else
|
||||||
|
ff_id = codec_id;
|
||||||
|
|
||||||
|
for (i = 0; i < num_profiles; i++)
|
||||||
|
{
|
||||||
|
if(ff_id == profile_to_codec(profile_list[i]))
|
||||||
|
{
|
||||||
|
profile = profile_list[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
err_0:
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
struct decoder* va_init_decoder(vst_t *vst)
|
struct decoder* va_init_decoder(vst_t *vst)
|
||||||
{
|
{
|
||||||
AVCodecContext *vCtx = vst->vCtx;
|
AVCodecContext *vCtx = vst->vCtx;
|
||||||
@ -599,6 +692,9 @@ struct decoder* va_init_decoder(vst_t *vst)
|
|||||||
if(decoder->hwctx == NULL)
|
if(decoder->hwctx == NULL)
|
||||||
goto err_1;
|
goto err_1;
|
||||||
|
|
||||||
|
if(get_profile(dpy, vCtx->codec_id) == VAProfileNone)
|
||||||
|
goto err_1;
|
||||||
|
|
||||||
decoder->Frame = av_frame_alloc();
|
decoder->Frame = av_frame_alloc();
|
||||||
if(decoder->Frame == NULL)
|
if(decoder->Frame == NULL)
|
||||||
goto err_1;
|
goto err_1;
|
||||||
@ -645,8 +741,8 @@ struct decoder* va_init_decoder(vst_t *vst)
|
|||||||
err_2:
|
err_2:
|
||||||
av_frame_free(&decoder->Frame);
|
av_frame_free(&decoder->Frame);
|
||||||
err_1:
|
err_1:
|
||||||
free(decoder);
|
|
||||||
vaTerminate(dpy);
|
vaTerminate(dpy);
|
||||||
|
free(decoder);
|
||||||
err_0:
|
err_0:
|
||||||
drm_fd = 0;
|
drm_fd = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user