GUAC-236: Allocate and maintain frame data for encoding.
This commit is contained in:
parent
9a5b503da5
commit
9eddaeee3d
@ -26,6 +26,8 @@
|
|||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavutil/common.h>
|
||||||
|
#include <libavutil/imgutils.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/timestamp.h>
|
#include <guacamole/timestamp.h>
|
||||||
|
|
||||||
@ -64,19 +66,35 @@ guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name,
|
|||||||
/* Open codec for use */
|
/* Open codec for use */
|
||||||
if (avcodec_open2(context, codec, NULL) < 0) {
|
if (avcodec_open2(context, codec, NULL) < 0) {
|
||||||
guacenc_log(GUAC_LOG_ERROR, "Failed to open codec \"%s\".", codec_name);
|
guacenc_log(GUAC_LOG_ERROR, "Failed to open codec \"%s\".", codec_name);
|
||||||
avcodec_free_context(&context);
|
goto fail_context;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
/* Allocate corresponding frame */
|
||||||
|
AVFrame* frame = av_frame_alloc();
|
||||||
|
if (frame == NULL) {
|
||||||
|
goto fail_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy necessary data for frame from context */
|
||||||
|
frame->format = context->pix_fmt;
|
||||||
|
frame->width = context->width;
|
||||||
|
frame->height = context->height;
|
||||||
|
|
||||||
|
/* Allocate actual backing data for frame */
|
||||||
|
if (av_image_alloc(frame->data, frame->linesize, frame->width,
|
||||||
|
frame->height, frame->format, 32) < 0) {
|
||||||
|
goto fail_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate video structure */
|
/* Allocate video structure */
|
||||||
guacenc_video* video = malloc(sizeof(guacenc_video));
|
guacenc_video* video = malloc(sizeof(guacenc_video));
|
||||||
if (video == NULL) {
|
if (video == NULL) {
|
||||||
avcodec_free_context(&context);
|
goto fail_frame_data;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init properties of video */
|
/* Init properties of video */
|
||||||
video->context = context;
|
video->context = context;
|
||||||
|
video->frame = frame;
|
||||||
video->width = width;
|
video->width = width;
|
||||||
video->height = height;
|
video->height = height;
|
||||||
video->frame_duration = 1000 / framerate;
|
video->frame_duration = 1000 / framerate;
|
||||||
@ -89,6 +107,17 @@ guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name,
|
|||||||
|
|
||||||
return video;
|
return video;
|
||||||
|
|
||||||
|
/* Free all allocated data in case of failure */
|
||||||
|
fail_frame_data:
|
||||||
|
av_freep(&frame->data[0]);
|
||||||
|
|
||||||
|
fail_frame:
|
||||||
|
av_frame_free(&frame);
|
||||||
|
|
||||||
|
fail_context:
|
||||||
|
avcodec_free_context(&context);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,6 +138,14 @@ static int guacenc_video_flush_frame(guacenc_video* video) {
|
|||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Init video packet */
|
||||||
|
AVPacket packet;
|
||||||
|
av_init_packet(&packet);
|
||||||
|
|
||||||
|
/* Request that encoder allocate data for packet */
|
||||||
|
packet.data = NULL;
|
||||||
|
packet.size = 0;
|
||||||
|
|
||||||
/* STUB: Write frame to video */
|
/* STUB: Write frame to video */
|
||||||
guacenc_log(GUAC_LOG_DEBUG, "Writing frame @ %" PRId64 "ms",
|
guacenc_log(GUAC_LOG_DEBUG, "Writing frame @ %" PRId64 "ms",
|
||||||
video->current_time);
|
video->current_time);
|
||||||
@ -160,6 +197,10 @@ int guacenc_video_free(guacenc_video* video) {
|
|||||||
/* Write final frame */
|
/* Write final frame */
|
||||||
guacenc_video_flush_frame(video);
|
guacenc_video_flush_frame(video);
|
||||||
|
|
||||||
|
/* Free frame encoding data */
|
||||||
|
av_freep(&video->frame->data[0]);
|
||||||
|
av_frame_free(&video->frame);
|
||||||
|
|
||||||
/* Clean up encoding context */
|
/* Clean up encoding context */
|
||||||
avcodec_close(video->context);
|
avcodec_close(video->context);
|
||||||
avcodec_free_context(&(video->context));
|
avcodec_free_context(&(video->context));
|
||||||
|
@ -42,6 +42,12 @@ typedef struct guacenc_video {
|
|||||||
*/
|
*/
|
||||||
AVCodecContext* context;
|
AVCodecContext* context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An image data area, containing YCbCr image data in the format required
|
||||||
|
* by avcodec_encode_video2(), for use and re-use as frames are rendered.
|
||||||
|
*/
|
||||||
|
AVFrame* frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the video, in pixels.
|
* The width of the video, in pixels.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user