diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/libtc/tcframes.h')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/libtc/tcframes.h | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/libtc/tcframes.h b/debian/transcode/transcode-1.1.7/libtc/tcframes.h new file mode 100644 index 00000000..0d8f4dfa --- /dev/null +++ b/debian/transcode/transcode-1.1.7/libtc/tcframes.h @@ -0,0 +1,491 @@ +/* + * tcframes.h -- common generic audio/video/whatever frame allocation/disposal + * routines for transcode. + * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com> + * + * This file is part of transcode, a video stream processing tool. + * + * transcode is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * transcode is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef TCFRAMES_H +#define TCFRAMES_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdarg.h> +#include <stdint.h> +#include <sys/types.h> + +#include "libtc/libtc.h" +#include "libtc/tctimer.h" +#include "libtc/tccodecs.h" + + +/*************************************************************************/ + +/* frame attributes */ +typedef enum tcframeattributes_ TCFrameAttributes; +enum tcframeattributes_ { + TC_FRAME_IS_KEYFRAME = 1, + TC_FRAME_IS_INTERLACED = 2, + TC_FRAME_IS_BROKEN = 4, + TC_FRAME_IS_SKIPPED = 8, + TC_FRAME_IS_CLONED = 16, + TC_FRAME_WAS_CLONED = 32, + TC_FRAME_IS_OUT_OF_RANGE = 64, + TC_FRAME_IS_DELAYED = 128, + TC_FRAME_IS_END_OF_STREAM = 256, +}; + +#define TC_FRAME_NEED_PROCESSING(PTR) \ + (!((PTR)->attributes & TC_FRAME_IS_OUT_OF_RANGE) \ + && !((PTR)->attributes & TC_FRAME_IS_END_OF_STREAM)) + +typedef enum tcframestatus_ TCFrameStatus; +enum tcframestatus_ { + TC_FRAME_NULL = -1, /* on the frame pool, not yet claimed */ + TC_FRAME_EMPTY = 0, /* claimed and being filled by decoder */ + TC_FRAME_WAIT, /* needs further processing (filtering) */ + TC_FRAME_LOCKED, /* being procedded by filter layer */ + TC_FRAME_READY, /* ready to be processed by encoder */ +}; + +/* + * frame status transitions scheme (overview) + * + * + * .-------<----- +-------<------+------<------+-------<-------. + * | ^ ^ ^ ^ + * V | | | | + * FRAME_NULL -> FRAME_EMPTY -> FRAME_WAIT -> FRAME_LOCKED -> FRAME_READY + * :_buffer_: \_decoder_/ \______filter_stage______/ \encoder_%/ + * \__pool__/ | : ^ : + * | \_______________encoder $__________|____/ + * V ^ + * `-------------->------------->---------------' + * + * Notes: + * % - regular case, frame (processing) threads avalaibles + * $ - practical (default) case, filtering is carried by encoder thread. + */ + +/*************************************************************************/ + +/* + * NOTE: The following warning will become irrelevant once NMS is + * in place, and frame_list_t can go away completely. --AC + * (here's a FIXME tag so we don't forget) + * + * BIG FAT WARNING: + * + * These structures must be kept in sync: meaning that if you add + * another field to the vframe_list_t you must add it at the end + * of the structure. + * + * aframe_list_t, vframe_list_t and the wrapper frame_list_t share + * the same offsets to their elements up to the field "size". That + * means that when a filter is called with at init time with the + * anonymouse frame_list_t, it can already access the size. + * + * -- tibit + */ + +/* This macro factorizes common frame data fields. + * Is not possible to completely factor out all frame_list_t fields + * because video and audio typess uses different names for same fields, + * and existing code relies on this assumption. + * Fixing this is stuff for 1.2.0 and beyond, for which I would like + * to introduce some generic frame structure or something like it. -- FR. + */ +#define TC_FRAME_COMMON \ + int id; /* frame id (sequential uint) */ \ + int bufid; /* buffer id */ \ + int tag; /* init, open, close, ... */ \ + int filter_id; /* filter instance to run */ \ + TCFrameStatus status; /* see enumeration above */ \ + TCFrameAttributes attributes; /* see enumeration above */ \ + TCTimestamp timestamp; \ +/* BEWARE: semicolon NOT NEEDED */ + +/* + * Size vs Length + * + * Size represent the effective size of audio/video buffer, + * while length represent the amount of valid data into buffer. + * Until 1.1.0, there isn't such distinction, and 'size' + * have approximatively a mixed meaning of above. + * + * In the long shot[1] (post-1.1.0) transcode will start + * intelligently allocate frame buffers based on highest + * request of all modules (core included) through filter + * mangling pipeline. This will lead on circumstances on + * which valid data into a buffer is less than buffer size: + * think to demuxer->decoder transition or RGB24->YUV420. + * + * There also are more specific cases like a full-YUV420P + * pipeline with final conversion to RGB24 and raw output, + * so we can have something like + * + * framebuffer size = sizeof(RGB24_frame) + * after demuxer: + * frame length << frame size (compressed data) + * after decoder: + * frame length < frame size (YUV420P smaller than RGB24) + * in filtering: + * frame length < frame size (as above) + * after encoding (in fact just colorspace transition): + * frame length == frame size (data becomes RGB24) + * into muxer: + * frame length == frame size (as above) + * + * In all those cases having a distinct 'lenght' fields help + * make things nicer and easier. + * + * +++ + * + * [1] in 1.1.0 that not happens due to module interface constraints + * since we're still bound to Old Module System. + */ + +#define TC_FRAME_GET_TIMESTAMP_UINT(FP) ((FP)->timestamp.u) +#define TC_FRAME_GET_TIMESTAMP_DOUBLE(FP) ((FP)->timestamp.d) +#define TC_FRAME_SET_TIMESTAMP_UINT(FP, TS) ((FP)->timestamp.u = (uint64_t)(TS)) +#define TC_FRAME_SET_TIMESTAMP_DOUBLE(FP, TS) ((FP)->timestamp.d = (double)(TS)) + +typedef struct tcframe_ TCFrame; +struct tcframe_ { + TC_FRAME_COMMON + + int codec; /* codec identifier */ + + int size; /* buffer size avalaible */ + int len; /* how much data is valid? */ + + int param1; /* v_width or a_rate */ + int param2; /* v_height or a_bits */ + int param3; /* v_bpp or a_chan */ + + struct tcframe_ *next; + struct tcframe_ *prev; +}; +typedef struct tcframe_ frame_list_t; + + +typedef struct tcframevideo_ TCFrameVideo; +struct tcframevideo_ { + TC_FRAME_COMMON + /* frame physical parameter */ + + int v_codec; /* codec identifier */ + + int video_size; /* buffer size avalaible */ + int video_len; /* how much data is valid? */ + + int v_width; + int v_height; + int v_bpp; + + struct tcframevideo_ *next; + struct tcframevideo_ *prev; + + uint8_t *video_buf; /* pointer to current buffer */ + uint8_t *video_buf2; /* pointer to backup buffer */ + + int free; /* flag */ + +#ifdef STATBUFFER + uint8_t *internal_video_buf_0; + uint8_t *internal_video_buf_1; +#else + uint8_t internal_video_buf_0[SIZE_RGB_FRAME]; + uint8_t internal_video_buf_1[SIZE_RGB_FRAME]; +#endif + + int deinter_flag; + /* set to N for internal de-interlacing with "-I N" */ + + uint8_t *video_buf_RGB[2]; + + uint8_t *video_buf_Y[2]; + uint8_t *video_buf_U[2]; + uint8_t *video_buf_V[2]; +}; +typedef struct tcframevideo_ vframe_list_t; + + +typedef struct tcframeaudio_ TCFrameAudio; +struct tcframeaudio_ { + TC_FRAME_COMMON + + int a_codec; /* codec identifier */ + + int audio_size; /* buffer size avalaible */ + int audio_len; /* how much data is valid? */ + + int a_rate; + int a_bits; + int a_chan; + + struct tcframeaudio_ *next; + struct tcframeaudio_ *prev; + + uint8_t *audio_buf; + uint8_t *audio_buf2; + + int free; /* flag */ + +#ifdef STATBUFFER + uint8_t *internal_audio_buf; + uint8_t *internal_audio_buf_1; +#else + uint8_t internal_audio_buf[SIZE_PCM_FRAME * 2]; + uint8_t internal_audio_buf_1[SIZE_PCM_FRAME * 2]; +#endif +}; +typedef struct tcframeaudio_ aframe_list_t; + +/* + * generic pointer type, needed at least by internal code. + * In the long (long) shot I'd like to use a unique generic + * data container, like AVPacket (libavcodec) or something like it. + * (see note about TC_FRAME_COMMON above) -- FR + */ +typedef union tcframeptr_ TCFramePtr; +union tcframeptr_ { + TCFrame *generic; + TCFrameVideo *video; + TCFrameAudio *audio; +}; + +/*************************************************************************/ + + +/* + * tc_video_planes_size: + * compute the size of video planes given frame size and frame format. + * Recognizes only video formats used in transcode. + * + * Parameters: + * psizes: array of size that will be filled with size of respective + * plane, in order. If given format isn't a planar one, only + * first element in array is significant. + * width: width of video frame + * height: height of video frame + * format: format of video frame + * Return Value: + * >= 0 if succesfull, + * TC_NULL_MATCH otherwise (wrong/unknown parameters) + */ +int tc_video_planes_size(size_t psizes[3], + int width, int height, int format); + +/* + * tc_video_frame_size: + * little helper function that returns the full dimension of a + * video frame given dimensions and format. + * + * Parameters: + * width: width of video frame + * height: height of video frame + * format: format of video frame + * Return Value: + * size in bytes of video frame + */ +#ifdef HAVE_GCC_ATTRIBUTES +__attribute__((unused)) +#endif +static size_t tc_video_frame_size(int width, int height, int format) +{ + size_t psizes[3] = { 0, 0, 0 }; + tc_video_planes_size(psizes, width, height, format); + return (psizes[0] + psizes[1] + psizes[2]); +} + +/* + * OK, we have sample rate. But sample rate means "[audio] samples PER SECOND" + * and we want audio samples PER FRAME. + */ +#define TC_AUDIO_SAMPLES_IN_FRAME(rate, fps) ((double)rate/(double)fps) + +/* + * tc_audio_frame_size: + * compute the size of buffer needed to store the audio data described by + * given specifiers. + * + * Parameters: + * samples: audio samples PER FRAME. Can (and it's likely that it will) + * be a real numner (values after the point are significant!) + * channels: audio channels. + * bits: audio BITS for sample. + * adjust: store here adjustement value. Such value means how much extra + * buffer size it's needed to safely store extra samples. + * We have extra samples when rate/fps != 0, so we can + * spread all samples in frames, there is something that + * "exceed" :) + * (OK, there is *A LOT* of room for improvement here. But this + * API it's also driven by legacy code). + * Return Value: + * amount of buffer needed. + * Preconditions: + * adjust != NULL. + */ +size_t tc_audio_frame_size(double samples, int channels, + int bits, int *adjust); + +/* + * tc_alloc_{video,audio}_frame: + * allocate, but NOT initialize, a {TCFrameVideo,TCFrameAudio}, + * large enough to hold a video frame large as given size. + * This function guarantee that video buffer(s) memory will + * be page-aligned. + * + * Parameters: + * size: size in bytes of video frame that will be contained. + * partial: if !0, doesn't allocate secondary video buffer, + * but only primary. This allow to save memory since + * secondary video buffer isn't ALWAYS needed. + * Return Value: + * pointer to a new TCFrameVideo (free it using tc_del_video_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameVideo *tc_alloc_video_frame(size_t size, int partial); +TCFrameAudio *tc_alloc_audio_frame(size_t size); + + +/* + * tc_init_video_frame: + * properly (re)initialize an already-allocated video frame, by + * asjusting plane pointers, (re)setting video buffer pointers, + * cleaning flags et. al. + * You usually always need to use this function unless you + * perfectly knows what you're doing. + * Do nothing if missing TCFrameVideo to (re)initialize of + * one or more parameter are wrong. + * + * Parameters: + * vptr: pointer to TCFrameVideo to (re)initialize. + * width: video frame width. + * height: video frame height. + * format: video frame format. + * Return Value: + * None + * Preconditions: + * given TCFrameVideo MUST be already allocated to be large + * enough to safely store a video frame with given + * parameters. This function DO NOT check if this precondition + * is respected. + */ +void tc_init_video_frame(TCFrameVideo *vptr, + int width, int height, int format); +/* + * tc_init_audio_frame: + * properly (re)initialize an already-allocated audio frame, + * (re)setting video buffer pointers,cleaning flags et. al. + * You usually always need to use this function unless you + * perfectly knows what you're doing. + * Do nothing if missing TCFrameAudio to (re)initialize of + * one or more parameter are wrong. + * + * Parameters: + * aptr: pointer to TCFrameAudio to (re)initialize. + * samples: audio frame samples that this audio frame + * will contain (WARNING: TCFrameAudio MUST + * be allocated accordingly). + * channels: audio frame channels. + * bits: audio frame bit for sample. + * Return Value: + * None + * Preconditions: + * given TCFrameAudio MUST be already allocated to be large + * enough to safely store an audio frame with given + * parameters. This function DO NOT check if this precondition + * is respected. + */ +void tc_init_audio_frame(TCFrameAudio *aptr, + double samples, int channels, int bits); + +/* + * tc_new_video_frame: + * allocate and initialize a new TCFrameVideo large enough + * to hold a video frame represented by given parameters. + * This function guarantee that video buffer(s) memory will + * be page-aligned. + * + * Parameters: + * width: video frame width. + * height: video frame height. + * format: video frame format. + * partial: if !0, doesn't allocate secondary video buffer, + * but only primary. This allow to save memory since + * secondary video buffer isn't ALWAYS needed. + * Return Value: + * pointer to a new TCFrameVideo (free it using tc_del_video_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameVideo *tc_new_video_frame(int width, int height, int format, + int partial); + +/* + * tc_new_audio_frame: + * allocate and initialize a new TCFrameAudio large enough + * to hold an audio frame represented by given parameters. + * This function guarantee that audio buffer memory will + * be page-aligned. + * + * Parameters: + * samples: audio frame samples that this audio frame + * will contain (WARNING: TCFrameAudio MUST + * be allocated accordingly). + * channels: audio frame channels. + * bits: audio frame bit for sample. + * Return Value: + * pointer to a new TCFrameAudio (free it using tc_del_audio_frame, + * not manually! ) if succesfull, NULL otherwise. + */ +TCFrameAudio *tc_new_audio_frame(double samples, int channels, int bits); + + +/* + * tc_del_{video,audio}_frame: + * safely deallocate memory obtained with tc_new_{video,audio}_frame + * or tc_alloc_{video,audio}_frame. + * + * Parameters: + * {vptr,aptr}: a pointer to a TCFrame{Video,Audio} obtained by calling + * tc_new_{video,audio}_frame or tc_alloc_{video,audio}_frame. + * Return Value: + * None + */ +void tc_del_video_frame(TCFrameVideo *vptr); +void tc_del_audio_frame(TCFrameAudio *aptr); + +/* + * tc_blank_{video,audio}_frame: + * fill a provided frame with per-format valid but blank (null) + * content. + * + * Parameters: + * ptr: pointer to frame to fill. + * Return Value: + * None. + */ +void tc_blank_video_frame(TCFrameVideo *ptr); +void tc_blank_audio_frame(TCFrameAudio *ptr); + + +#endif /* TCFRAMES_H */ |
