Bug #2267 ยป ffmpeg_2.9.patch
vdr-plugin-softhddevice-0.6.0+git20150324/Todo | ||
---|---|---|
check start with 24Hz display rate
|
||
crash with ffmpeg without vaapi and vdpau.
|
||
still-picture of PES recordings should use VideoMpegEnqueue.
|
||
convert PIX_FMT_... PixelFormat to new names AV_PIX_FMT_..., AVPixelFormat.
|
||
atmo service support 3D grab
|
||
no warnings during still picture
|
||
-- vdr-plugin-softhddevice-0.6.0+git20150324.orig/codec.c
|
||
++ vdr-plugin-softhddevice-0.6.0+git20150324/codec.c
|
||
... | ... | |
//----------------------------------------------------------------------------
|
||
/**
|
||
** Callback to negotiate the PixelFormat.
|
||
** Callback to negotiate the AVPixelFormat.
|
||
**
|
||
** @param video_ctx codec context
|
||
** @param fmt is the list of formats which are supported by
|
||
... | ... | |
** valid format, the formats are ordered by
|
||
** quality.
|
||
*/
|
||
static enum PixelFormat Codec_get_format(AVCodecContext * video_ctx,
|
||
const enum PixelFormat *fmt)
|
||
static enum AVPixelFormat Codec_get_format(AVCodecContext * video_ctx,
|
||
const enum AVPixelFormat *fmt)
|
||
{
|
||
VideoDecoder *decoder;
|
||
... | ... | |
return Video_get_format(decoder->HwDecoder, video_ctx, fmt);
|
||
}
|
||
static void Codec_free_buffer(void *opaque, uint8_t *data);
|
||
/**
|
||
** Video buffer management, get buffer for frame.
|
||
**
|
||
... | ... | |
** @param video_ctx Codec context
|
||
** @param frame Get buffer for this frame
|
||
*/
|
||
static int Codec_get_buffer(AVCodecContext * video_ctx, AVFrame * frame)
|
||
static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int flags)
|
||
{
|
||
VideoDecoder *decoder;
|
||
... | ... | |
// libav 0.8.5 53.35.0 still needs this
|
||
#endif
|
||
if (!decoder->GetFormatDone) { // get_format missing
|
||
enum PixelFormat fmts[2];
|
||
enum AVPixelFormat fmts[2];
|
||
fprintf(stderr, "codec: buggy libav, use ffmpeg\n");
|
||
Warning(_("codec: buggy libav, use ffmpeg\n"));
|
||
fmts[0] = video_ctx->pix_fmt;
|
||
fmts[1] = PIX_FMT_NONE;
|
||
fmts[1] = AV_PIX_FMT_NONE;
|
||
Codec_get_format(video_ctx, fmts);
|
||
}
|
||
#ifdef USE_VDPAU
|
||
// VDPAU: PIX_FMT_VDPAU_H264 .. PIX_FMT_VDPAU_VC1 PIX_FMT_VDPAU_MPEG4
|
||
if ((PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == PIX_FMT_VDPAU_MPEG4) {
|
||
// VDPAU: AV_PIX_FMT_VDPAU_H264 .. AV_PIX_FMT_VDPAU_VC1 AV_PIX_FMT_VDPAU_MPEG4
|
||
if ((AV_PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= AV_PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG4) {
|
||
unsigned surface;
|
||
struct vdpau_render_state *vrs;
|
||
... | ... | |
frame->age = 256 * 256 * 256 * 64;
|
||
#endif
|
||
// render
|
||
frame->data[0] = (void *)vrs;
|
||
frame->buf[0] = av_buffer_create((uint8_t*)vrs, 0, Codec_free_buffer, video_ctx, 0);
|
||
frame->data[0] = frame->buf[0]->data;
|
||
frame->data[1] = NULL;
|
||
frame->data[2] = NULL;
|
||
frame->data[3] = NULL;
|
||
... | ... | |
frame->age = 256 * 256 * 256 * 64;
|
||
#endif
|
||
// vaapi needs both fields set
|
||
frame->data[0] = (void *)(size_t) surface;
|
||
frame->data[3] = (void *)(size_t) surface;
|
||
frame->buf[0] = av_buffer_create((uint8_t*)(size_t)surface, 0, Codec_free_buffer, video_ctx, 0);
|
||
frame->data[0] = frame->buf[0]->data;
|
||
frame->data[3] = frame->data[0];
|
||
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52,66,100)
|
||
// reordered frames
|
||
... | ... | |
return 0;
|
||
}
|
||
//Debug(3, "codec: fallback to default get_buffer\n");
|
||
return avcodec_default_get_buffer(video_ctx, frame);
|
||
return avcodec_default_get_buffer2(video_ctx, frame, flags);
|
||
}
|
||
/**
|
||
** Video buffer management, release buffer for frame.
|
||
** Called to release buffers which were allocated with get_buffer.
|
||
**
|
||
** @param video_ctx Codec context
|
||
** @param frame Release buffer for this frame
|
||
** @param opaque opaque data
|
||
** @param data buffer data
|
||
*/
|
||
static void Codec_release_buffer(AVCodecContext * video_ctx, AVFrame * frame)
|
||
static void Codec_free_buffer(void *opaque, uint8_t *data)
|
||
{
|
||
AVCodecContext *video_ctx = (AVCodecContext *)opaque;
|
||
#ifdef USE_VDPAU
|
||
// VDPAU: PIX_FMT_VDPAU_H264 .. PIX_FMT_VDPAU_VC1 PIX_FMT_VDPAU_MPEG4
|
||
if ((PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == PIX_FMT_VDPAU_MPEG4) {
|
||
// VDPAU: AV_PIX_FMT_VDPAU_H264 .. AV_PIX_FMT_VDPAU_VC1 AV_PIX_FMT_VDPAU_MPEG4
|
||
if ((AV_PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= AV_PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG4) {
|
||
VideoDecoder *decoder;
|
||
struct vdpau_render_state *vrs;
|
||
unsigned surface;
|
||
decoder = video_ctx->opaque;
|
||
vrs = (struct vdpau_render_state *)frame->data[0];
|
||
vrs = (struct vdpau_render_state *)data;
|
||
surface = vrs->surface;
|
||
//Debug(3, "codec: release surface %#010x\n", surface);
|
||
... | ... | |
av_freep(&vrs->bitstream_buffers);
|
||
vrs->bitstream_buffers_allocated = 0;
|
||
av_freep(&frame->data[0]);
|
||
av_freep(&data);
|
||
return;
|
||
}
|
||
... | ... | |
unsigned surface;
|
||
decoder = video_ctx->opaque;
|
||
surface = (unsigned)(size_t) frame->data[3];
|
||
surface = (unsigned)(size_t) data;
|
||
//Debug(3, "codec: release surface %#010x\n", surface);
|
||
VideoReleaseSurface(decoder->HwDecoder, surface);
|
||
frame->data[0] = NULL;
|
||
frame->data[3] = NULL;
|
||
return;
|
||
}
|
||
//Debug(3, "codec: fallback to default release_buffer\n");
|
||
return avcodec_default_release_buffer(video_ctx, frame);
|
||
}
|
||
/// libav: compatibility hack
|
||
... | ... | |
int height)
|
||
{
|
||
#ifdef USE_VDPAU
|
||
// VDPAU: PIX_FMT_VDPAU_H264 .. PIX_FMT_VDPAU_VC1 PIX_FMT_VDPAU_MPEG4
|
||
if ((PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == PIX_FMT_VDPAU_MPEG4) {
|
||
// VDPAU: AV_PIX_FMT_VDPAU_H264 .. AV_PIX_FMT_VDPAU_VC1 AV_PIX_FMT_VDPAU_MPEG4
|
||
if ((AV_PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= AV_PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG4) {
|
||
VideoDecoder *decoder;
|
||
struct vdpau_render_state *vrs;
|
||
... | ... | |
if (video_codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
|
||
// FIXME: get_format never called.
|
||
decoder->VideoCtx->get_format = Codec_get_format;
|
||
decoder->VideoCtx->get_buffer = Codec_get_buffer;
|
||
decoder->VideoCtx->release_buffer = Codec_release_buffer;
|
||
decoder->VideoCtx->reget_buffer = Codec_get_buffer;
|
||
decoder->VideoCtx->get_buffer2 = Codec_get_buffer2;
|
||
decoder->VideoCtx->draw_horiz_band = Codec_draw_horiz_band;
|
||
decoder->VideoCtx->slice_flags =
|
||
SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD;
|
||
... | ... | |
// our pixel format video hardware decoder hook
|
||
if (decoder->VideoCtx->hwaccel_context) {
|
||
decoder->VideoCtx->get_format = Codec_get_format;
|
||
decoder->VideoCtx->get_buffer = Codec_get_buffer;
|
||
decoder->VideoCtx->release_buffer = Codec_release_buffer;
|
||
decoder->VideoCtx->reget_buffer = Codec_get_buffer;
|
||
decoder->VideoCtx->get_buffer2 = Codec_get_buffer2;
|
||
#if 0
|
||
decoder->VideoCtx->thread_count = 1;
|
||
decoder->VideoCtx->draw_horiz_band = NULL;
|
||
... | ... | |
//
|
||
// Prepare frame buffer for decoder
|
||
//
|
||
if (!(decoder->Frame = avcodec_alloc_frame())) {
|
||
if (!(decoder->Frame = av_frame_alloc())) {
|
||
Fatal(_("codec: can't allocate decoder frame\n"));
|
||
}
|
||
// reset buggy ffmpeg/libav flag
|
||
... | ... | |
void CodecVideoClose(VideoDecoder * video_decoder)
|
||
{
|
||
// FIXME: play buffered data
|
||
av_freep(&video_decoder->Frame);
|
||
av_frame_free(&video_decoder->Frame);
|
||
if (video_decoder->VideoCtx) {
|
||
pthread_mutex_lock(&CodecLockMutex);
|
||
avcodec_close(video_decoder->VideoCtx);
|
||
... | ... | |
int HwSampleRate; ///< hw sample rate
|
||
int HwChannels; ///< hw channels
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1)
|
||
AVFrame *Frame; ///< decoded audio frame buffer
|
||
#endif
|
||
... | ... | |
if (!(audio_decoder = calloc(1, sizeof(*audio_decoder)))) {
|
||
Fatal(_("codec: can't allocate audio decoder\n"));
|
||
}
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1)
|
||
if (!(audio_decoder->Frame = av_frame_alloc())) {
|
||
Fatal(_("codec: can't allocate audio decoder frame buffer\n"));
|
||
}
|
||
... | ... | |
*/
|
||
void CodecAudioDelDecoder(AudioDecoder * decoder)
|
||
{
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58,28,1)
|
||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1)
|
||
av_frame_free(&decoder->Frame); // callee does checks
|
||
#endif
|
||
free(decoder);
|
||
... | ... | |
{
|
||
AVCodecContext *audio_ctx;
|
||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,28,1)
|
||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
|
||
AVFrame frame[1];
|
||
#else
|
||
AVFrame *frame;
|
||
... | ... | |
// FIXME: don't need to decode pass-through codecs
|
||
// new AVFrame API
|
||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58,28,1)
|
||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
|
||
avcodec_get_frame_defaults(frame);
|
||
#else
|
||
frame = audio_decoder->Frame;
|
||
av_frame_unref(frame);
|
||
#endif
|
||
av_frame_unref(frame);
|
||
got_frame = 0;
|
||
n = avcodec_decode_audio4(audio_ctx, frame, &got_frame,
|
||
-- vdr-plugin-softhddevice-0.6.0+git20150324.orig/video.c
|
||
++ vdr-plugin-softhddevice-0.6.0+git20150324/video.c
|
||
... | ... | |
void (*const DelHwDecoder) (VideoHwDecoder *);
|
||
unsigned (*const GetSurface) (VideoHwDecoder *, const AVCodecContext *);
|
||
void (*const ReleaseSurface) (VideoHwDecoder *, unsigned);
|
||
enum PixelFormat (*const get_format) (VideoHwDecoder *, AVCodecContext *,
|
||
const enum PixelFormat *);
|
||
enum AVPixelFormat (*const get_format) (VideoHwDecoder *, AVCodecContext *,
|
||
const enum AVPixelFormat *);
|
||
void (*const RenderFrame) (VideoHwDecoder *, const AVCodecContext *,
|
||
const AVFrame *);
|
||
void *(*const GetHwAccelContext)(VideoHwDecoder *);
|
||
... | ... | |
/// flags for put surface for different resolutions groups
|
||
unsigned SurfaceFlagsTable[VideoResolutionMax];
|
||
enum PixelFormat PixFmt; ///< ffmpeg frame pixfmt
|
||
enum AVPixelFormat PixFmt; ///< ffmpeg frame pixfmt
|
||
int WrongInterlacedWarned; ///< warning about interlace flag issued
|
||
int Interlaced; ///< ffmpeg interlaced flag
|
||
int TopFieldFirst; ///< ffmpeg top field displayed first
|
||
... | ... | |
decoder->OutputWidth = VideoWindowWidth;
|
||
decoder->OutputHeight = VideoWindowHeight;
|
||
decoder->PixFmt = PIX_FMT_NONE;
|
||
decoder->PixFmt = AV_PIX_FMT_NONE;
|
||
decoder->Stream = stream;
|
||
if (!VaapiDecoderN) { // FIXME: hack sync on audio
|
||
... | ... | |
/// FIXME: must check if put/get with this format is supported (see intel)
|
||
///
|
||
static int VaapiFindImageFormat(VaapiDecoder * decoder,
|
||
enum PixelFormat pix_fmt, VAImageFormat * format)
|
||
enum AVPixelFormat pix_fmt, VAImageFormat * format)
|
||
{
|
||
VAImageFormat *imgfrmts;
|
||
int imgfrmt_n;
|
||
... | ... | |
// NV12, YV12, I420, BGRA
|
||
// intel: I420 is native format for MPEG-2 decoded surfaces
|
||
// intel: NV12 is native format for H.264 decoded surfaces
|
||
case PIX_FMT_YUV420P:
|
||
case PIX_FMT_YUVJ420P:
|
||
case AV_PIX_FMT_YUV420P:
|
||
case AV_PIX_FMT_YUVJ420P:
|
||
// fourcc = VA_FOURCC_YV12; // YVU
|
||
fourcc = VA_FOURCC('I', '4', '2', '0'); // YUV
|
||
break;
|
||
case PIX_FMT_NV12:
|
||
case AV_PIX_FMT_NV12:
|
||
fourcc = VA_FOURCC_NV12;
|
||
break;
|
||
default:
|
||
... | ... | |
#endif
|
||
// FIXME: PixFmt not set!
|
||
//VaapiFindImageFormat(decoder, decoder->PixFmt, format);
|
||
VaapiFindImageFormat(decoder, PIX_FMT_NV12, format);
|
||
VaapiFindImageFormat(decoder, AV_PIX_FMT_NV12, format);
|
||
// FIXME: this image is only needed for software decoder and auto-crop
|
||
if (decoder->GetPutImage
|
||
... | ... | |
}
|
||
///
|
||
/// Callback to negotiate the PixelFormat.
|
||
/// Callback to negotiate the AVPixelFormat.
|
||
///
|
||
/// @param fmt is the list of formats which are supported by the codec,
|
||
/// it is terminated by -1 as 0 is a valid format, the
|
||
... | ... | |
///
|
||
/// @note + 2 surface for software deinterlace
|
||
///
|
||
static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
|
||
AVCodecContext * video_ctx, const enum PixelFormat *fmt)
|
||
static enum AVPixelFormat Vaapi_get_format(VaapiDecoder * decoder,
|
||
AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
||
{
|
||
const enum PixelFormat *fmt_idx;
|
||
const enum AVPixelFormat *fmt_idx;
|
||
VAProfile profiles[vaMaxNumProfiles(VaDisplay)];
|
||
int profile_n;
|
||
VAEntrypoint entrypoints[vaMaxNumEntrypoints(VaDisplay)];
|
||
... | ... | |
}
|
||
Debug(3, "codec: %d entrypoints\n", entrypoint_n);
|
||
// look through formats
|
||
for (fmt_idx = fmt; *fmt_idx != PIX_FMT_NONE; fmt_idx++) {
|
||
Debug(3, "\t%#010x %s\n", *fmt_idx, av_get_pix_fmt_name(*fmt_idx));
|
||
for (fmt_idx = fmt; *fmt_idx != AV_PIX_FMT_NONE; fmt_idx++) {
|
||
Debug(3, "\t%#010x %s\n", *fmt_idx, av_get_AV_PIX_FMT_name(*fmt_idx));
|
||
// check supported pixel format with entry point
|
||
switch (*fmt_idx) {
|
||
case PIX_FMT_VAAPI_VLD:
|
||
case AV_PIX_FMT_VAAPI_VLD:
|
||
e = VaapiFindEntrypoint(entrypoints, entrypoint_n,
|
||
VAEntrypointVLD);
|
||
break;
|
||
case PIX_FMT_VAAPI_MOCO:
|
||
case PIX_FMT_VAAPI_IDCT:
|
||
case AV_PIX_FMT_VAAPI_MOCO:
|
||
case AV_PIX_FMT_VAAPI_IDCT:
|
||
Debug(3, "codec: this VA-API pixel format is not supported\n");
|
||
default:
|
||
continue;
|
||
... | ... | |
}
|
||
#endif
|
||
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_pix_fmt_name(fmt_idx[0]));
|
||
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_AV_PIX_FMT_name(fmt_idx[0]));
|
||
return *fmt_idx;
|
||
slow_path:
|
||
... | ... | |
decoder->Entrypoint = VA_INVALID_ID;
|
||
decoder->VaapiContext->config_id = VA_INVALID_ID;
|
||
decoder->SurfacesNeeded = VIDEO_SURFACES_MAX + 2;
|
||
decoder->PixFmt = PIX_FMT_NONE;
|
||
decoder->PixFmt = AV_PIX_FMT_NONE;
|
||
decoder->InputWidth = 0;
|
||
decoder->InputHeight = 0;
|
||
... | ... | |
// FIXME: PixFmt not set!
|
||
//VaapiFindImageFormat(decoder, decoder->PixFmt, format);
|
||
VaapiFindImageFormat(decoder, PIX_FMT_NV12, format);
|
||
//VaapiFindImageFormat(decoder, PIX_FMT_YUV420P, format);
|
||
VaapiFindImageFormat(decoder, AV_PIX_FMT_NV12, format);
|
||
//VaapiFindImageFormat(decoder, AV_PIX_FMT_YUV420P, format);
|
||
if (vaCreateImage(VaDisplay, format, width, height,
|
||
decoder->Image) != VA_STATUS_SUCCESS) {
|
||
Error(_("video/vaapi: can't create image!\n"));
|
||
... | ... | |
if (decoder->Image->image_id == VA_INVALID_ID) {
|
||
VAImageFormat format[1];
|
||
VaapiFindImageFormat(decoder, PIX_FMT_NV12, format);
|
||
VaapiFindImageFormat(decoder, AV_PIX_FMT_NV12, format);
|
||
status =
|
||
vaCreateImage(VaDisplay, format, VideoWindowWidth,
|
||
VideoWindowHeight, decoder->Image);
|
||
... | ... | |
// I420 Y U V 2x2
|
||
// Intel needs NV12
|
||
VaapiFindImageFormat(decoder, PIX_FMT_NV12, format);
|
||
//VaapiFindImageFormat(decoder, PIX_FMT_YUV420P, format);
|
||
VaapiFindImageFormat(decoder, AV_PIX_FMT_NV12, format);
|
||
//VaapiFindImageFormat(decoder, AV_PIX_FMT_YUV420P, format);
|
||
for (i = 0; i < 5; ++i) {
|
||
if (vaCreateImage(decoder->VaDisplay, format, decoder->InputWidth,
|
||
decoder->InputHeight,
|
||
... | ... | |
if (decoder->Image->image_id == VA_INVALID_ID) {
|
||
VAImageFormat format[1];
|
||
VaapiFindImageFormat(decoder, PIX_FMT_NV12, format);
|
||
VaapiFindImageFormat(decoder, AV_PIX_FMT_NV12, format);
|
||
if (vaCreateImage(VaDisplay, format, decoder->InputWidth,
|
||
decoder->InputHeight, decoder->Image) != VA_STATUS_SUCCESS) {
|
||
Error(_("video/vaapi: can't create image!\n"));
|
||
... | ... | |
const AVCodecContext *))VaapiGetSurface,
|
||
.ReleaseSurface =
|
||
(void (*const) (VideoHwDecoder *, unsigned))VaapiReleaseSurface,
|
||
.get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum PixelFormat *))Vaapi_get_format,
|
||
.get_format = (enum AVPixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum AVPixelFormat *))Vaapi_get_format,
|
||
.RenderFrame = (void (*const) (VideoHwDecoder *,
|
||
const AVCodecContext *, const AVFrame *))VaapiSyncRenderFrame,
|
||
.GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
|
||
... | ... | |
const AVCodecContext *))VaapiGetSurface,
|
||
.ReleaseSurface =
|
||
(void (*const) (VideoHwDecoder *, unsigned))VaapiReleaseSurface,
|
||
.get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum PixelFormat *))Vaapi_get_format,
|
||
.get_format = (enum AVPixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum AVPixelFormat *))Vaapi_get_format,
|
||
.RenderFrame = (void (*const) (VideoHwDecoder *,
|
||
const AVCodecContext *, const AVFrame *))VaapiSyncRenderFrame,
|
||
.GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
|
||
... | ... | |
int OutputWidth; ///< real video output width
|
||
int OutputHeight; ///< real video output height
|
||
enum PixelFormat PixFmt; ///< ffmpeg frame pixfmt
|
||
enum AVPixelFormat PixFmt; ///< ffmpeg frame pixfmt
|
||
int WrongInterlacedWarned; ///< warning about interlace flag issued
|
||
int Interlaced; ///< ffmpeg interlaced flag
|
||
int TopFieldFirst; ///< ffmpeg top field displayed first
|
||
... | ... | |
decoder->OutputWidth = VideoWindowWidth;
|
||
decoder->OutputHeight = VideoWindowHeight;
|
||
decoder->PixFmt = PIX_FMT_NONE;
|
||
decoder->PixFmt = AV_PIX_FMT_NONE;
|
||
#ifdef USE_AUTOCROP
|
||
//decoder->AutoCropBuffer = NULL; // done by calloc
|
||
... | ... | |
}
|
||
///
|
||
/// Callback to negotiate the PixelFormat.
|
||
/// Callback to negotiate the AVPixelFormat.
|
||
///
|
||
/// @param fmt is the list of formats which are supported by the codec,
|
||
/// it is terminated by -1 as 0 is a valid format, the
|
||
/// formats are ordered by quality.
|
||
///
|
||
static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
|
||
AVCodecContext * video_ctx, const enum PixelFormat *fmt)
|
||
static enum AVPixelFormat Vdpau_get_format(VdpauDecoder * decoder,
|
||
AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
||
{
|
||
const enum PixelFormat *fmt_idx;
|
||
const enum AVPixelFormat *fmt_idx;
|
||
VdpDecoderProfile profile;
|
||
int max_refs;
|
||
... | ... | |
// look through formats
|
||
//
|
||
Debug(3, "%s: codec %d fmts:\n", __FUNCTION__, video_ctx->codec_id);
|
||
for (fmt_idx = fmt; *fmt_idx != PIX_FMT_NONE; fmt_idx++) {
|
||
Debug(3, "\t%#010x %s\n", *fmt_idx, av_get_pix_fmt_name(*fmt_idx));
|
||
for (fmt_idx = fmt; *fmt_idx != AV_PIX_FMT_NONE; fmt_idx++) {
|
||
Debug(3, "\t%#010x %s\n", *fmt_idx, av_get_AV_PIX_FMT_name(*fmt_idx));
|
||
// check supported pixel format with entry point
|
||
switch (*fmt_idx) {
|
||
case PIX_FMT_VDPAU_H264:
|
||
case PIX_FMT_VDPAU_MPEG1:
|
||
case PIX_FMT_VDPAU_MPEG2:
|
||
case PIX_FMT_VDPAU_WMV3:
|
||
case PIX_FMT_VDPAU_VC1:
|
||
case PIX_FMT_VDPAU_MPEG4:
|
||
case AV_PIX_FMT_VDPAU_H264:
|
||
case AV_PIX_FMT_VDPAU_MPEG1:
|
||
case AV_PIX_FMT_VDPAU_MPEG2:
|
||
case AV_PIX_FMT_VDPAU_WMV3:
|
||
case AV_PIX_FMT_VDPAU_VC1:
|
||
case AV_PIX_FMT_VDPAU_MPEG4:
|
||
break;
|
||
default:
|
||
continue;
|
||
... | ... | |
break;
|
||
}
|
||
if (*fmt_idx == PIX_FMT_NONE) {
|
||
if (*fmt_idx == AV_PIX_FMT_NONE) {
|
||
Error(_("video/vdpau: no valid vdpau pixfmt found\n"));
|
||
goto slow_path;
|
||
}
|
||
... | ... | |
}
|
||
#endif
|
||
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_pix_fmt_name(fmt_idx[0]));
|
||
Debug(3, "\t%#010x %s\n", fmt_idx[0], av_get_AV_PIX_FMT_name(fmt_idx[0]));
|
||
return *fmt_idx;
|
||
slow_path:
|
||
// no accelerated format found
|
||
decoder->Profile = VDP_INVALID_HANDLE;
|
||
decoder->SurfacesNeeded = VIDEO_SURFACES_MAX + 2;
|
||
decoder->PixFmt = PIX_FMT_NONE;
|
||
decoder->PixFmt = AV_PIX_FMT_NONE;
|
||
decoder->InputWidth = 0;
|
||
decoder->InputHeight = 0;
|
||
... | ... | |
//
|
||
// Hardware render
|
||
//
|
||
// VDPAU: PIX_FMT_VDPAU_H264 .. PIX_FMT_VDPAU_VC1 PIX_FMT_VDPAU_MPEG4
|
||
if ((PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == PIX_FMT_VDPAU_MPEG4) {
|
||
// VDPAU: AV_PIX_FMT_VDPAU_H264 .. AV_PIX_FMT_VDPAU_VC1 AV_PIX_FMT_VDPAU_MPEG4
|
||
if ((AV_PIX_FMT_VDPAU_H264 <= video_ctx->pix_fmt
|
||
&& video_ctx->pix_fmt <= AV_PIX_FMT_VDPAU_VC1)
|
||
|| video_ctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG4) {
|
||
struct vdpau_render_state *vrs;
|
||
vrs = (struct vdpau_render_state *)frame->data[0];
|
||
... | ... | |
// Copy data from frame to image
|
||
//
|
||
switch (video_ctx->pix_fmt) {
|
||
case PIX_FMT_YUV420P:
|
||
case PIX_FMT_YUVJ420P: // some streams produce this
|
||
case AV_PIX_FMT_YUV420P:
|
||
case AV_PIX_FMT_YUVJ420P: // some streams produce this
|
||
break;
|
||
case PIX_FMT_YUV422P:
|
||
case PIX_FMT_YUV444P:
|
||
case AV_PIX_FMT_YUV422P:
|
||
case AV_PIX_FMT_YUV444P:
|
||
default:
|
||
Fatal(_("video/vdpau: pixel format %d not supported\n"),
|
||
video_ctx->pix_fmt);
|
||
... | ... | |
const AVCodecContext *))VdpauGetSurface,
|
||
.ReleaseSurface =
|
||
(void (*const) (VideoHwDecoder *, unsigned))VdpauReleaseSurface,
|
||
.get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum PixelFormat *))Vdpau_get_format,
|
||
.get_format = (enum AVPixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum AVPixelFormat *))Vdpau_get_format,
|
||
.RenderFrame = (void (*const) (VideoHwDecoder *,
|
||
const AVCodecContext *, const AVFrame *))VdpauSyncRenderFrame,
|
||
.GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
|
||
... | ... | |
#endif
|
||
.ReleaseSurface = NoopReleaseSurface,
|
||
#if 0
|
||
.get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum PixelFormat *))Noop_get_format,
|
||
.get_format = (enum AVPixelFormat(*const) (VideoHwDecoder *,
|
||
AVCodecContext *, const enum AVPixelFormat *))Noop_get_format,
|
||
.RenderFrame = (void (*const) (VideoHwDecoder *,
|
||
const AVCodecContext *, const AVFrame *))NoopSyncRenderFrame,
|
||
.GetHwAccelContext = (void *(*const)(VideoHwDecoder *))
|
||
... | ... | |
case MapNotify:
|
||
Debug(3, "video/event: MapNotify\n");
|
||
// ?wm workaround
|
||
// \B5wm workaround
|
||
VideoThreadLock();
|
||
xcb_change_window_attributes(Connection, VideoWindow,
|
||
XCB_CW_CURSOR, &VideoBlankCursor);
|
||
... | ... | |
}
|
||
///
|
||
/// Callback to negotiate the PixelFormat.
|
||
/// Callback to negotiate the AVPixelFormat.
|
||
///
|
||
/// @param hw_decoder video hardware decoder
|
||
/// @param video_ctx ffmpeg video codec context
|
||
... | ... | |
/// valid format, the formats are ordered by
|
||
/// quality.
|
||
///
|
||
enum PixelFormat Video_get_format(VideoHwDecoder * hw_decoder,
|
||
AVCodecContext * video_ctx, const enum PixelFormat *fmt)
|
||
enum AVPixelFormat Video_get_format(VideoHwDecoder * hw_decoder,
|
||
AVCodecContext * video_ctx, const enum AVPixelFormat *fmt)
|
||
{
|
||
#ifdef DEBUG
|
||
int ms_delay;
|
||
-- vdr-plugin-softhddevice-0.6.0+git20150324.orig/video.h
|
||
++ vdr-plugin-softhddevice-0.6.0+git20150324/video.h
|
||
... | ... | |
/// Release a video hardware surface
|
||
extern void VideoReleaseSurface(VideoHwDecoder *, unsigned);
|
||
/// Callback to negotiate the PixelFormat.
|
||
extern enum PixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
||
const enum PixelFormat *);
|
||
/// Callback to negotiate the AVPixelFormat.
|
||
extern enum AVPixelFormat Video_get_format(VideoHwDecoder *, AVCodecContext *,
|
||
const enum AVPixelFormat *);
|
||
/// Render a ffmpeg frame.
|
||
extern void VideoRenderFrame(VideoHwDecoder *, const AVCodecContext *,
|