add libeplayer3-arm test

Origin commit data
------------------
Branch: master
Commit: d2b5eae8f7
Author: max_10 <max_10@gmx.de>
Date: 2017-12-16 (Sat, 16 Dec 2017)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
max_10
2017-12-16 23:41:01 +01:00
committed by TangoCash
parent a50cdc1d17
commit cd783bd89b
101 changed files with 28366 additions and 21 deletions

View File

@@ -0,0 +1,544 @@
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream reader API header.
*/
#ifndef AVCODEC_GET_BITS_H
#define AVCODEC_GET_BITS_H
#include <stdint.h>
#include <limits.h>
#include <libavutil/common.h>
#include <libavutil/error.h>
#include <libavutil/intreadwrite.h>
#include <libavutil/attributes.h>
#include "mathops.h"
typedef struct GetBitContext
{
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
} GetBitContext;
/* Bitstream reader API docs:
* name
* arbitrary name which is used as prefix for the internal variables
*
* gb
* getbitcontext
*
* OPEN_READER(name, gb)
* load gb into local variables
*
* CLOSE_READER(name, gb)
* store local vars in gb
*
* UPDATE_CACHE(name, gb)
* Refill the internal cache from the bitstream.
* After this call at least MIN_CACHE_BITS will be available.
*
* GET_CACHE(name, gb)
* Will output the contents of the internal cache,
* next bit is MSB of 32 or 64 bits (FIXME 64 bits).
*
* SHOW_UBITS(name, gb, num)
* Will return the next num bits.
*
* SHOW_SBITS(name, gb, num)
* Will return the next num bits and do sign extension.
*
* SKIP_BITS(name, gb, num)
* Will skip over the next num bits.
* Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER.
*
* SKIP_CACHE(name, gb, num)
* Will remove the next num bits from the cache (note SKIP_COUNTER
* MUST be called before UPDATE_CACHE / CLOSE_READER).
*
* SKIP_COUNTER(name, gb, num)
* Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS).
*
* LAST_SKIP_BITS(name, gb, num)
* Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER.
*
* BITS_LEFT(name, gb)
* Return the number of bits left
*
* For examples see get_bits, show_bits, skip_bits, get_vlc.
*/
#ifdef LONG_BITSTREAM_READER
# define MIN_CACHE_BITS 32
#else
# define MIN_CACHE_BITS 25
#endif
#define OPEN_READER_NOSIZE(name, gb) \
unsigned int name ## _index = (gb)->index; \
unsigned int av_unused name ## _cache
#define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb)
#define BITS_AVAILABLE(name, gb) 1
#define CLOSE_READER(name, gb) (gb)->index = name ## _index
# ifdef LONG_BITSTREAM_READER
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
#else
# define UPDATE_CACHE_LE(name, gb) name ## _cache = \
AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
# define UPDATE_CACHE_BE(name, gb) name ## _cache = \
AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
#endif
#ifdef BITSTREAM_READER_LE
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num)
#else
# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb)
# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
#endif
#define SKIP_COUNTER(name, gb, num) name ## _index += (num)
#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index))
#define SKIP_BITS(name, gb, num) \
do { \
SKIP_CACHE(name, gb, num); \
SKIP_COUNTER(name, gb, num); \
} while (0)
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
#define SHOW_UBITS_LE(name, gb, num) zero_extend(name ## _cache, num)
#define SHOW_SBITS_LE(name, gb, num) sign_extend(name ## _cache, num)
#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name ## _cache, num)
#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num)
#ifdef BITSTREAM_READER_LE
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num)
#else
# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num)
# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num)
#endif
#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
static inline int get_bits_count(const GetBitContext *s)
{
return s->index;
}
static inline void skip_bits_long(GetBitContext *s, int n)
{
s->index += n;
}
/**
* Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB).
* if MSB not set it is negative
* @param n length in bits
*/
static inline int get_xbits(GetBitContext *s, int n)
{
register int sign;
register int32_t cache;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
cache = GET_CACHE(re, s);
sign = ~cache >> 31;
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
}
static inline int get_xbits_le(GetBitContext *s, int n)
{
register int sign;
register int32_t cache;
OPEN_READER(re, s);
UPDATE_CACHE_LE(re, s);
cache = GET_CACHE(re, s);
sign = sign_extend(~cache, n) >> 31;
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (zero_extend(sign ^ cache, n) ^ sign) - sign;
}
static inline int get_sbits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
tmp = SHOW_SBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Read 1-25 bits.
*/
static inline unsigned int get_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Read 0-25 bits.
*/
static inline int get_bitsz(GetBitContext *s, int n)
{
return n ? get_bits(s, n) : 0;
}
static inline unsigned int get_bits_le(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s);
UPDATE_CACHE_LE(re, s);
tmp = SHOW_UBITS_LE(re, s, n);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return tmp;
}
/**
* Show 1-25 bits.
*/
static inline unsigned int show_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER_NOSIZE(re, s);
UPDATE_CACHE(re, s);
tmp = SHOW_UBITS(re, s, n);
return tmp;
}
static inline void skip_bits(GetBitContext *s, int n)
{
OPEN_READER(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
}
static inline unsigned int get_bits1(GetBitContext *s)
{
unsigned int index = s->index;
uint8_t result = s->buffer[index >> 3];
#ifdef BITSTREAM_READER_LE
result >>= index & 7;
result &= 1;
#else
result <<= index & 7;
result >>= 8 - 1;
#endif
index++;
s->index = index;
return result;
}
static inline unsigned int show_bits1(GetBitContext *s)
{
return show_bits(s, 1);
}
static inline void skip_bits1(GetBitContext *s)
{
skip_bits(s, 1);
}
/**
* Read 0-32 bits.
*/
static inline unsigned int get_bits_long(GetBitContext *s, int n)
{
if (!n)
{
return 0;
}
else if (n <= MIN_CACHE_BITS)
{
return get_bits(s, n);
}
else
{
#ifdef BITSTREAM_READER_LE
unsigned ret = get_bits(s, 16);
return ret | (get_bits(s, n - 16) << 16);
#else
unsigned ret = get_bits(s, 16) << (n - 16);
return ret | get_bits(s, n - 16);
#endif
}
}
/**
* Read 0-64 bits.
*/
static inline uint64_t get_bits64(GetBitContext *s, int n)
{
if (n <= 32)
{
return get_bits_long(s, n);
}
else
{
#ifdef BITSTREAM_READER_LE
uint64_t ret = get_bits_long(s, 32);
return ret | (uint64_t) get_bits_long(s, n - 32) << 32;
#else
uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32;
return ret | get_bits_long(s, 32);
#endif
}
}
/**
* Read 0-32 bits as a signed integer.
*/
static inline int get_sbits_long(GetBitContext *s, int n)
{
/* sign_extend(x, 0) is undefined */
if (!n)
return 0;
return sign_extend(get_bits_long(s, n), n);
}
/**
* Show 0-32 bits.
*/
static inline unsigned int show_bits_long(GetBitContext *s, int n)
{
if (n <= MIN_CACHE_BITS)
{
return show_bits(s, n);
}
else
{
GetBitContext gb = *s;
return get_bits_long(&gb, n);
}
}
static inline int check_marker(void *logctx, GetBitContext *s, const char *msg)
{
int bit = get_bits1(s);
return bit;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
{
int buffer_size;
int ret = 0;
if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer)
{
bit_size = 0;
buffer = NULL;
ret = AVERROR_INVALIDDATA;
}
buffer_size = (bit_size + 7) >> 3;
s->buffer = buffer;
s->size_in_bits = bit_size;
s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size;
s->index = 0;
return ret;
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param byte_size the size of the buffer in bytes
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
int byte_size)
{
if (byte_size > INT_MAX / 8 || byte_size < 0)
byte_size = -1;
return init_get_bits(s, buffer, byte_size * 8);
}
static inline const uint8_t *align_get_bits(GetBitContext *s)
{
int n = -get_bits_count(s) & 7;
if (n)
skip_bits(s, n);
return s->buffer + (s->index >> 3);
}
/**
* If the vlc code is invalid and max_depth=1, then no bits will be removed.
* If the vlc code is invalid and max_depth>1, then the number of bits removed
* is undefined.
*/
#define GET_VLC(code, name, gb, table, bits, max_depth) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
code = table[index][0]; \
n = table[index][1]; \
\
if (max_depth > 1 && n < 0) { \
LAST_SKIP_BITS(name, gb, bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
if (max_depth > 2 && n < 0) { \
LAST_SKIP_BITS(name, gb, nb_bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
} \
} \
SKIP_BITS(name, gb, n); \
} while (0)
#define GET_RL_VLC(level, run, name, gb, table, bits, \
max_depth, need_update) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
level = table[index].level; \
n = table[index].len; \
\
if (max_depth > 1 && n < 0) { \
SKIP_BITS(name, gb, bits); \
if (need_update) { \
UPDATE_CACHE(name, gb); \
} \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
if (max_depth > 2 && n < 0) { \
LAST_SKIP_BITS(name, gb, nb_bits); \
if (need_update) { \
UPDATE_CACHE(name, gb); \
} \
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
} \
} \
run = table[index].run; \
SKIP_BITS(name, gb, n); \
} while (0)
static inline int decode012(GetBitContext *gb)
{
int n;
n = get_bits1(gb);
if (n == 0)
return 0;
else
return get_bits1(gb) + 1;
}
static inline int decode210(GetBitContext *gb)
{
if (get_bits1(gb))
return 0;
else
return 2 - get_bits1(gb);
}
static inline int get_bits_left(GetBitContext *gb)
{
return gb->size_in_bits - get_bits_count(gb);
}
static inline int skip_1stop_8data_bits(GetBitContext *gb)
{
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
while (get_bits1(gb))
{
skip_bits(gb, 8);
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
}
return 0;
}
#endif /* AVCODEC_GET_BITS_H */

View File

@@ -0,0 +1,45 @@
/*
* LATM/LOAS muxer
* Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_LATMENC_H
#define AVCODEC_LATMENC_H
#include <stdint.h>
#define MAX_EXTRADATA_SIZE 1024
typedef struct LATMContext
{
int off;
int channel_conf;
int object_type;
int counter;
int mod; // default 0x0014
uint8_t loas_header[3];
uint8_t buffer[0x1fff + MAX_EXTRADATA_SIZE + 1024];
int len;
} LATMContext;
int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size);
int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *extradata, int extradata_size);
#endif /* AVCODEC_LATMENC_H */

View File

@@ -0,0 +1,56 @@
/*
* simple math operations
* Copyright (c) 2001, 2002 Fabrice Bellard
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MATHOPS_H
#define AVCODEC_MATHOPS_H
#include <stdint.h>
#include <libavutil/common.h>
#ifndef NEG_USR32
# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
#endif
#ifndef NEG_SSR32
# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
#endif
#ifndef sign_extend
static inline av_const int sign_extend(int val, unsigned bits)
{
unsigned shift = 8 * sizeof(int) - bits;
union
{
unsigned u;
int s;
} v = { (unsigned) val << shift };
return v.s >> shift;
}
#endif
#ifndef zero_extend
static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
{
return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
}
#endif
#endif /* AVCODEC_MATHOPS_H */

View File

