video.h (6380B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#ifndef GUACENC_VIDEO_H 21#define GUACENC_VIDEO_H 22 23#include "config.h" 24#include "buffer.h" 25 26#include <guacamole/timestamp.h> 27#include <libavcodec/avcodec.h> 28 29#ifndef AVCODEC_AVCODEC_H 30#include <libavcodec/avcodec.h> 31#endif 32 33#ifndef AVFORMAT_AVFORMAT_H 34#include <libavformat/avformat.h> 35#endif 36 37#include <stdint.h> 38#include <stdio.h> 39 40/** 41 * The framerate at which video should be encoded, in frames per second. 42 */ 43#define GUACENC_VIDEO_FRAMERATE 25 44 45/** 46 * A video which is actively being encoded. Frames can be added to the video 47 * as they are generated, along with their associated timestamps, and the 48 * corresponding video will be continuously written as it is encoded. 49 */ 50typedef struct guacenc_video { 51 52 /** 53 * AVStream for video output. 54 * Frames sent to this stream are written into 55 * the output file in the specified container format. 56 */ 57 AVStream* output_stream; 58 59 /** 60 * The open encoding context from libavcodec, created for the codec 61 * specified when this guacenc_video was created. 62 */ 63 AVCodecContext* context; 64 65 /** 66 * The open format context from libavformat, created for the file 67 * container specified when this guacenc_video was created. 68 */ 69 AVFormatContext* container_format_context; 70 71 /** 72 * The width of the video, in pixels. 73 */ 74 int width; 75 76 /** 77 * The height of the video, in pixels. 78 */ 79 int height; 80 81 /** 82 * The desired output bitrate of the video, in bits per second. 83 */ 84 int bitrate; 85 86 /** 87 * An image data area containing the next frame to be written, encoded as 88 * YCbCr image data in the format required by avcodec_encode_video2(), for 89 * use and re-use as frames are rendered. 90 */ 91 AVFrame* next_frame; 92 93 /** 94 * The presentation timestamp that should be used for the next frame. This 95 * is equivalent to the frame number. 96 */ 97 int64_t next_pts; 98 99 /** 100 * The timestamp associated with the last frame, or 0 if no frames have yet 101 * been added. 102 */ 103 guac_timestamp last_timestamp; 104 105} guacenc_video; 106 107/** 108 * Allocates a new guacenc_video which encodes video according to the given 109 * specifications, saving the output in the given file. If the output file 110 * already exists, encoding will be aborted, and the original file contents 111 * will be preserved. Frames will be scaled up or down as necessary to fit the 112 * given width and height. 113 * 114 * @param path 115 * The full path to the file in which encoded video should be written. 116 * 117 * @param codec_name 118 * The name of the codec to use for the video encoding, as defined by 119 * ffmpeg / libavcodec. 120 * 121 * @param width 122 * The width of the desired video, in pixels. 123 * 124 * @param height 125 * The height of the desired video, in pixels. 126 * 127 * @param bitrate 128 * The desired overall bitrate of the resulting encoded video, in bits per 129 * second. 130 */ 131guacenc_video* guacenc_video_alloc(const char* path, const char* codec_name, 132 int width, int height, int bitrate); 133 134/** 135 * Advances the timeline of the encoding process to the given timestamp, such 136 * that frames added via guacenc_video_prepare_frame() will be encoded at the 137 * proper frame boundaries within the video. Duplicate frames will be encoded 138 * as necessary to ensure that the output is correctly timed with respect to 139 * the given timestamp. This is particularly important as Guacamole does not 140 * have a framerate per se, and the time between each Guacamole "frame" will 141 * vary significantly. 142 * 143 * This function MUST be called prior to invoking guacenc_video_prepare_frame() 144 * to ensure the prepared frame will be encoded at the correct point in time. 145 * 146 * @param video 147 * The video whose timeline should be adjusted. 148 * 149 * @param timestamp 150 * The Guacamole timestamp denoting the point in time that the video 151 * timeline should be advanced to, as dictated by a parsed "sync" 152 * instruction. 153 * 154 * @return 155 * Zero if the timeline was adjusted successfully, non-zero if an error 156 * occurs (such as during the encoding of duplicate frames). 157 */ 158int guacenc_video_advance_timeline(guacenc_video* video, 159 guac_timestamp timestamp); 160 161/** 162 * Stores the given buffer within the given video structure such that it will 163 * be written if it falls within proper frame boundaries. If the timeline of 164 * the video (as dictated by guacenc_video_advance_timeline()) is not at a 165 * frame boundary with respect to the video framerate (it occurs between frame 166 * boundaries), the prepared frame will only be written if another frame is not 167 * prepared within the same pair of frame boundaries). The prepared frame will 168 * not be written until it is implicitly flushed through updates to the video 169 * timeline or through reaching the end of the encoding process 170 * (guacenc_video_free()). 171 * 172 * @param video 173 * The video in which the given buffer should be queued for possible 174 * writing (depending on timing vs. video framerate). 175 * 176 * @param buffer 177 * The guacenc_buffer representing the image data of the frame that should 178 * be queued. 179 */ 180void guacenc_video_prepare_frame(guacenc_video* video, guacenc_buffer* buffer); 181 182/** 183 * Frees all resources associated with the given video, finalizing the encoding 184 * process. Any buffered frames which have not yet been written will be written 185 * at this point. 186 * 187 * @return 188 * Zero if the video was successfully written and freed, non-zero if the 189 * video could not be written due to an error. 190 */ 191int guacenc_video_free(guacenc_video* video); 192 193#endif 194