36 #include <mfx/mfxvideo.h> 39 #include <va/va_x11.h> 63 static mfxStatus
frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
64 mfxFrameAllocResponse *resp)
70 fprintf(stderr,
"Multiple allocation requests.\n");
71 return MFX_ERR_MEMORY_ALLOC;
73 if (!(req->Type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)) {
74 fprintf(stderr,
"Unsupported surface type: %d\n", req->Type);
75 return MFX_ERR_UNSUPPORTED;
77 if (req->Info.BitDepthLuma != 8 || req->Info.BitDepthChroma != 8 ||
78 req->Info.Shift || req->Info.FourCC != MFX_FOURCC_NV12 ||
79 req->Info.ChromaFormat != MFX_CHROMAFORMAT_YUV420) {
80 fprintf(stderr,
"Unsupported surface properties.\n");
81 return MFX_ERR_UNSUPPORTED;
90 err = vaCreateSurfaces(decode->
va_dpy, VA_RT_FORMAT_YUV420,
91 req->Info.Width, req->Info.Height,
92 decode->
surfaces, req->NumFrameSuggested,
94 if (err != VA_STATUS_SUCCESS) {
95 fprintf(stderr,
"Error allocating VA surfaces\n");
114 return MFX_ERR_MEMORY_ALLOC;
117 static mfxStatus
frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
122 static mfxStatus
frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
124 return MFX_ERR_UNSUPPORTED;
127 static mfxStatus
frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
129 return MFX_ERR_UNSUPPORTED;
159 mfxFrameSurface1 *surf;
168 fprintf(stderr,
"No free surfaces\n");
183 surf->Data.MemId = &decode->
surfaces[idx];
185 frame->
buf[0] = surf_buf;
204 qsv->
iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
215 fprintf(stderr,
"The QSV pixel format not offered in get_format()\n");
227 while (pkt->
size > 0 || (!pkt->
data && got_frame)) {
230 fprintf(stderr,
"Error during decoding\n");
241 mfxFrameSurface1 *surf = (mfxFrameSurface1*)frame->
data[3];
242 VASurfaceID surface = *(VASurfaceID*)surf->Data.MemId;
244 VAImageFormat img_fmt = {
245 .fourcc = VA_FOURCC_NV12,
246 .byte_order = VA_LSB_FIRST,
257 img.buf = VA_INVALID_ID;
258 img.image_id = VA_INVALID_ID;
260 err = vaCreateImage(decode->
va_dpy, &img_fmt,
262 if (err != VA_STATUS_SUCCESS) {
263 fprintf(stderr,
"Error creating an image: %s\n",
269 err = vaGetImage(decode->
va_dpy, surface, 0, 0,
272 if (err != VA_STATUS_SUCCESS) {
273 fprintf(stderr,
"Error getting an image: %s\n",
279 err = vaMapBuffer(decode->
va_dpy, img.buf, (
void**)&data);
280 if (err != VA_STATUS_SUCCESS) {
281 fprintf(stderr,
"Error mapping the image buffer: %s\n",
287 for (i = 0; i < img.num_planes; i++)
288 for (j = 0; j < (img.height >> (i > 0)); j++)
289 avio_write(output_ctx, data + img.offsets[i] + j * img.pitches[i], img.width);
292 if (img.buf != VA_INVALID_ID)
293 vaUnmapBuffer(decode->
va_dpy, img.buf);
294 if (img.image_id != VA_INVALID_ID)
295 vaDestroyImage(decode->
va_dpy, img.image_id);
306 int main(
int argc,
char **argv)
319 int va_ver_major, va_ver_minor;
321 mfxIMPL mfx_impl = MFX_IMPL_AUTO_ANY;
322 mfxVersion mfx_ver = { { 1, 1 } };
324 mfxFrameAllocator frame_allocator = {
340 fprintf(stderr,
"Usage: %s <input file> <output file>\n", argv[0]);
347 fprintf(stderr,
"Cannot open input file '%s': ", argv[1]);
361 fprintf(stderr,
"No H.264 video stream in the input file\n");
366 dpy = XOpenDisplay(
NULL);
368 fprintf(stderr,
"Cannot open the X display\n");
371 decode.
va_dpy = vaGetDisplay(dpy);
373 fprintf(stderr,
"Cannot open the VA display\n");
377 err = vaInitialize(decode.
va_dpy, &va_ver_major, &va_ver_minor);
378 if (err != VA_STATUS_SUCCESS) {
379 fprintf(stderr,
"Cannot initialize VA: %s\n", vaErrorStr(err));
382 fprintf(stderr,
"Initialized VA v%d.%d\n", va_ver_major, va_ver_minor);
385 err = MFXInit(mfx_impl, &mfx_ver, &decode.
mfx_session);
386 if (err != MFX_ERR_NONE) {
387 fprintf(stderr,
"Error initializing an MFX session\n");
391 MFXVideoCORE_SetHandle(decode.
mfx_session, MFX_HANDLE_VA_DISPLAY, decode.
va_dpy);
392 MFXVideoCORE_SetFrameAllocator(decode.
mfx_session, &frame_allocator);
397 fprintf(stderr,
"The QSV decoder is not present in libavcodec\n");
426 fprintf(stderr,
"Error opening the decoder: ");
433 fprintf(stderr,
"Error opening the output context: ");
450 ret =
decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
458 ret =
decode_packet(&decode, decoder_ctx, frame, &pkt, output_ctx);
464 fprintf(stderr,
"%s\n", buf);
480 vaTerminate(decode.
va_dpy);
int avio_open(AVIOContext **s, const char *url, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
enum AVPixelFormat(* get_format)(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
callback to negotiate the pixelFormat
This structure describes decoded (raw) audio or video data.
memory handling functions
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int index
stream index in AVFormatContext
#define AVIO_FLAG_WRITE
write-only
static mfxStatus frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
static mfxStatus frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
void * hwaccel_context
Hardware accelerator context.
static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream ** streams
A list of all streams in the file.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
static mfxStatus frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
int width
width and height of the video frame
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
int main(int argc, char **argv)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
int iopattern
The IO pattern to use.
int extradata_size
Size of the extradata content in bytes.
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
static const chunk_decoder decoder[8]
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
int refcounted_frames
If non-zero, the decoded audio and video frames returned from avcodec_decode_video2() and avcodec_dec...
Libavcodec external API header.
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer...
main external API structure.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
int(* get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags)
This callback is called at the beginning of each frame to get data buffer(s) for it.
AVQSVContext * av_qsv_alloc_context(void)
Allocate a new context.
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
static int get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
This struct is used for communicating QSV parameters between libavcodec and the caller.
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
static enum AVPixelFormat pix_fmts[]
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
static int decode_packet(DecodeContext *decode, AVCodecContext *decoder_ctx, AVFrame *frame, AVPacket *pkt, AVIOContext *output_ctx)
AVCodec * avcodec_find_decoder_by_name(const char *name)
Find a registered decoder with the specified name.
static void * av_malloc_array(size_t nmemb, size_t size)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
A reference to a data buffer.
static void free_buffer(void *opaque, uint8_t *data)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
static void free_surfaces(DecodeContext *decode)
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
static void * av_mallocz_array(size_t nmemb, size_t size)
static mfxStatus frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
AVCodecParameters * codecpar
attribute_deprecated int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)
Decode the video frame of size avpkt->size from avpkt->data into picture.
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
AVPixelFormat
Pixel format.
This structure stores compressed data.
void av_register_all(void)
Initialize libavformat and register all the muxers, demuxers and protocols.
mfxSession session
If non-NULL, the session to use for encoding or decoding.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
void * opaque
Private data of the user, can be used to carry app specific stuff.