@@ -0,0 +1,112 @@
/*
* MPEG-4 Audio common header
* Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_MPEG4AUDIO_H
#define AVCODEC_MPEG4AUDIO_H
#include <stdint.h>
#include "get_bits.h"
#include "put_bits.h"
typedef struct MPEG4AudioConfig
{
int object_type;
int sampling_index;
int sample_rate;
int chan_config;
int sbr; ///< -1 implicit, 1 presence
int ext_object_type;
int ext_sampling_index;
int ext_sample_rate;
int ext_chan_config;
int channels;
int ps; ///< -1 implicit, 1 presence
int frame_length_short;
} MPEG4AudioConfig;
extern const int avpriv_mpeg4audio_sample_rates[16];
extern const uint8_t ff_mpeg4audio_channels[8];
/**
* Parse MPEG-4 systems extradata to retrieve audio configuration.
* @param[in] c MPEG4AudioConfig structure to fill.
* @param[in] buf Extradata from container.
* @param[in] bit_size Extradata size in bits.
* @param[in] sync_extension look for a sync extension after config if true.
* @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
*/
int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
int bit_size, int sync_extension);
enum AudioObjectType
{
AOT_NULL,
// Support? Name
AOT_AAC_MAIN, ///< Y Main
AOT_AAC_LC, ///< Y Low Complexity
AOT_AAC_SSR, ///< N (code in SoC repo) Scalable Sample Rate
AOT_AAC_LTP, ///< Y Long Term Prediction
AOT_SBR, ///< Y Spectral Band Replication
AOT_AAC_SCALABLE, ///< N Scalable
AOT_TWINVQ, ///< N Twin Vector Quantizer
AOT_CELP, ///< N Code Excited Linear Prediction
AOT_HVXC, ///< N Harmonic Vector eXcitation Coding
AOT_TTSI = 12, ///< N Text-To-Speech Interface
AOT_MAINSYNTH, ///< N Main Synthesis
AOT_WAVESYNTH, ///< N Wavetable Synthesis
AOT_MIDI, ///< N General MIDI
AOT_SAFX, ///< N Algorithmic Synthesis and Audio Effects
AOT_ER_AAC_LC, ///< N Error Resilient Low Complexity
AOT_ER_AAC_LTP = 19, ///< N Error Resilient Long Term Prediction
AOT_ER_AAC_SCALABLE, ///< N Error Resilient Scalable
AOT_ER_TWINVQ, ///< N Error Resilient Twin Vector Quantizer
AOT_ER_BSAC, ///< N Error Resilient Bit-Sliced Arithmetic Coding
AOT_ER_AAC_LD, ///< N Error Resilient Low Delay
AOT_ER_CELP, ///< N Error Resilient Code Excited Linear Prediction
AOT_ER_HVXC, ///< N Error Resilient Harmonic Vector eXcitation Coding
AOT_ER_HILN, ///< N Error Resilient Harmonic and Individual Lines plus Noise
AOT_ER_PARAM, ///< N Error Resilient Parametric
AOT_SSC, ///< N SinuSoidal Coding
AOT_PS, ///< N Parametric Stereo
AOT_SURROUND, ///< N MPEG Surround
AOT_ESCAPE, ///< Y Escape Value
AOT_L1, ///< Y Layer 1
AOT_L2, ///< Y Layer 2
AOT_L3, ///< Y Layer 3
AOT_DST, ///< N Direct Stream Transfer
AOT_ALS, ///< Y Audio LosslesS
AOT_SLS, ///< N Scalable LosslesS
AOT_SLS_NON_CORE, ///< N Scalable LosslesS (non core)
AOT_ER_AAC_ELD, ///< N Error Resilient Enhanced Low Delay
AOT_SMR_SIMPLE, ///< N Symbolic Music Representation Simple
AOT_SMR_MAIN, ///< N Symbolic Music Representation Main
AOT_USAC_NOSBR, ///< N Unified Speech and Audio Coding (no SBR)
AOT_SAOC, ///< N Spatial Audio Object Coding
AOT_LD_SURROUND, ///< N Low Delay MPEG Surround
AOT_USAC, ///< N Unified Speech and Audio Coding
};
#define MAX_PCE_SIZE 320 ///<Maximum size of a PCE including the 3-bit ID_PCE
///<marker and the comment
int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb);
#endif /* AVCODEC_MPEG4AUDIO_H */

View File

@@ -0,0 +1,274 @@
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream writer API
*/
#ifndef AVCODEC_PUT_BITS_H
#define AVCODEC_PUT_BITS_H
#include <stdint.h>
#include <stddef.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/avassert.h"
typedef struct PutBitContext
{
uint32_t bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
int size_in_bits;
} PutBitContext;
/**
* Initialize the PutBitContext s.
*
* @param buffer the buffer where to put bits
* @param buffer_size the size in bytes of buffer
*/
static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size)
{
if (buffer_size < 0)
{
buffer_size = 0;
buffer = NULL;
}
s->size_in_bits = 8 * buffer_size;
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
s->buf_ptr = s->buf;
s->bit_left = 32;
s->bit_buf = 0;
}
/**
* Rebase the bit writer onto a reallocated buffer.
*
* @param buffer the buffer where to put bits
* @param buffer_size the size in bytes of buffer,
* must be larger than the previous size
*/
static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size)
{
av_assert0(8 * buffer_size > s->size_in_bits);
s->buf_end = buffer + buffer_size;
s->buf_ptr = buffer + (s->buf_ptr - s->buf);
s->buf = buffer;
s->size_in_bits = 8 * buffer_size;
}
/**
* @return the total number of bits written to the bitstream.
*/
static inline int put_bits_count(PutBitContext *s)
{
return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
}
/**
* @return the number of bits available in the bitstream.
*/
static inline int put_bits_left(PutBitContext *s)
{
return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left;
}
/**
* Pad the end of the output stream with zeros.
*/
static inline void flush_put_bits(PutBitContext *s)
{
#ifndef BITSTREAM_WRITER_LE
if (s->bit_left < 32)
s->bit_buf <<= s->bit_left;
#endif
while (s->bit_left < 32)
{
av_assert0(s->buf_ptr < s->buf_end);
#ifdef BITSTREAM_WRITER_LE
*s->buf_ptr++ = s->bit_buf;
s->bit_buf >>= 8;
#else
*s->buf_ptr++ = s->bit_buf >> 24;
s->bit_buf <<= 8;
#endif
s->bit_left += 8;
}
s->bit_left = 32;
s->bit_buf = 0;
}
#ifdef BITSTREAM_WRITER_LE
#define avpriv_align_put_bits align_put_bits_unsupported_here
#define avpriv_put_string ff_put_string_unsupported_here
#define avpriv_copy_bits avpriv_copy_bits_unsupported_here
#else
/**
* Pad the bitstream with zeros up to the next byte boundary.
*/
void avpriv_align_put_bits(PutBitContext *s);
/**
* Put the string string in the bitstream.
*
* @param terminate_string 0-terminates the written string if value is 1
*/
void avpriv_put_string(PutBitContext *pb, const char *string,
int terminate_string);
/**
* Copy the content of src to the bitstream.
*
* @param length the number of bits of src to copy
*/
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
#endif
/**
* Write up to 31 bits into a bitstream.
* Use put_bits32 to write 32 bits.
*/
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{
unsigned int bit_buf;
int bit_left;
av_assert2(n <= 31 && value < (1U << n));
bit_buf = s->bit_buf;
bit_left = s->bit_left;
/* XXX: optimize */
#ifdef BITSTREAM_WRITER_LE
bit_buf |= value << (32 - bit_left);
if (n >= bit_left)
{
if (3 < s->buf_end - s->buf_ptr)
{
AV_WL32(s->buf_ptr, bit_buf);
s->buf_ptr += 4;
}
else
{
av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
av_assert2(0);
}
bit_buf = value >> bit_left;
bit_left += 32;
}
bit_left -= n;
#else
if (n < bit_left)
{
bit_buf = (bit_buf << n) | value;
bit_left -= n;
}
else
{
bit_buf <<= bit_left;
bit_buf |= value >> (n - bit_left);
if (3 < s->buf_end - s->buf_ptr)
{
AV_WB32(s->buf_ptr, bit_buf);
s->buf_ptr += 4;
}
else
{
av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n");
av_assert2(0);
}
bit_left += 32 - n;
bit_buf = value;
}
#endif
s->bit_buf = bit_buf;
s->bit_left = bit_left;
}
static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
{
av_assert2(n >= 0 && n <= 31);
put_bits(pb, n, av_mod_uintp2(value, n));
}
/**
* Write exactly 32 bits into a bitstream.
*/
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
{
int lo = value & 0xffff;
int hi = value >> 16;
#ifdef BITSTREAM_WRITER_LE
put_bits(s, 16, lo);
put_bits(s, 16, hi);
#else
put_bits(s, 16, hi);
put_bits(s, 16, lo);
#endif
}
/**
* Return the pointer to the byte where the bitstream writer will put
* the next bit.
*/
static inline uint8_t *put_bits_ptr(PutBitContext *s)
{
return s->buf_ptr;
}
/**
* Skip the given number of bytes.
* PutBitContext must be flushed & aligned to a byte boundary before calling this.
*/
static inline void skip_put_bytes(PutBitContext *s, int n)
{
av_assert2((put_bits_count(s) & 7) == 0);
av_assert2(s->bit_left == 32);
av_assert0(n <= s->buf_end - s->buf_ptr);
s->buf_ptr += n;
}
/**
* Skip the given number of bits.
* Must only be used if the actual values in the bitstream do not matter.
* If n is 0 the behavior is undefined.
*/
static inline void skip_put_bits(PutBitContext *s, int n)
{
s->bit_left -= n;
s->buf_ptr -= 4 * (s->bit_left >> 5);
s->bit_left &= 31;
}
/**
* Change the end of the buffer.
*
* @param size the new size in bytes of the buffer where to put bits
*/
static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
{
av_assert0(size <= INT_MAX / 8 - 32);
s->buf_end = s->buf + size;
s->size_in_bits = 8 * size;
}
#endif /* AVCODEC_PUT_BITS_H */

View File

@@ -0,0 +1,75 @@
/*
* Common bit i/o utils
* Copyright (c) 2000, 2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2010 Loren Merritt
*
* alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* bitstream api.
*/
#include <libavutil/avassert.h>
#include <ffmpeg/put_bits.h>
void avpriv_align_put_bits(PutBitContext *s)
{
put_bits(s, s->bit_left & 7, 0);
}
void avpriv_put_string(PutBitContext *pb, const char *string,
int terminate_string)
{
while (*string)
{
put_bits(pb, 8, *string);
string++;
}
if (terminate_string)
put_bits(pb, 8, 0);
}
void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
{
int words = length >> 4;
int bits = length & 15;
int i;
if (length == 0)
return;
av_assert0(length <= put_bits_left(pb));
if (words < 16 || put_bits_count(pb) & 7)
{
for (i = 0; i < words; i++)
put_bits(pb, 16, AV_RB16(src + 2 * i));
}
else
{
for (i = 0; put_bits_count(pb) & 31; i++)
put_bits(pb, 8, src[i]);
flush_put_bits(pb);
memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
skip_put_bytes(pb, 2 * words - i);
}
put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
}

View File

