summaryrefslogtreecommitdiffstats
path: root/debian/transcode/transcode-1.1.7/libtc/tcframes.h
diff options
context:
space:
mode:
Diffstat (limited to 'debian/transcode/transcode-1.1.7/libtc/tcframes.h')
-rw-r--r--debian/transcode/transcode-1.1.7/libtc/tcframes.h491
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 */