lib cleanup and sync for mips vu support

This commit is contained in:
2020-01-05 13:24:19 +01:00
parent ed84d0ac6e
commit 60f6a1f4be
137 changed files with 311 additions and 58 deletions

View File

@@ -0,0 +1,186 @@
/*
* 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 inline int get_br_pos(BR *p)
{
return (p->read << 3) + p->bitoffset;
}
typedef struct _VLCtab
{
int code;
int n;
} VLCtab;
static inline int 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 inline int 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,150 @@
/*
* 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 inline void clear_bw(BW *p)
{
p->pos = 0;
p->bitoffset = 0;
p->tmp = 0;
}
static inline void init_bw(BW *p, uint8 *buf, uint32 size)
{
p->buf = buf;
p->size = size;
clear_bw(p);
}
static inline void 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 inline void 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 inline void pad_to_boundary(BW *p)
{
uint32 bits = 8 - (p->bitoffset % 8);
if (bits < 8)
{
put_bits(p, bits, 0);
}
}
static inline void 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:
break;
}
p->tmp = 0;
p->bitoffset = 0;
}
static inline uint32 get_bw_pos(BW *p)
{
return p->pos * 8 + p->bitoffset;
}
static inline void put_vlcdec(BW *bw, VLCDEC *vlcdec)
{
put_bits(bw, vlcdec->bits, vlcdec->value);
}
// M4V ADDED
static inline void 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,194 @@
/*
* 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 inline int 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 inline void 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 inline int 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

161
libeplayer3/external/flv2mpeg4/src/flv.h vendored Normal file
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,324 @@
/*
* 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,566 @@
/*
* 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 inline int 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 inline int 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 inline int 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 inline int 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 inline int 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 inline int 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 inline int get_cbpy(BR *br)
{
return get_vlc(br, vlc_table_cbpy, 6, 1);
}
static inline int decode_dquant(BR *p)
{
static const int table[4] = { -1, -2, 1, 2 };
return table[get_bits(p, 2)];
}
static inline int 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 inline int 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 inline int 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);
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;
}

139
libeplayer3/external/flv2mpeg4/src/m4v.h vendored Normal file
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,678 @@
/*
* 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 inline void 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 inline void 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 inline void 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 inline void encode_intra_block(BW *bw, M4V_BLOCK *block, int n)
{
encode_DC(bw, block->block[0], n);
encode_AC(bw, block, 1);
}
static inline void encode_inter_block(BW *bw, M4V_BLOCK *block)
{
encode_AC(bw, block, 0);
}
// same as H.263
static inline void 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 inline void 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 inline void 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 inline void 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 inline void encode_cbpy(BW *bw, int cbpy)
{
put_bits(bw, vlce_cbpy_bits[cbpy], vlce_cbpy_code[cbpy]);
}
// same as H.263
static inline void 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 inline void 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 inline void 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 inline void 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 inline int 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 inline int 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 inline int 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 inline int 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