@@ -0,0 +1,155 @@
/*
* LATM/LOAS muxer
* Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* ***************************** */
/* Includes */
/* ***************************** */
#include <ffmpeg/get_bits.h>
#include <ffmpeg/put_bits.h>
#include <ffmpeg/mpeg4audio.h>
#include <ffmpeg/latmenc.h>
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
//#define LATMENC_SILENT
#ifndef LATMENC_SILENT
#define latmenc_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define latmenc_err(fmt, x...)
#endif
int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
{
MPEG4AudioConfig m4ac;
if (size > MAX_EXTRADATA_SIZE)
{
latmenc_err("Extradata is larger than currently supported.\n");
return AVERROR_INVALIDDATA;
}
ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1);
if (ctx->off < 0)
return ctx->off;
if (ctx->object_type == AOT_ALS && (ctx->off & 7))
{
// as long as avpriv_mpeg4audio_get_config works correctly this is impossible
latmenc_err("BUG: ALS offset is not byte-aligned\n");
return AVERROR_INVALIDDATA;
}
/* FIXME: are any formats not allowed in LATM? */
if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS)
{
latmenc_err("Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type);
return AVERROR_INVALIDDATA;
}
ctx->channel_conf = m4ac.chan_config;
ctx->object_type = m4ac.object_type;
return 0;
}
static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int extradata_size, PutBitContext *bs)
{
int header_size;
/* AudioMuxElement */
put_bits(bs, 1, !!ctx->counter);
if (!ctx->counter)
{
/* StreamMuxConfig */
put_bits(bs, 1, 0); /* audioMuxVersion */
put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */
put_bits(bs, 6, 0); /* numSubFrames */
put_bits(bs, 4, 0); /* numProgram */
put_bits(bs, 3, 0); /* numLayer */
/* AudioSpecificConfig */
if (ctx->object_type == AOT_ALS)
{
header_size = extradata_size - (ctx->off >> 3);
avpriv_copy_bits(bs, &extradata[ctx->off >> 3], header_size);
}
else
{
// + 3 assumes not scalable and dependsOnCoreCoder == 0,
// see decode_ga_specific_config in libavcodec/aacdec.c
avpriv_copy_bits(bs, extradata, ctx->off + 3);
if (!ctx->channel_conf)
{
GetBitContext gb;
int ret = init_get_bits8(&gb, extradata, extradata_size);
av_assert0(ret >= 0); // extradata size has been checked already, so this should not fail
skip_bits_long(&gb, ctx->off + 3);
avpriv_copy_pce_data(bs, &gb);
}
}
put_bits(bs, 3, 0); /* frameLengthType */
put_bits(bs, 8, 0xff); /* latmBufferFullness */
put_bits(bs, 1, 0); /* otherDataPresent */
put_bits(bs, 1, 0); /* crcCheckPresent */
}
ctx->counter++;
ctx->counter %= ctx->mod;
}
int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *extradata, int extradata_size)
{
PutBitContext bs;
int i, len;
if (size > 0x1fff)
goto too_large;
init_put_bits(&bs, ctx->buffer, size + 1024 + MAX_EXTRADATA_SIZE);
latmenc_write_frame_header(ctx, extradata, extradata_size, &bs);
/* PayloadLengthInfo() */
for (i = 0; i <= size - 255; i += 255)
put_bits(&bs, 8, 255);
put_bits(&bs, 8, size - i);
/* The LATM payload is written unaligned */
/* PayloadMux() */
if (size && (data[0] & 0xe1) == 0x81)
{
// Convert byte-aligned DSE to non-aligned.
// Due to the input format encoding we know that
// it is naturally byte-aligned in the input stream,
// so there are no padding bits to account for.
// To avoid having to add padding bits and rearrange
// the whole stream we just remove the byte-align flag.
// This allows us to remux our FATE AAC samples into latm
// files that are still playable with minimal effort.
put_bits(&bs, 8, data[0] & 0xfe);
avpriv_copy_bits(&bs, data + 1, 8 * size - 8);
}
else
avpriv_copy_bits(&bs, data, 8 * size);
avpriv_align_put_bits(&bs);
flush_put_bits(&bs);
len = put_bits_count(&bs) >> 3;
if (len > 0x1fff)
goto too_large;
memcpy(ctx->loas_header, "\x56\xe0\x00", 3);
ctx->loas_header[1] |= (len >> 8) & 0x1f;
ctx->loas_header[2] |= len & 0xff;
ctx->len = len;
return 0;
too_large:
latmenc_err("LATM packet size larger than maximum size 0x1fff\n");
return AVERROR_INVALIDDATA;
}

View File

@@ -0,0 +1,190 @@
/*
* MPEG-4 Audio common code
* Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
* Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <ffmpeg/get_bits.h>
#include <ffmpeg/put_bits.h>
#include <ffmpeg/mpeg4audio.h>
/**
* Parse MPEG-4 audio configuration for ALS object type.
* @param[in] gb bit reader context
* @param[in] c MPEG4AudioConfig structure to fill
* @return on success 0 is returned, otherwise a value < 0
*/
static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c)
{
if (get_bits_left(gb) < 112)
return -1;
if (get_bits_long(gb, 32) != MKBETAG('A', 'L', 'S', '\0'))
return -1;
// override AudioSpecificConfig channel configuration and sample rate
// which are buggy in old ALS conformance files
c->sample_rate = get_bits_long(gb, 32);
// skip number of samples
skip_bits_long(gb, 32);
// read number of channels
c->chan_config = 0;
c->channels = get_bits(gb, 16) + 1;
return 0;
}
/* XXX: make sure to update the copies in the different encoders if you change
* this table */
const int avpriv_mpeg4audio_sample_rates[16] =
{
96000, 88200, 64000, 48000, 44100, 32000,
24000, 22050, 16000, 12000, 11025, 8000, 7350
};
const uint8_t ff_mpeg4audio_channels[8] =
{
0, 1, 2, 3, 4, 5, 6, 8
};
static inline int get_object_type(GetBitContext *gb)
{
int object_type = get_bits(gb, 5);
if (object_type == AOT_ESCAPE)
object_type = 32 + get_bits(gb, 6);
return object_type;
}
static inline int get_sample_rate(GetBitContext *gb, int *index)
{
*index = get_bits(gb, 4);
return *index == 0x0f ? get_bits(gb, 24) :
avpriv_mpeg4audio_sample_rates[*index];
}
int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf,
int bit_size, int sync_extension)
{
GetBitContext gb;
int specific_config_bitindex, ret;
if (bit_size <= 0)
return AVERROR_INVALIDDATA;
ret = init_get_bits(&gb, buf, bit_size);
if (ret < 0)
return ret;
c->object_type = get_object_type(&gb);
c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
c->chan_config = get_bits(&gb, 4);
if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels))
c->channels = ff_mpeg4audio_channels[c->chan_config];
c->sbr = -1;
c->ps = -1;
if (c->object_type == AOT_SBR || (c->object_type == AOT_PS &&
// check for W6132 Annex YYYY draft MP3onMP4
!(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F))))
{
if (c->object_type == AOT_PS)
c->ps = 1;
c->ext_object_type = AOT_SBR;
c->sbr = 1;
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
c->object_type = get_object_type(&gb);
if (c->object_type == AOT_ER_BSAC)
c->ext_chan_config = get_bits(&gb, 4);
}
else
{
c->ext_object_type = AOT_NULL;
c->ext_sample_rate = 0;
}
specific_config_bitindex = get_bits_count(&gb);
if (c->object_type == AOT_ALS)
{
skip_bits(&gb, 5);
if (show_bits_long(&gb, 24) != MKBETAG('\0', 'A', 'L', 'S'))
skip_bits_long(&gb, 24);
specific_config_bitindex = get_bits_count(&gb);
if (parse_config_ALS(&gb, c))
return -1;
}
if (c->ext_object_type != AOT_SBR && sync_extension)
{
while (get_bits_left(&gb) > 15)
{
if (show_bits(&gb, 11) == 0x2b7) // sync extension
{
get_bits(&gb, 11);
c->ext_object_type = get_object_type(&gb);
if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1)
{
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
if (c->ext_sample_rate == c->sample_rate)
c->sbr = -1;
}
if (get_bits_left(&gb) > 11 && get_bits(&gb, 11) == 0x548)
c->ps = get_bits1(&gb);
break;
}
else
get_bits1(&gb); // skip 1 bit
}
}
//PS requires SBR
if (!c->sbr)
c->ps = 0;
//Limit implicit PS to the HE-AACv2 Profile
if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01)
c->ps = 0;
return specific_config_bitindex;
}
static av_always_inline unsigned int copy_bits(PutBitContext *pb,
GetBitContext *gb,
int bits)
{
unsigned int el = get_bits(gb, bits);
put_bits(pb, bits, el);
return el;
}
int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb)
{
int five_bit_ch, four_bit_ch, comment_size, bits;
int offset = put_bits_count(pb);
copy_bits(pb, gb, 10); //Tag, Object Type, Frequency
five_bit_ch = copy_bits(pb, gb, 4); //Front
five_bit_ch += copy_bits(pb, gb, 4); //Side
five_bit_ch += copy_bits(pb, gb, 4); //Back
four_bit_ch = copy_bits(pb, gb, 2); //LFE
four_bit_ch += copy_bits(pb, gb, 3); //Data
five_bit_ch += copy_bits(pb, gb, 4); //Coupling
if (copy_bits(pb, gb, 1)) //Mono Mixdown
copy_bits(pb, gb, 4);
if (copy_bits(pb, gb, 1)) //Stereo Mixdown
copy_bits(pb, gb, 4);
if (copy_bits(pb, gb, 1)) //Matrix Mixdown
copy_bits(pb, gb, 3);
for (bits = five_bit_ch * 5 + four_bit_ch * 4; bits > 16; bits -= 16)
copy_bits(pb, gb, 16);
if (bits)
copy_bits(pb, gb, bits);
avpriv_align_put_bits(pb);
align_get_bits(gb);
comment_size = copy_bits(pb, gb, 8);
for (; comment_size > 0; comment_size--)
copy_bits(pb, gb, 8);
return put_bits_count(pb) - offset;
}

View File

@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -0,0 +1,5 @@
This file contains the name of the people who have contributed to
VIXY FLV Converter. The names are sorted alphabetically by last name.
Takuma Mori (SGRA Corporation / Farside Inc. / vixy@vixy.net)

View File

@@ -0,0 +1,46 @@
This file contains the name of the people who have contributed to
FFmpeg. The names are sorted alphabetically by last name.
Michel Bardiaux
Fabrice Bellard
Patrice Bensoussan
Alex Beregszaszi
BERO
Mario Brito
Ronald Bultje
Maarten Daniels
Reimar Doeffinger
Tim Ferguson
Brian Foley
Arpad Gereoffy
Philip Gladstone
Vladimir Gneushev
Roine Gustafsson
David Hammerton
Wolfgang Hesseler
Falk Hueffner
Steven Johnson
Zdenek Kabelac
Robin Kay
Todd Kirby
Nick Kurshev
Benjamin Larsson
Loïc Le Loarer
Daniel Maas
Mike Melanson
Loren Merritt
Jeff Muizelaar
Michael Niedermayer
François Revol
Peter Ross
Måns Rullgård
Roman Shaposhnik
Dieter Shirley
Konstantin Shishkov
Juan J. Sierralta
Ewald Snel
Sascha Sommer
Leon van Stuivenberg
Roberto Togni
Lionel Ulmer
Reynaldo Verdejo

View File

@@ -0,0 +1,32 @@
VIXY FLV Converter contains the code that based on FFmpeg.
The following is the code and copyright notice.
/ffmpeg/libavcodec/bitstream.h
/ffmpeg/libavcodec/bitstream.c
* Copyright (c) 2000, 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
/ffmpeg/libavcodec/h263.c
* Copyright (c) 2001 Juan J. Sierralta P.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
/ffmpeg/libavcodec/h263data.h
/ffmpeg/libavcodec/h263dec.c
* Copyright (c) 2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
/ffmpeg/libavcodec/mpeg4data.h
/ffmpeg/libavcodec/mpegvideo.c
* Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
/ffmpeg/libavcodec/mpegvideo.h
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer
And see /FFMPEG_CREDITS.
Thanks.

View File

@@ -0,0 +1,14 @@
build
-----
$ cd src
$ gcc -O3 -o flv2mpeg4 avformat_writer.c dcprediction.c flv2mpeg4.c fetch.c flvdecoder.c m4vencode.c mp3header.c -lavformat -lavcodec -lavutil -I/usr/include/ffmpeg -L/usr/lib
usage
-----
- FLV to AVI(DIVX)
./flv2mpeg4 input.flv output.avi
- FLV to MOV
./flv2mpeg4 input.flv output.mov
- FLV to MP4(Video only)
./flv2mpeg4 input.flv output.mp4

View File

@@ -0,0 +1,16 @@
VIXY FLV Converter README
-------------------------
1) Licensing
------------
* Read the file COPYING and FFMPEG_IMPORTS.
2) Intsall
----------
* Read the file INSTALL.
3) WebSite
----------
* http://vixy.net/
Takuma Mori (vixy@vixy.net)

View File

