This example shows how to do VAAPI-accelerated encoding.
This example shows how to do VAAPI-accelerated encoding. now only support NV12 raw file, usage like: vaapi_encode 1920 1080 input.yuv output.h264
#include <stdio.h>
#include <string.h>
#include <errno.h>
{
int err = 0;
fprintf(stderr, "Failed to create VAAPI frame context.\n");
return -1;
}
fprintf(stderr, "Failed to initialize VAAPI frame context."
return err;
}
return err;
}
{
int ret = 0;
fprintf(stderr,
"Error code: %s\n",
av_err2str(ret));
goto end;
}
while (1) {
if (ret)
break;
ret = fwrite(enc_pkt->
data, enc_pkt->
size, 1, fout);
if (ret != enc_pkt->
size) {
break;
}
}
end:
ret = ((ret ==
AVERROR(EAGAIN)) ? 0 : -1);
return ret;
}
int main(
int argc,
char *argv[])
{
int size, err;
FILE *fin = NULL, *fout = NULL;
AVFrame *sw_frame = NULL, *hw_frame = NULL;
const char *enc_name = "h264_vaapi";
if (argc < 5) {
fprintf(stderr, "Usage: %s <width> <height> <input file> <output file>\n", argv[0]);
return -1;
}
if (!(fin = fopen(argv[3], "r"))) {
fprintf(stderr, "Fail to open input file : %s\n", strerror(errno));
return -1;
}
if (!(fout = fopen(argv[4], "w+b"))) {
fprintf(stderr, "Fail to open output file : %s\n", strerror(errno));
err = -1;
goto close;
}
NULL, NULL, 0);
if (err < 0) {
fprintf(stderr,
"Failed to create a VAAPI device. Error code: %s\n",
av_err2str(err));
goto close;
}
fprintf(stderr, "Could not find encoder.\n");
err = -1;
goto close;
}
goto close;
}
fprintf(stderr, "Failed to set hwframe context.\n");
goto close;
}
fprintf(stderr,
"Cannot open video encoder codec. Error code: %s\n",
av_err2str(err));
goto close;
}
while (1) {
goto close;
}
goto close;
if ((err = fread((uint8_t*)(sw_frame->
data[0]), size, 1, fin)) <= 0)
break;
if ((err = fread((uint8_t*)(sw_frame->
data[1]), size/2, 1, fin)) <= 0)
break;
goto close;
}
fprintf(stderr,
"Error code: %s.\n",
av_err2str(err));
goto close;
}
if (!hw_frame->hw_frames_ctx) {
goto close;
}
fprintf(stderr, "Error while transferring frame data to surface."
goto close;
}
fprintf(stderr, "Failed to encode.\n");
goto close;
}
}
err = 0;
close:
if (fin)
fclose(fin);
if (fout)
fclose(fout);
return err;
}
Libavcodec external API header.
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
const AVCodec * avcodec_find_encoder_by_name(const char *name)
Find a registered encoder with the specified name.
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Read encoded data from the encoder.
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Supply a raw video or audio frame to the encoder.
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_EOF
End of file.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ctx)
Allocate an AVHWFramesContext tied to a given device context.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
A reference to a data buffer.
uint8_t * data
The data buffer.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
This struct describes a set or pool of "hardware" frames (i.e.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
int initial_pool_size
Initial size of the frame pool.
int width
The allocated dimensions of the frames in this pool.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
static AVBufferRef * hw_device_ctx
int main(int argc, char *argv[])
static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
static int set_hwframe_ctx(AVCodecContext *ctx, AVBufferRef *hw_device_ctx)