Project

General

Profile

Bug #2424 ยป ffmpeg_2.9.patch

marco, 06/28/2016 11:24 AM

View differences:

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;
-- a/video.c
++ b/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;
-- a/video.h
++ b/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 *,
    (1-1/1)