@@ -0,0 +1,45 @@
/*
*
*
* Copyright (c) 2006 vixy project
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FLV_2_MPEG4_H
#define FLV_2_MPEG4_H
#include <stdint.h>
typedef int (*flv2mpeg4_write_packet_cb)(void *usr_data, int keyframe, int pts, const uint8_t *buf, int size);
typedef int (*flv2mpeg4_write_extradata_cb)(void *usr_data, int width, int height, int bitrate, const uint8_t *extradata, int extradatasize);
typedef struct
{
flv2mpeg4_write_packet_cb write_packet_cb;
flv2mpeg4_write_extradata_cb write_extradata_cb;
void *usr_data;
void *priv;
} flv2mpeg4_CTX;
flv2mpeg4_CTX *flv2mpeg4_init_ctx(void *priv_data, int width, int height, flv2mpeg4_write_packet_cb wp_cb, flv2mpeg4_write_extradata_cb we_cb);
void flv2mpeg4_set_frame(flv2mpeg4_CTX *ctx, int frame, int icounter);
int flv2mpeg4_process_flv_packet(flv2mpeg4_CTX *ctx, uint8_t picture_type, const uint8_t *buf, uint32_t size, uint32_t time);
int flv2mpeg4_prepare_extra_data(flv2mpeg4_CTX *ctx);
void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx);
#endif // FLV_2_MPEG4_H

View File

@@ -0,0 +1,177 @@
/*
* Bitstream reader
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BITREADER_H
#define BITREADER_H
#include "type.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _BR
{
const uint8 *buf;
uint32 size;
uint32 read;
int bitoffset;
} BR;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void init_br(BR *p, const uint8 *buf, uint32 size)
{
p->buf = buf;
p->size = size;
p->read = 0;
p->bitoffset = 0;
}
static uint8 get_u8(BR *p)
{
return p->buf[p->read++];
}
static uint32 get_u24(BR *p)
{
uint32 a = get_u8(p);
uint32 b = get_u8(p);
uint32 c = get_u8(p);
return (a << 16) | (b << 8) | c;
}
static uint32 get_u32(BR *p)
{
uint32 a = get_u8(p);
uint32 b = get_u8(p);
uint32 c = get_u8(p);
uint32 d = get_u8(p);
return (a << 24) | (b << 16) | (c << 8) | d;
}
static int is_eob(BR *p)
{
return p->read >= p->size;
}
static void skip(BR *p, uint32 skip)
{
p->read += skip;
}
static uint32 show_bits(BR *p, uint32 bits)
{
const uint8 *pp;
uint32 tmp;
pp = p->buf + p->read;
tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]);
tmp <<= p->bitoffset;
tmp >>= 32 - bits;
return tmp;
}
static int32 show_sbits(BR *p, uint32 bits)
{
const uint8 *pp;
int32 tmp;
pp = p->buf + p->read;
tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]);
tmp <<= p->bitoffset;
tmp >>= 32 - bits;
return tmp;
}
static void flash_bits(BR *p, uint32 bits)
{
if (bits > 0)
{
bits = bits + p->bitoffset;
p->read += bits >> 3;
p->bitoffset = bits & 7;
}
}
static uint32 get_bits(BR *p, uint32 bits)
{
uint32 tmp = show_bits(p, bits);
flash_bits(p, bits);
return tmp;
}
static int32 get_sbits(BR *p, uint32 bits)
{
int32 tmp = show_sbits(p, bits);
flash_bits(p, bits);
return tmp;
}
static void align_bits(BR *p)
{
if (p->bitoffset > 0)
{
p->bitoffset = 0;
p->read++;
}
}
static int __inline get_br_pos(BR *p)
{
return (p->read << 3) + p->bitoffset;
}
typedef struct _VLCtab
{
int code;
int n;
} VLCtab;
static int __inline get_vlc(BR *br, const VLCtab *table, int bits, int max_depth)
{
int n, index, nb_bits, code;
index = show_bits(br, bits);
code = table[index].code;
n = table[index].n;
if (max_depth > 1 && n < 0)
{
flash_bits(br, bits);
nb_bits = -n;
index = show_bits(br, nb_bits) + code;
code = table[index].code;
n = table[index].n;
}
flash_bits(br, n);
return code;
}
static int __inline get_vlcdec(BR *p, const VLCtab *table, int bits, int max_depth, VLCDEC *vlcdec)
{
int pos = get_br_pos(p);
uint32 show = show_bits(p, 24);
uint32 tmp = get_vlc(p, table, bits, max_depth);
int len = get_br_pos(p) - pos;
int val = show >> (24 - len);
vlcdec->bits = len;
vlcdec->value = val;
return tmp;
}
#endif // BITREADER_H

View File

@@ -0,0 +1,144 @@
/*
* Bitstream writer
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BITWRITER_H
#define BITWRITER_H
#include "type.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _BW
{
uint8 *buf;
uint32 size;
uint32 pos;
uint32 bitoffset;
uint32 tmp;
} BW;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void __inline clear_bw(BW *p)
{
p->pos = 0;
p->bitoffset = 0;
p->tmp = 0;
}
static void __inline init_bw(BW *p, uint8 *buf, uint32 size)
{
p->buf = buf;
p->size = size;
clear_bw(p);
}
static void __inline forword_bits(BW *p, uint32 bits)
{
p->bitoffset += bits;
if (p->bitoffset >= 32)
{
p->buf[p->pos++] = (p->tmp >> 24) & 0xff;
p->buf[p->pos++] = (p->tmp >> 16) & 0xff;
p->buf[p->pos++] = (p->tmp >> 8) & 0xff;
p->buf[p->pos++] = (p->tmp >> 0) & 0xff;
p->tmp = 0;
p->bitoffset -= 32;
}
}
static void __inline put_bits(BW *p, uint32 bits, uint32 value)
{
uint32 shift = 32 - p->bitoffset - bits;
if (shift <= 32)
{
p->tmp |= value << shift;
forword_bits(p, bits);
}
else
{
shift = bits - (32 - p->bitoffset);
p->tmp |= value >> shift;
forword_bits(p, bits - shift);
p->tmp |= value << (32 - shift);
forword_bits(p, shift);
}
}
static void __inline pad_to_boundary(BW *p)
{
uint32 bits = 8 - (p->bitoffset % 8);
if (bits < 8)
{
put_bits(p, bits, 0);
}
}
static void __inline flash_bw(BW *p)
{
pad_to_boundary(p);
switch (p->bitoffset)
{
case 0: // nothing to do
break;
case 8:
p->buf[p->pos++] = (p->tmp >> 24) & 0xff;
break;
case 16:
p->buf[p->pos++] = (p->tmp >> 24) & 0xff;
p->buf[p->pos++] = (p->tmp >> 16) & 0xff;
break;
case 24:
p->buf[p->pos++] = (p->tmp >> 24) & 0xff;
p->buf[p->pos++] = (p->tmp >> 16) & 0xff;
p->buf[p->pos++] = (p->tmp >> 8) & 0xff;
break;
default:
// fprintf(stderr, "flash_bw error!(%d)\n", p->bitoffset);
break;
}
p->tmp = 0;
p->bitoffset = 0;
}
static uint32 __inline get_bw_pos(BW *p)
{
return p->pos * 8 + p->bitoffset;
}
static void __inline put_vlcdec(BW *bw, VLCDEC *vlcdec)
{
put_bits(bw, vlcdec->bits, vlcdec->value);
}
// M4V ADDED
static void __inline m4v_stuffing(BW *p)
{
int length;
put_bits(p, 1, 0);
length = (- p->bitoffset) & 7;
if (length) put_bits(p, length, (1 << length) - 1);
}
#endif // BITWRITER_H

View File

@@ -0,0 +1,183 @@
/*
* DC prediction
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dcprediction.h"
// M4V ADDED
static const uint8 mpeg4_y_dc_scale_table[32] =
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0, 8, 8, 8, 8, 10, 12, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 36, 38, 40, 42, 44, 46
};
// M4V ADDED
static const uint8 mpeg4_c_dc_scale_table[32] =
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25
};
static int __inline get_pred(int *dc_cur, int stride, int scale)
{
/* B C
A X */
int A = dc_cur[-1];
int B = dc_cur[-1 - stride];
int C = dc_cur[-stride];
int pred;
if (abs(A - B) < abs(B - C))
{
pred = C;
}
else
{
pred = A;
}
return (pred + (scale >> 1)) / scale;
}
static void __inline set_dc_to_dc_cur(int *dc_cur, int level, int scale)
{
level *= scale;
if (level & (~2047))
{
if (level < 0)
level = 0;
else
level = 2047;
}
dc_cur[0] = level;
}
static int *get_dc_cur(M4V_DCPRED *pred, int mb_x, int mb_y, int n)
{
if (n < 4)
{
return pred->dc[n] + mb_x * 2 + mb_y * 2 * pred->stride[n] + pred->block_offset[n];
}
else
{
return pred->dc[n] + mb_x * 1 + mb_y * pred->stride[n];
}
}
static int __inline get_scale(M4V_DCPRED *pred, int n)
{
if (n < 4)
{
return pred->y_dc_scale;
}
else
{
return pred->c_dc_scale;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void dcpred_set_qscale(M4V_DCPRED *pred, int qscale)
{
if (qscale < 0) qscale = 0;
if (qscale > 31) qscale = 31;
pred->y_dc_scale = mpeg4_y_dc_scale_table[qscale];
pred->c_dc_scale = mpeg4_c_dc_scale_table[qscale];
}
void dcpred_set_pos(M4V_DCPRED *pred, int mb_x, int mb_y)
{
int n;
for (n = 0; n < 6; n++)
{
pred->dc_cur[n] = get_dc_cur(pred, mb_x, mb_y, n);
}
}
int dcpred_for_enc(M4V_DCPRED *p, int n, int level)
{
int *dc_cur = p->dc_cur[n];
int scale = get_scale(p, n);
int pred = get_pred(dc_cur, p->stride[n], scale);
set_dc_to_dc_cur(dc_cur, level, scale);
return level - pred;
}
int dcpred_for_dec(M4V_DCPRED *p, int n, int level)
{
int *dc_cur = p->dc_cur[n];
int scale = get_scale(p, n);
int pred = get_pred(dc_cur, p->stride[n], scale);
level += pred;
set_dc_to_dc_cur(dc_cur, level, scale);
return level;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void init_plane(M4V_DCPRED *pred, int n)
{
int x, len = pred->stride[n] * pred->height[n];
int *p = pred->_dc[n];
for (x = 0; x < len; x++)
{
p[x] = 1024;
}
}
void init_dcpred(M4V_DCPRED *pred)
{
init_plane(pred, 0);
init_plane(pred, 4);
init_plane(pred, 5);
}
void alloc_dcpred(M4V_DCPRED *pred, int mb_width, int mb_height)
{
const int w2 = mb_width * 2 + 1;
const int h2 = mb_height * 2 + 1;
const int w = mb_width + 1;
const int h = mb_height + 1;
pred->_dc[0] = pred->_dc[1] = pred->_dc[2] = pred->_dc[3] = (int *)malloc(sizeof(int) * w2 * h2);
pred->_dc[4] = (int *)malloc(sizeof(int) * w * h);
pred->_dc[5] = (int *)malloc(sizeof(int) * w * h);
pred->dc[0] = pred->dc[1] = pred->dc[2] = pred->dc[3] = pred->_dc[0] + w2 + 1;
pred->dc[4] = pred->_dc[4] + w + 1;
pred->dc[5] = pred->_dc[5] + w + 1;
pred->stride[0] = pred->stride[1] = pred->stride[2] = pred->stride[3] = w2;
pred->height[0] = pred->height[1] = pred->height[2] = pred->height[3] = h2;
pred->stride[4] = pred->stride[5] = w;
pred->height[4] = pred->height[5] = h;
pred->block_offset[0] = 0;
pred->block_offset[1] = 1;
pred->block_offset[2] = w2;
pred->block_offset[3] = w2 + 1;
pred->block_offset[4] = 0;
pred->block_offset[5] = 0;
}
void free_dcpred(M4V_DCPRED *pred)
{
free(pred->_dc[0]);
free(pred->_dc[4]);
free(pred->_dc[5]);
}

View File

@@ -0,0 +1,56 @@
/*
* DC Prediction
*
* Copyright (c) 2006 vixy project
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DCPREDICTION_H
#define DCPREDICTION_H
#include "type.h"
#include <stdlib.h>
typedef struct _M4V_DCPRED
{
int *_dc[6]; // for malloc(),free()
int *dc[6]; // for point (0,0)
int *dc_cur[6]; // for point current pos
int stride[6];
int height[6];
int block_offset[6];
int y_dc_scale;
int c_dc_scale;
} M4V_DCPRED;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void dcpred_set_qscale(M4V_DCPRED *pred, int qscale);
void dcpred_set_pos(M4V_DCPRED *pred, int mb_x, int mb_y);
int dcpred_for_enc(M4V_DCPRED *pred, int n, int level);
int dcpred_for_dec(M4V_DCPRED *pred, int n, int level);
void init_dcpred(M4V_DCPRED *pred);
void alloc_dcpred(M4V_DCPRED *pred, int mb_width, int mb_height);
void free_dcpred(M4V_DCPRED *pred);
#endif // DCPREDICTION_H

View File

@@ -0,0 +1,161 @@
/*
* FLV structs and tables
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef FLV_H
#define FLV_H
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "bitreader.h"
#include "bitwriter.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _BLOCK
{
int block[64];
int index;
int last_index;
} BLOCK;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _MICROBLOCK
{
BLOCK block[6];
int dquant;
int intra;
int skip;
#define MV_TYPE_16X16 0
#define MV_TYPE_8X8 1
int mv_type;
VLCDEC mv_x[4];
VLCDEC mv_y[4];
} MICROBLOCK;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _PICTURE
{
int width;
int height;
#define FLV_I_TYPE 0
#define FLV_P_TYPE 1
int picture_type; // 0:I 1:P
int escape_type; // 0:h263 1:flv(11bits)
int qscale;
int frame_number;
} PICTURE;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int decode_picture_header(BR *p, PICTURE *picture);
int decode_I_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale);
int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale);
void encode_picture_header(BW *bw, PICTURE *picture);
void encode_I_mb(BW *bw, MICROBLOCK *mb, int escape_type);
void encode_P_mb(BW *bw, MICROBLOCK *mb, int escape_type);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const uint16 rl_inter_vlc[103][2] =
{
{ 0x2, 2 }, { 0xf, 4 }, { 0x15, 6 }, { 0x17, 7 },
{ 0x1f, 8 }, { 0x25, 9 }, { 0x24, 9 }, { 0x21, 10 },
{ 0x20, 10 }, { 0x7, 11 }, { 0x6, 11 }, { 0x20, 11 },
{ 0x6, 3 }, { 0x14, 6 }, { 0x1e, 8 }, { 0xf, 10 },
{ 0x21, 11 }, { 0x50, 12 }, { 0xe, 4 }, { 0x1d, 8 },
{ 0xe, 10 }, { 0x51, 12 }, { 0xd, 5 }, { 0x23, 9 },
{ 0xd, 10 }, { 0xc, 5 }, { 0x22, 9 }, { 0x52, 12 },
{ 0xb, 5 }, { 0xc, 10 }, { 0x53, 12 }, { 0x13, 6 },
{ 0xb, 10 }, { 0x54, 12 }, { 0x12, 6 }, { 0xa, 10 },
{ 0x11, 6 }, { 0x9, 10 }, { 0x10, 6 }, { 0x8, 10 },
{ 0x16, 7 }, { 0x55, 12 }, { 0x15, 7 }, { 0x14, 7 },
{ 0x1c, 8 }, { 0x1b, 8 }, { 0x21, 9 }, { 0x20, 9 },
{ 0x1f, 9 }, { 0x1e, 9 }, { 0x1d, 9 }, { 0x1c, 9 },
{ 0x1b, 9 }, { 0x1a, 9 }, { 0x22, 11 }, { 0x23, 11 },
{ 0x56, 12 }, { 0x57, 12 }, { 0x7, 4 }, { 0x19, 9 },
{ 0x5, 11 }, { 0xf, 6 }, { 0x4, 11 }, { 0xe, 6 },
{ 0xd, 6 }, { 0xc, 6 }, { 0x13, 7 }, { 0x12, 7 },
{ 0x11, 7 }, { 0x10, 7 }, { 0x1a, 8 }, { 0x19, 8 },
{ 0x18, 8 }, { 0x17, 8 }, { 0x16, 8 }, { 0x15, 8 },
{ 0x14, 8 }, { 0x13, 8 }, { 0x18, 9 }, { 0x17, 9 },
{ 0x16, 9 }, { 0x15, 9 }, { 0x14, 9 }, { 0x13, 9 },
{ 0x12, 9 }, { 0x11, 9 }, { 0x7, 10 }, { 0x6, 10 },
{ 0x5, 10 }, { 0x4, 10 }, { 0x24, 11 }, { 0x25, 11 },
{ 0x26, 11 }, { 0x27, 11 }, { 0x58, 12 }, { 0x59, 12 },
{ 0x5a, 12 }, { 0x5b, 12 }, { 0x5c, 12 }, { 0x5d, 12 },
{ 0x5e, 12 }, { 0x5f, 12 }, { 0x3, 7 },
};
static const int8 rl_inter_level[102] =
{
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 1, 2, 3, 4,
5, 6, 1, 2, 3, 4, 1, 2,
3, 1, 2, 3, 1, 2, 3, 1,
2, 3, 1, 2, 1, 2, 1, 2,
1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 3, 1, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1,
};
static const int8 rl_inter_run[102] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 3, 3,
3, 4, 4, 4, 5, 5, 5, 6,
6, 6, 7, 7, 8, 8, 9, 9,
10, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 0, 0, 0, 1, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40,
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const int rl_inter_n = 102;
static const int rl_inter_last = 58;
#endif // FLV_H

View File

@@ -0,0 +1,289 @@
/*
* FLV to MPEG4 converter
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "m4v.h"
#include "bitwriter.h"
#include "flv.h"
#include "m4vencode.h"
#include "../flv2mpeg4.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _CONVCTX
{
int width;
int height;
int frame;
int icounter;
M4V_VOL vol;
} CONVCTX;
typedef struct
{
uint8 *out_buf;
M4V_VOL vol;
CONVCTX conv;
} CTX;
#define VOL_TIME_BITS 5
#define PACKETBUFFER_SIZE (256*1024*4)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const uint8 ff_mpeg4_y_dc_scale_table[32] =
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0, 8, 8, 8, 8, 10, 12, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 36, 38, 40, 42, 44, 46
};
static const uint8 ff_mpeg4_c_dc_scale_table[32] =
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25
};
static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol)
{
vol->width = flv_pic->width;
vol->height = flv_pic->height;
vol->time_bits = VOL_TIME_BITS; // 0-31
}
static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c)
{
vop->qscale = flv_pic->qscale;
vop->time = c->frame % 30;
vop->icount = (c->icounter + 29) / 30;
vop->intra_dc_threshold = 99;
if (flv_pic->picture_type == FLV_I_TYPE)
{
vop->picture_type = M4V_I_TYPE;
}
else
{
vop->picture_type = M4V_P_TYPE;
vop->f_code = 1;
}
}
static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb)
{
int i;
m4v_mb->dquant = flv_mb->dquant;
memcpy(m4v_mb->block, flv_mb->block, sizeof(m4v_mb->block)); // !!!!!!!
m4v_mb->intra = flv_mb->intra;
m4v_mb->skip = flv_mb->skip;
m4v_mb->mv_type = flv_mb->mv_type;
memcpy(m4v_mb->mv_x, flv_mb->mv_x, sizeof(m4v_mb->mv_x)); // !!!!!!
memcpy(m4v_mb->mv_y, flv_mb->mv_y, sizeof(m4v_mb->mv_y)); // !!!!!!
// dc rescale
if (m4v_mb->intra)
{
for (i = 0; i < 4; i++)
{
m4v_mb->block[i].block[0] *= 8;
m4v_mb->block[i].block[0] /= ff_mpeg4_y_dc_scale_table[m4v_mb->qscale];
}
for (i = 4; i < 6; i++)
{
m4v_mb->block[i].block[0] *= 8;
m4v_mb->block[i].block[0] /= ff_mpeg4_c_dc_scale_table[m4v_mb->qscale];
}
}
}
static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw, uint32 time)
{
// if any timecode padding is needed, then pad.
while (c->frame * 1000 / 30 < time)
{
M4V_VOP vop;
memset(&vop, 0, sizeof(vop));
vop.picture_type = M4V_P_TYPE;
vop.time = c->frame % 30;
vop.icount = (c->icounter + 29) / 30;
m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 1);
m4v_stuffing(bw);
flash_bw(bw);
// write frame
if (pub_ctx->write_packet_cb(pub_ctx->usr_data,
0,
0,//c->frame,
bw->buf,
bw->pos) < 0)
{
return -1;
}
clear_bw(bw);
c->frame++;
c->icounter++;
}
return 0;
}
static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, PICTURE *flvpic, uint32 time)
{
MICROBLOCK mb;
M4V_VOP vop;
M4V_MICROBLOCK m4v_mb;
int x, y;
int mb_width = (flvpic->width + 15) / 16;
int mb_height = (flvpic->height + 15) / 16;
memset(&vop, 0, sizeof(vop));
copy_vop(flvpic, &vop, c);
m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 0);
// transcode flv to mpeg4
for (y = 0; y < mb_height; y++)
{
for (x = 0; x < mb_width; x++)
{
memset(&mb, 0, sizeof(mb));
memset(&m4v_mb, 0, sizeof(m4v_mb));
if (vop.picture_type == M4V_I_TYPE)
{
mb.intra = 1;
if (decode_I_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) return -1;
m4v_mb.qscale = vop.qscale;
copy_microblock(&mb, &m4v_mb);
m4v_encode_I_dcpred(&m4v_mb, &c->vol.dcpred, x, y);
m4v_encode_I_mb(bw, &m4v_mb);
}
else
{
if (decode_P_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) return -1;
m4v_mb.qscale = vop.qscale;
copy_microblock(&mb, &m4v_mb);
m4v_encode_I_dcpred(&m4v_mb, &c->vol.dcpred, x, y);
m4v_encode_P_mb(bw, &m4v_mb);
}
}
}
m4v_stuffing(bw);
flash_bw(bw);
// write frame
if (pub_ctx->write_packet_cb(pub_ctx->usr_data,
vop.picture_type == M4V_I_TYPE,
0,//c->frame,
bw->buf,
bw->pos) < 0)
{
return -1;
}
c->frame++;
c->icounter++;
return 0;
}
static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, uint32 time)
{
PICTURE picture;
memset(&picture, 0, sizeof(picture));
init_dcpred(&c->vol.dcpred);
if (decode_picture_header(br, &picture) < 0) return -1;
if (c->width != picture.width || c->height != picture.height) return -1; //size changed..
copy_vol(&picture, &c->vol);
if (picture.picture_type == FLV_I_TYPE)
{
c->icounter = 0;
}
else
{
if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) return -1;
}
if (write_m4v_picture_frame(pub_ctx, c, br, bw, &picture, time) < 0)
{
return -1;
}
return 0;
}
int flv2mpeg4_process_flv_packet(flv2mpeg4_CTX *ctx, uint8 picture_type, const uint8 *buf, uint32 size, uint32 time)
{
CTX *p = ctx->priv;
BR br;
BW bw;
init_br(&br, buf, size);
init_bw(&bw, p->out_buf, PACKETBUFFER_SIZE);
write_m4v_frame(ctx, &p->conv, &br, &bw, time);
return 0;
}
int flv2mpeg4_prepare_extra_data(flv2mpeg4_CTX *ctx)
{
CTX *p = ctx->priv;
BW bw;
CONVCTX *c = &(p->conv);
M4V_VOP vop;
memset(&vop, 0, sizeof(vop));
init_bw(&bw, p->out_buf, PACKETBUFFER_SIZE);
c->vol.width = c->width;
c->vol.height = c->height;
c->vol.time_bits = VOL_TIME_BITS; // 0-31
m4v_encode_m4v_header(&bw, &c->vol, 0);
m4v_stuffing(&bw);
flash_bw(&bw);
alloc_dcpred(&c->vol.dcpred, (c->width + 15) / 16, (c->height + 15) / 16);
return ctx->write_extradata_cb(ctx->usr_data, c->width, c->height, 200 * 1000, bw.buf, bw.pos);
}
void flv2mpeg4_set_frame(flv2mpeg4_CTX *ctx, int frame, int icounter)
{
CTX *p = ctx->priv;
p->conv.frame = frame;
p->conv.icounter = icounter;
}
flv2mpeg4_CTX *flv2mpeg4_init_ctx(void *priv_data, int width, int height, flv2mpeg4_write_packet_cb wp_cb, flv2mpeg4_write_extradata_cb we_cb)
{
flv2mpeg4_CTX *pub_ctx = malloc(sizeof(flv2mpeg4_CTX));
memset(pub_ctx, 0x0, sizeof(flv2mpeg4_CTX));
pub_ctx->usr_data = priv_data;
pub_ctx->write_packet_cb = wp_cb;
pub_ctx->write_extradata_cb = we_cb;
pub_ctx->priv = malloc(sizeof(CTX));
memset(pub_ctx->priv, 0x0, sizeof(CTX));
CTX *ctx = pub_ctx->priv;
ctx->conv.width = width;
ctx->conv.height = height;
ctx->out_buf = malloc(PACKETBUFFER_SIZE);
memset(ctx->out_buf, 0x0, PACKETBUFFER_SIZE);
memset(&(ctx->vol), 0x0, sizeof(ctx->vol));
return pub_ctx;
}
void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx)
{
CTX *ctx = (*pub_ctx)->priv;
free_dcpred(&ctx->conv.vol.dcpred);
free(ctx->out_buf);
free(ctx);
free(*pub_ctx);
*pub_ctx = NULL;
}

View File

@@ -0,0 +1,523 @@
/*
* FLV Bitstream/VLC Decoder
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "bitreader.h"
#include "flv.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const uint8 zig_zag_scan[64] =
{
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};
static const VLCtab vlc_table_intra_MCBPC[] = //: table_size=72 table_allocated=128 bits=6
{
{64, -3},
{5, 6}, {6, 6}, {7, 6}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
{1, 3}, {1, 3}, {1, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {3, 3},
{3, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {-1, 0}, {8, 3}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}
};
static const VLCtab vlc_table_inter_MCBPC[] = //table_size=198 table_allocated=256 bits=7
{
{128, -6}, {192, -2}, {196, -1}, {7, 7}, {18, 7}, {17, 7}, {10, 7}, {9, 7}, {12, 6}, {12, 6}, {3, 6}, {3, 6},
{4, 5}, {4, 5}, {4, 5}, {4, 5}, {2, 4}, {2, 4}, {2, 4}, {2, 4}, {2, 4}, {2, 4}, {2, 4}, {2, 4}, {1, 4}, {1, 4},
{1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3},
{16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {16, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3},
{8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0}, {-1, 0},
{-1, 0}, {24, 4}, {24, 4}, {24, 4}, {24, 4}, {25, 6}, {-1, 0}, {26, 6}, {27, 6}, {20, 2}, {20, 2}, {20, 2},
{20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2}, {20, 2},
{20, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2},
{15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2},
{14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {14, 2}, {13, 2}, {11, 2}, {6, 1},
{6, 1}, {5, 1}, {19, 1},
};
static const VLCtab vlc_table_cbpy[] = //table_size=64 table_allocated=64 bits=6
{
{-1, 0}, {-1, 0}, {6, 6}, {9, 6}, {8, 5}, {8, 5}, {4, 5}, {4, 5}, {2, 5}, {2, 5}, {1, 5}, {1, 5}, {0, 4}, {0, 4},
{0, 4}, {0, 4}, {12, 4}, {12, 4}, {12, 4}, {12, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {14, 4}, {14, 4},
{14, 4}, {14, 4}, {5, 4}, {5, 4}, {5, 4}, {5, 4}, {13, 4}, {13, 4}, {13, 4}, {13, 4}, {3, 4}, {3, 4}, {3, 4},
{3, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {7, 4}, {7, 4}, {7, 4}, {7, 4}, {15, 2}, {15, 2}, {15, 2}, {15, 2},
{15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}, {15, 2}
};
static const VLCtab vlc_table_rl_inter[] = //: table_size=554 table_allocated=1024 bits=9
{
{-1, 0}, {512, -2}, {516, -1}, {518, -1}, {520, -1}, {522, -1}, {524, -1}, {526, -1}, {528, -2}, {532, -2},
{536, -3}, {544, -3}, {102, 7}, {102, 7}, {102, 7}, {102, 7}, {552, -1}, {85, 9}, {84, 9}, {83, 9}, {82, 9},
{81, 9}, {80, 9}, {79, 9}, {78, 9}, {59, 9}, {53, 9}, {52, 9}, {51, 9}, {50, 9}, {49, 9}, {48, 9}, {47, 9},
{46, 9}, {26, 9}, {23, 9}, {6, 9}, {5, 9}, {77, 8}, {77, 8}, {76, 8}, {76, 8}, {75, 8}, {75, 8}, {74, 8},
{74, 8}, {73, 8}, {73, 8}, {72, 8}, {72, 8}, {71, 8}, {71, 8}, {70, 8}, {70, 8}, {45, 8}, {45, 8}, {44, 8},
{44, 8}, {19, 8}, {19, 8}, {14, 8}, {14, 8}, {4, 8}, {4, 8}, {69, 7}, {69, 7}, {69, 7}, {69, 7}, {68, 7},
{68, 7}, {68, 7}, {68, 7}, {67, 7}, {67, 7}, {67, 7}, {67, 7}, {66, 7}, {66, 7}, {66, 7}, {66, 7}, {43, 7},
{43, 7}, {43, 7}, {43, 7}, {42, 7}, {42, 7}, {42, 7}, {42, 7}, {40, 7}, {40, 7}, {40, 7}, {40, 7}, {3, 7},
{3, 7}, {3, 7}, {3, 7}, {65, 6}, {65, 6}, {65, 6}, {65, 6}, {65, 6}, {65, 6}, {65, 6}, {65, 6}, {64, 6}, {64, 6},
{64, 6}, {64, 6}, {64, 6}, {64, 6}, {64, 6}, {64, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6},
{63, 6}, {63, 6}, {61, 6}, {61, 6}, {61, 6}, {61, 6}, {61, 6}, {61, 6}, {61, 6}, {61, 6}, {38, 6}, {38, 6},
{38, 6}, {38, 6}, {38, 6}, {38, 6}, {38, 6}, {38, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6},
{36, 6}, {36, 6}, {34, 6}, {34, 6}, {34, 6}, {34, 6}, {34, 6}, {34, 6}, {34, 6}, {34, 6}, {31, 6}, {31, 6},
{31, 6}, {31, 6}, {31, 6}, {31, 6}, {31, 6}, {31, 6}, {13, 6}, {13, 6}, {13, 6}, {13, 6}, {13, 6}, {13, 6},
{13, 6}, {13, 6}, {2, 6}, {2, 6}, {2, 6}, {2, 6}, {2, 6}, {2, 6}, {2, 6}, {2, 6}, {28, 5}, {28, 5}, {28, 5},
{28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5},
{28, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5},
{25, 5}, {25, 5}, {25, 5}, {25, 5}, {25, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5},
{22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {22, 5}, {58, 4}, {58, 4}, {58, 4},
{58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4},
{58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4},
{58, 4}, {58, 4}, {58, 4}, {58, 4}, {58, 4}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
{0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3},
{12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3},
{12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3},
{12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3},
{12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3},
{12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {12, 3}, {18, 4},
{18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4},
{18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4},
{18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {18, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4},
{1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4},
{1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {1, 4}, {62, 2}, {60, 2},
{10, 2}, {9, 2}, {89, 1}, {88, 1}, {87, 1}, {86, 1}, {39, 1}, {37, 1}, {35, 1}, {32, 1}, {29, 1}, {24, 1},
{20, 1}, {15, 1}, {11, 2}, {16, 2}, {54, 2}, {55, 2}, {90, 2}, {91, 2}, {92, 2}, {93, 2}, {17, 3}, {21, 3},
{27, 3}, {30, 3}, {33, 3}, {41, 3}, {56, 3}, {57, 3}, {94, 3}, {95, 3}, {96, 3}, {97, 3}, {98, 3}, {99, 3},
{100, 3}, {101, 3}, {8, 1}, {7, 1}
};
static const VLCtab vlc_table_mv[] = //mv_vlc: table_size=538 table_allocated=1024 bits=9
{
{512, -3}, {520, -2}, {524, -1}, {526, -1}, {528, -1}, {530, -1}, {532, -1}, {534, -1}, {536, -1}, {10, 9},
{9, 9}, {8, 9}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7},
{4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {4, 6}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4},
{3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4},
{3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {3, 4}, {2, 3}, {2, 3},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {-1, 0}, {-1, 0},
{32, 3}, {31, 3}, {30, 2}, {30, 2}, {29, 2}, {29, 2}, {28, 2}, {27, 2}, {26, 2}, {25, 2}, {24, 1}, {23, 1}, {22, 1},
{21, 1}, {20, 1}, {19, 1}, {18, 1}, {17, 1}, {16, 1}, {15, 1}, {14, 1}, {13, 1}, {12, 1}, {11, 1},
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int __inline decode_DC(BR *p)
{
int level = get_bits(p, 8);
if ((level & 0x7f) == 0)
{
printf("illigal dc\n");
return -1;
}
if (level == 255) level = 128;
// printf("DC: %d\n", level);
return level;
}
static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i)
{
int code, run, level, last, sign;
while (1)
{
code = get_vlc(p, vlc_table_rl_inter, 9, 2);
if (code < 0)
{
printf("invalid Huffman code in getblock()\n");
return -1;
}
if (code == rl_inter_n)
{
//escape
if (escape_type == 1)
{
int is11bit = get_bits(p, 1);
last = get_bits(p, 1);
run = get_bits(p, 6);
if (is11bit)
{
level = get_sbits(p, 11);
}
else
{
level = get_sbits(p, 7);
}
}
else
{
last = get_bits(p, 1);
run = get_bits(p, 6);
level = get_bits(p, 8);
sign = level >= 128;
if (sign) level = 256 - level;
}
}
else
{
run = rl_inter_run[code];
level = rl_inter_level[code];
last = code >= rl_inter_last;
sign = get_bits(p, 1);
if (sign) level = -level;
}
i += run;
if (i >= 64)
{
printf("run overflow..\n");
return -1;
}
block->block[zig_zag_scan[i]] = level;
if (last) break;
i++;
}
block->last_index = i;
return 0;
}
static int __inline decode_intra_block(BR *p, BLOCK *block, int escape_type, int coded)
{
int level = decode_DC(p);
if (level < 0)
{
printf("dc error.\n");
return -1;
}
block->block[0] = level;
block->last_index = 0;
if (!coded)
{
return 0;
}
if (decode_AC(p, block, escape_type, 1) < 0) return -1;
return 0;
}
static int __inline decode_inter_block(BR *p, BLOCK *block, int escape_type, int coded)
{
block->last_index = -1;
if (!coded)
{
return 0;
}
if (decode_AC(p, block, escape_type, 0) < 0) return -1;
return 0;
}
static int __inline get_intra_MCBPC(BR *br)
{
int cbpc;
do
{
cbpc = get_vlc(br, vlc_table_intra_MCBPC, 6, 2);
if (cbpc < 0) return -1;
}
while (cbpc == 8);
return cbpc;
}
static int __inline get_inter_MCBPC(BR *br)
{
int cbpc;
do
{
if (get_bits(br, 1))
{
return -2;
}
cbpc = get_vlc(br, vlc_table_inter_MCBPC, 7, 2);
if (cbpc < 0) return -1;
}
while (cbpc == 20);
return cbpc;
}
static int __inline get_cbpy(BR *br)
{
return get_vlc(br, vlc_table_cbpy, 6, 1);
}
static int __inline decode_dquant(BR *p)
{
static const int table[4] = { -1, -2, 1, 2 };
return table[get_bits(p, 2)];
}
static int __inline decode_motion(BR *br, VLCDEC *vlcdec)
{
int tmp;
int code = get_vlcdec(br, vlc_table_mv, 9, 2, vlcdec);
vlcdec->bits_ex = 0;
if (code == 0)
return 0;
if (code < 0)
return -1;
tmp = get_bits(br, 1);
/*
vlcdec->value |= (tmp << vlcdec->bits);
/// vlcdec->value <<= 1;
// vlcdec->value |= tmp;
vlcdec->bits++;
// vlcdec->value |= (tmp << vlcdec->bits);
*/
vlcdec->bits_ex = 1;
vlcdec->value_ex = tmp;
return 0;
}
static int __inline decode_intra_mb_internal(BR *p, MICROBLOCK *mb, int escape_type, int qscale, int cbpc, int dquant)
{
int cbpy, cbp;
int i;
cbpy = get_cbpy(p);
if (cbpy < 0)
{
printf("cbpy error\n");
return -1;
}
cbp = (cbpc & 3) | (cbpy << 2);
if (dquant)
{
mb->dquant = decode_dquant(p);
qscale += mb->dquant;
}
for (i = 0; i < 6; i++)
{
if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1;
cbp += cbp;
}
return 0;
}
static int __inline decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_type, int qscale, int cbpc, int dquant)
{
int cbpy, cbp;
int i;
cbpy = get_cbpy(p);
if (cbpy < 0)
{
printf("cbpy error\n");
return -1;
}
cbpy ^= 0xF;
cbp = (cbpc & 3) | (cbpy << 2);
if (dquant)
{
mb->dquant = decode_dquant(p);
qscale += mb->dquant;
}
if ((cbpc & 16) == 0)
{
// 16x16 motion prediction
decode_motion(p, &mb->mv_x[0]);
decode_motion(p, &mb->mv_y[0]);
mb->mv_type = MV_TYPE_16X16;
}
else
{
// 8x8 motion prediction
for (i = 0; i < 4; i++)
{
decode_motion(p, &mb->mv_x[i]);
decode_motion(p, &mb->mv_y[i]);
}
mb->mv_type = MV_TYPE_8X8;
}
for (i = 0; i < 6; i++)
{
if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1;
cbp += cbp;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int decode_I_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
{
int dquant;
int cbpc = get_intra_MCBPC(p);
if (cbpc < 0)
{
printf("intra_MCBPC error\n");
return -1;
}
dquant = cbpc & 4;
decode_intra_mb_internal(p, mb, escape_type, qscale, cbpc, dquant);
if (show_bits(p, 16) == 0)
{
// printf("slice end???\n");
}
return 0;
}
int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale)
{
int cbpc = get_inter_MCBPC(p);
if (cbpc == -1)
{
printf("inter_MCBPC error\n");
return -1;
}
if (cbpc == -2)
{
mb->skip = 1;
}
else if (cbpc >= 0)
{
int dquant = cbpc & 8;
mb->skip = 0;
if ((cbpc & 4) != 0)
{
mb->intra = 1;
decode_intra_mb_internal(p, mb, escape_type, qscale, cbpc, dquant);
}
else
{
mb->intra = 0;
decode_inter_mb_internal(p, mb, escape_type, qscale, cbpc, dquant);
}
}
if (show_bits(p, 16) == 0)
{
// printf("slice end???\n");
}
return 0;
}
int decode_picture_header(BR *p, PICTURE *picture)
{
int tmp, width = 0, height = 0;
if (get_bits(p, 17) != 1)
{
fprintf(stderr, "start code error\n");
return -1;
}
tmp = get_bits(p, 5);
if (tmp != 0 && tmp != 1)
{
fprintf(stderr, "picture format error\n");
return -1;
}
picture->escape_type = tmp;
picture->frame_number = get_bits(p, 8);
// printf("picture_format: %d\n", tmp);
// printf("picture_number: %d\n", get_bits(p, 8));
tmp = get_bits(p, 3);
switch (tmp)
{
case 0:
width = get_bits(p, 8);
height = get_bits(p, 8);
break;
case 1:
width = get_bits(p, 16);
height = get_bits(p, 16);
break;
case 2:
width = 352, height = 288;
break;
case 3:
width = 176, height = 144;
break;
case 4:
width = 128, height = 96;
break;
case 5:
width = 320, height = 240;
break;
case 6:
width = 160, height = 120;
break;
default:
fprintf(stderr, "size error\n");
return -1;
}
picture->width = width;
picture->height = height;
// printf("width: %d height: %d\n", width, height);
picture->picture_type = get_bits(p, 2);
// printf("picture_type: %d\n", tmp);
tmp = get_bits(p, 1);
// printf("deblocking flag: %d\n", tmp);
tmp = get_bits(p, 5);
picture->qscale = tmp;
// printf("qscale: %d\n", tmp);
// PEI
while (get_bits(p, 1) != 0)
{
flash_bits(p, 8);
}
// dump_marker(0, "dd header end");
return 0;
}

View File

@@ -0,0 +1,139 @@
/*
* MPEG4 structs and tables
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef M4V_H
#define M4V_H
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "bitreader.h"
#include "dcprediction.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define VOS_STARTCODE 0x1B0
#define USERDATA_STARTCODE 0x1B2
#define GOP_STARTCODE 0x1B3
#define VISUAL_OBJECT_STARTCODE 0x1B5
#define VOP_STARTCODE 0x1B6
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _M4V_BLOCK
{
int block[64];
int index;
int last_index;
} M4V_BLOCK;
typedef struct _M4V_MICROBLOCK
{
M4V_BLOCK block[6];
int qscale;
int dquant; // for encoding
int ac_pred;
int intra;
int skip;
#define MV_TYPE_16X16 0
#define MV_TYPE_8X8 1
int mv_type;
VLCDEC mv_x[4];
VLCDEC mv_y[4];
} M4V_MICROBLOCK;
typedef struct _M4V_VOL
{
int width;
int height;
int time_bits;
M4V_DCPRED dcpred;
} M4V_VOL;
typedef struct _M4V_VOP
{
#define M4V_I_TYPE 0
#define M4V_P_TYPE 1
#define M4V_B_TYPE 2
int picture_type;
int time;
int icount;
int intra_dc_threshold;
int rounding_type;
int qscale;
int f_code;
int b_code;
} M4V_VOP;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// same as FLV
static const uint8 zig_zag_scan[64] =
{
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};
// M4V ADDED
static const uint8 alternate_horizontal_scan[64] =
{
0, 1, 2, 3, 8, 9, 16, 17,
10, 11, 4, 5, 6, 7, 15, 14,
13, 12, 19, 18, 24, 25, 32, 33,
26, 27, 20, 21, 22, 23, 28, 29,
30, 31, 34, 35, 40, 41, 48, 49,
42, 43, 36, 37, 38, 39, 44, 45,
46, 47, 50, 51, 56, 57, 58, 59,
52, 53, 54, 55, 60, 61, 62, 63,
};
// M4V ADDED
static const uint8 alternate_vertical_scan[64] =
{
0, 8, 16, 24, 1, 9, 2, 10,
17, 25, 32, 40, 48, 56, 57, 49,
41, 33, 26, 18, 3, 11, 4, 12,
19, 27, 34, 42, 50, 58, 35, 43,
51, 59, 20, 28, 5, 13, 6, 14,
21, 29, 36, 44, 52, 60, 37, 45,
53, 61, 22, 30, 7, 15, 23, 31,
38, 46, 54, 62, 39, 47, 55, 63,
};
#endif // M4V_H

View File

@@ -0,0 +1,603 @@
/*
* MPEG4 Bitstream/VLC Encoder
*
* Copyright (c) 2006 vixy project
*
* This file contains the code that based on FFmpeg (http://ffmpeg.mplayerhq.hu/)
* See original copyright notice in /FFMPEG_CREDITS and /FFMPEG_IMPORTS
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "m4vencode.h"
#include "m4vencode_tables.h"
#include "bitwriter.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// same as H.263
static const uint32 vlce_intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 };
static const uint32 vlce_intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 };
static const uint32 vlce_cbpy_code[16] = { 3, 5, 4, 9, 3, 7, 2, 11, 2, 3, 5, 10, 4, 8, 6, 3};
static const uint32 vlce_cbpy_bits[16] = { 4, 5, 5, 4, 5, 4, 6, 4, 5, 6, 4, 4, 4, 4, 4, 2};
// same as H.263
static const uint32 vlce_inter_MCBPC_code[28] =
{
1, 3, 2, 5,
3, 4, 3, 3,
3, 7, 6, 5,
4, 4, 3, 2,
2, 5, 4, 5,
1, 0, 0, 0, /* Stuffing */
2, 12, 14, 15,
};
// same as H.263
static const uint32 vlce_inter_MCBPC_bits[28] =
{
1, 4, 4, 6, /* inter */
5, 8, 8, 7, /* intra */
3, 7, 7, 9, /* interQ */
6, 9, 9, 9, /* intraQ */
3, 7, 7, 8, /* inter4 */
9, 0, 0, 0, /* Stuffing */
11, 13, 13, 13,/* inter4Q*/
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void __inline encode_DC(BW *p, int level, int n)
{
if (level < -255 || level > 255) printf("dc overflow\n");
#if 1
level += 256;
if (n < 4)
{
put_bits(p, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]);
}
else
{
put_bits(p, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]);
}
#else
int size, v;
/* find number of bits */
size = 0;
v = abs(level);
while (v)
{
v >>= 1;
size++;
}
if (n < 4)
{
/* luminance */
put_bits(p, DCtab_lum[size][1], DCtab_lum[size][0]);
}
else
{
/* chrominance */
put_bits(p, DCtab_chrom[size][1], DCtab_chrom[size][0]);
}
/* encode remaining bits */
if (size > 0)
{
if (level < 0)
level = (-level) ^ ((1 << size) - 1);
put_bits(p, size, level);
if (size > 8)
put_bits(p, 1, 1);
}
#endif
}
static void __inline encode_escape_3(BW *p, int last, int run, int level)
{
#if 0
put_bits(p,
7 + 2 + 1 + 6 + 1 + 12 + 1, //30bit
(3 << 23) + (3 << 21) + (last << 20) + (run << 14) + (1 << 13) + (((level - 64) & 0xfff) << 1) + 1);
#else
put_bits(p, 7, 3); // escape
put_bits(p, 2, 3); // escape3
put_bits(p, 1, last);
put_bits(p, 6, run);
put_bits(p, 1, 1); // marker
put_bits(p, 12, ((level - 64) & 0xfff));
put_bits(p, 1, 1); // marker
#endif
}
#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last)*128*64 + (run)*128 + (level))
static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra)
{
int i = intra;
int last_index = block->last_index;
int last_non_zero = i - 1;
const uint8 *scan_table = zig_zag_scan; // !!!
#if 1
const uint8 *len_tab;
const uint32 *bits_tab;
if (intra)
{
len_tab = uni_mpeg4_intra_rl_len;
bits_tab = uni_mpeg4_intra_rl_bits;
}
else
{
len_tab = uni_mpeg4_inter_rl_len;
bits_tab = uni_mpeg4_inter_rl_bits;
}
for (; i < last_index; i++)
{
int level = block->block[scan_table[i]];
if (level)
{
int run = i - last_non_zero - 1;
level += 64;
if ((level & (~127)) == 0)
{
const int index = UNI_MPEG4_ENC_INDEX(0, run, level);
put_bits(p, len_tab[index], bits_tab[index]);
}
else
{
encode_escape_3(p, 0, run, level);
}
last_non_zero = i;
}
}
{
int level = block->block[scan_table[i]];
int run = i - last_non_zero - 1;
level += 64;
if ((level & (~127)) == 0)
{
const int index = UNI_MPEG4_ENC_INDEX(1, run, level);
put_bits(p, len_tab[index], bits_tab[index]);
}
else
{
encode_escape_3(p, 1, run, level);
}
}
#else
const RL *rl;
int last, sign, code;
if (intra)
{
rl = &rl_intra;
}
else
{
rl = &rl_inter;
}
for (; i <= last_index; i++)
{
const int slevel = block->block[scan_table[i]];
if (slevel)
{
int level;
int run = i - last_non_zero - 1;
last = (i == last_index);
sign = 0;
level = slevel;
if (level < 0)
{
sign = 1;
level = -level;
}
code = get_rl_index(rl, last, run, level);
put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]);
if (code == rl->n)
{
int level1, run1;
level1 = level - rl->max_level[run][last];
if (level1 < 1)
goto esc2;
code = get_rl_index(rl, last, run, level1);
if (code == rl->n)
{
esc2:
put_bits(p, 1, 1);
if (level > 64)
goto esc3;
run1 = run - rl->max_run[level][last] - 1;
if (run1 < 0)
goto esc3;
code = get_rl_index(rl, last, run1, level);
if (code == rl->n)
{
esc3:
/* third escape */
put_bits(p, 1, 1);
put_bits(p, 1, last);
put_bits(p, 6, run);
put_bits(p, 1, 1);
put_bits(p, 12, slevel & 0xfff);
put_bits(p, 1, 1);
}
else
{
/* second escape */
put_bits(p, 1, 0);
put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]);
put_bits(p, 1, sign);
}
}
else
{
/* first escape */
put_bits(p, 1, 0);
put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]);
put_bits(p, 1, sign);
}
}
else
{
put_bits(p, 1, sign);
}
last_non_zero = i;
}
}
#endif
}
static void __inline encode_intra_block(BW *bw, M4V_BLOCK *block, int n)
{
encode_DC(bw, block->block[0], n);
encode_AC(bw, block, 1);
}
static void __inline encode_inter_block(BW *bw, M4V_BLOCK *block)
{
encode_AC(bw, block, 0);
}
// same as H.263
static void __inline encode_intra_I_MCBPC(BW *bw, int cbpc)
{
put_bits(bw, vlce_intra_MCBPC_bits[cbpc], vlce_intra_MCBPC_code[cbpc]);
}
// same as H.263
static void __inline encode_intra_P_MCBPC(BW *bw, int cbpc)
{
put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 4], vlce_inter_MCBPC_code[cbpc + 4]);
}
// same as H.263
static void __inline encode_inter_16x16_MCBPC(BW *bw, int cbpc)
{
put_bits(bw, vlce_inter_MCBPC_bits[cbpc], vlce_inter_MCBPC_code[cbpc]);
}
// same as H.263
static void __inline encode_inter_8x8_MCBPC(BW *bw, int cbpc)
{
put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 16], vlce_inter_MCBPC_code[cbpc + 16]);
}
// same as H.263
static void __inline encode_cbpy(BW *bw, int cbpy)
{
put_bits(bw, vlce_cbpy_bits[cbpy], vlce_cbpy_code[cbpy]);
}
// same as H.263
static void __inline encode_dquant(BW *bw, int dquant)
{
const uint32 dquant_code[5] = {1, 0, -1, 2, 3};
if (dquant)
{
put_bits(bw, 2, dquant_code[dquant + 2]);
}
}
// same as FLV
static void __inline encode_motion(BW *bw, VLCDEC *mv_x, VLCDEC *mv_y)
{
put_vlcdec(bw, mv_x);
if (mv_x->bits_ex)
{
put_bits(bw, 1, mv_x->value_ex & 1);
if (mv_x->bits_ex > 1)
{
put_bits(bw, mv_x->bits_ex - 1, mv_x->value_ex >> 1);
}
}
put_vlcdec(bw, mv_y);
if (mv_y->bits_ex)
{
put_bits(bw, 1, mv_y->value_ex & 1);
if (mv_y->bits_ex > 1)
{
put_bits(bw, mv_y->bits_ex - 1, mv_y->value_ex >> 1);
}
}
}
// same as FLV
static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb)
{
int cbp = 0, cbpc, cbpy;
int i;
for (i = 0; i < 6; i++)
{
if (mb->block[i].last_index >= 0)
{
cbp |= 1 << (5 - i);
}
}
cbpc = cbp & 3;
cbpy = cbp >> 2;
cbpy ^= 0xF;
if (mb->dquant) cbpc += 8;
switch (mb->mv_type)
{
case MV_TYPE_16X16:
encode_inter_16x16_MCBPC(bw, cbpc);
encode_cbpy(bw, cbpy);
encode_dquant(bw, mb->dquant);
encode_motion(bw, &mb->mv_x[0], &mb->mv_y[0]);
break;
case MV_TYPE_8X8:
encode_inter_8x8_MCBPC(bw, cbpc);
encode_cbpy(bw, cbpy);
encode_dquant(bw, mb->dquant);
for (i = 0; i < 4; i++)
{
encode_motion(bw, &mb->mv_x[i], &mb->mv_y[i]);
}
break;
}
for (i = 0; i < 6; i++)
{
encode_inter_block(bw, &mb->block[i]);
}
}
static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int iframe)
{
int cbp = 0, cbpc, cbpy;
int i;
for (i = 0; i < 6; i++)
{
if (mb->block[i].last_index >= 1)
{
cbp |= 1 << (5 - i);
}
}
cbpc = cbp & 3;
if (iframe)
{
if (mb->dquant) cbpc += 4;
encode_intra_I_MCBPC(bw, cbpc);
}
else
{
if (mb->dquant) cbpc += 8;
encode_intra_P_MCBPC(bw, cbpc);
}
put_bits(bw, 1, 0); // AC Prediction = no
cbpy = cbp >> 2;
encode_cbpy(bw, cbpy);
encode_dquant(bw, mb->dquant);
for (i = 0; i < 6; i++)
{
encode_intra_block(bw, &mb->block[i], i);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int __inline encode_vo_header(BW *p)
{
put_bits(p, 16, 0);
put_bits(p, 16, VOS_STARTCODE);
put_bits(p, 8, 1); // *** profile_and_level_indidation
put_bits(p, 16, 0);
put_bits(p, 16, VISUAL_OBJECT_STARTCODE);
put_bits(p, 1, 1);
put_bits(p, 4, 1); // vo_vel_id
put_bits(p, 3, 1); // priority
put_bits(p, 4, 1); // visual_object_type = video object
put_bits(p, 1, 0); // video signal type = no clue
m4v_stuffing(p);
return 0;
}
static int __inline encode_vol_header(BW *p, M4V_VOL *vol)
{
const int vo_number = 0;
const int vol_number = 0;
put_bits(p, 16, 0);
put_bits(p, 16, 0x100 + vo_number);
put_bits(p, 16, 0);
put_bits(p, 16, 0x120 + vol_number);
put_bits(p, 1, 0); // random_accessible_vol
put_bits(p, 8, 1); // video_object_type_indication = Simple Object Type
put_bits(p, 1, 0); //is_object_layer_identifier
put_bits(p, 4, 1); // *** aspect_ratio_info = 1(1:1)
put_bits(p, 1, 0); //vol_control_parameters
put_bits(p, 2, 0); // shape_type
put_bits(p, 1, 1); // marker
if (vol->time_bits != 5) return -1; // for vop_time_increment_resolution = 30
put_bits(p, 16, 30); // *** vop_time_increment_resolution = 30
put_bits(p, 1, 1); // marker
put_bits(p, 1, 0); // fixed vop rate = no
put_bits(p, 1, 1); // marker
put_bits(p, 13, vol->width); // width
put_bits(p, 1, 1); // marker
put_bits(p, 13, vol->height); // height
put_bits(p, 1, 1); // marker
put_bits(p, 1, 0); // progressive = false
put_bits(p, 1, 1); // obmc disable = true
put_bits(p, 1, 0); // sprite = disable
put_bits(p, 1, 0); // not8bit = false
put_bits(p, 1, 0); // quant type = H.263
put_bits(p, 1, 1); // complexity estimaition disable = true
put_bits(p, 1, 1); // resync marker disable = true
put_bits(p, 1, 0); // data pertitioning = false
put_bits(p, 1, 0); // scalability = false
m4v_stuffing(p);
return 0;
}
static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vop_not_coded)
{
// static int time_old = 0;
int time_incr = vop->icount;
if (vop->time != 0)
time_incr = 0;
put_bits(p, 16, 0);
put_bits(p, 16, VOP_STARTCODE);
put_bits(p, 2, vop->picture_type);
// printf("not_code:%d vop_time: %d\n", vop_not_coded, vop->time);
// printf("pic:%d icount:%d vop_time: %d\n", vop->picture_type, time_incr, vop->time);
/* if (time_old > vop->time)
{
put_bits(p, 1, 1);
}
time_old = vop->time;
*/
// !!!!!
while (time_incr--)
put_bits(p, 1, 1);
put_bits(p, 1, 0);
put_bits(p, 1, 1); // marker
put_bits(p, time_bits, vop->time); // time_increment
put_bits(p, 1, 1); // marker
if (vop_not_coded)
{
put_bits(p, 1, 0); // vop coded
return 0;
}
put_bits(p, 1, 1); // vop coded
if (vop->picture_type == M4V_P_TYPE)
{
put_bits(p, 1, vop->rounding_type); // rounding type
}
put_bits(p, 3, 0); // intra dc VLC threashold
put_bits(p, 5, vop->qscale); // qscale
if (vop->picture_type != M4V_I_TYPE)
{
put_bits(p, 3, vop->f_code);
}
if (vop->picture_type == M4V_B_TYPE)
{
put_bits(p, 3, vop->b_code);
}
return 0;
}
static __inline int encode_gop_header(BW *bw, uint32 time_ms)
{
int sec, min, hour;
sec = time_ms / 1000;
min = sec / 60;
sec %= 60;
hour = min / 60;
min %= 60;
hour %= 24;
put_bits(bw, 16, 0);
put_bits(bw, 16, GOP_STARTCODE);
put_bits(bw, 5, hour);
put_bits(bw, 6, min);
put_bits(bw, 1, 1);
put_bits(bw, 6, sec);
put_bits(bw, 1, 0); // closed_gop == NO
put_bits(bw, 1, 0); // broken link == NO
printf("GOP %02d:%02d:%02d\n", hour, min, sec);
m4v_stuffing(bw);
return 0;
}
static int __inline encode_user_header(BW *p)
{
put_bits(p, 16, 0);
put_bits(p, 16, USERDATA_STARTCODE);
put_bits(p, 8, 'v');
put_bits(p, 8, 'i');
put_bits(p, 8, 'x');
put_bits(p, 8, 'y');
put_bits(p, 8, '.');
put_bits(p, 8, 'n');
put_bits(p, 8, 'e');
put_bits(p, 8, 't');
m4v_stuffing(p);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void m4v_encode_m4v_header(BW *bw, M4V_VOL *vol, uint32 time)
{
encode_vo_header(bw);
encode_vol_header(bw, vol);
// encode_gop_header(bw, time);
encode_user_header(bw);
}
void m4v_encode_vop_header(BW *bw, M4V_VOP *vop, int time_bits, int vop_not_coded)
{
encode_vop_header(bw, vop, time_bits, vop_not_coded);
}
void m4v_encode_I_mb(BW *bw, M4V_MICROBLOCK *mb)
{
encode_mb_intra_internal(bw, mb, 1);
}
// same as FLV
void m4v_encode_P_mb(BW *bw, M4V_MICROBLOCK *mb)
{
if (mb->skip)
{
put_bits(bw, 1, 1); // not coded
return;
}
else
{
put_bits(bw, 1, 0); // coded
}
if (mb->intra)
{
encode_mb_intra_internal(bw, mb, 0);
}
else
{
encode_mb_inter_internal(bw, mb);
}
}
int m4v_encode_I_dcpred(M4V_MICROBLOCK *mb, M4V_DCPRED *dcpred, int mb_x, int mb_y)
{
int n;
if (mb->intra)
{
dcpred_set_qscale(dcpred, mb->qscale);
dcpred_set_pos(dcpred, mb_x, mb_y);
for (n = 0; n < 6; n ++)
{
int level = dcpred_for_enc(dcpred, n, mb->block[n].block[0]);
mb->block[n].block[0] = level;
}
}
return 0;
}

View File

@@ -0,0 +1,37 @@
/*
* MPEG4 Bitstream/VLC Encoder
*
* Copyright (c) 2006 vixy project
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef M4VENCODE_H
#define M4VENCODE_H
#include "m4v.h"
#include "bitwriter.h"
void m4v_encode_m4v_header(BW *bw, M4V_VOL *vol, uint32 time);
void m4v_encode_vop_header(BW *bw, M4V_VOP *vop, int time_bits, int vop_not_coded);
void m4v_encode_I_mb(BW *bw, M4V_MICROBLOCK *mb);
void m4v_encode_P_mb(BW *bw, M4V_MICROBLOCK *mb);
int m4v_encode_I_dcpred(M4V_MICROBLOCK *mb, M4V_DCPRED *dcpred, int mb_x, int mb_y);
#endif // M4VENCODE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
/*
* types
*
* Copyright (c) 2006 vixy project
*
* This file is part of VIXY FLV Converter.
*
* 'VIXY FLV Converter' is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 'VIXY FLV Converter' 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef TYPE_H
#define TYPE_H
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _VLCDEC
{
int bits;
int value;
int bits_ex;
int value_ex;
} VLCDEC;
#endif // TYPE_H