Update avcodec to 20080825

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27556 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2008-09-15 14:09:14 +00:00
parent 7bfcce50a5
commit 65509a25cd
27 changed files with 12497 additions and 8765 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
/*
* MPEG1/2 common code
* Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
*
* 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 FFMPEG_MPEG12_H
#define FFMPEG_MPEG12_H
#include "mpegvideo.h"
#define DC_VLC_BITS 9
#define TEX_VLC_BITS 9
static VLC dc_lum_vlc;
static VLC dc_chroma_vlc;
extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
void ff_mpeg12_common_init(MpegEncContext *s);
void ff_mpeg12_init_vlcs(void);
static inline int decode_dc(GetBitContext *gb, int component)
{
int code, diff;
if (component == 0) {
code = get_vlc2(gb, dc_lum_vlc.table, DC_VLC_BITS, 2);
} else {
code = get_vlc2(gb, dc_chroma_vlc.table, DC_VLC_BITS, 2);
}
if (code < 0){
av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n");
return 0xffff;
}
if (code == 0) {
diff = 0;
} else {
diff = get_xbits(gb, code);
}
return diff;
}
#endif /* FFMPEG_MPEG12_H */

View File

@ -0,0 +1,366 @@
/*
* MPEG1/2 tables
* copyright (c) 2000,2001 Fabrice Bellard
* copyright (c) 2002-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 mpeg12data.c
* MPEG1/2 tables.
*/
#include "mpeg12data.h"
const uint16_t ff_mpeg1_default_intra_matrix[64] = {
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
19, 22, 26, 27, 29, 34, 34, 38,
22, 22, 26, 27, 29, 34, 37, 40,
22, 26, 27, 29, 32, 35, 40, 48,
26, 27, 29, 32, 35, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
const uint16_t ff_mpeg1_default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
};
const uint16_t ff_mpeg12_vlc_dc_lum_code[12] = {
0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff,
};
const unsigned char ff_mpeg12_vlc_dc_lum_bits[12] = {
3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9,
};
const uint16_t ff_mpeg12_vlc_dc_chroma_code[12] = {
0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff,
};
const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12] = {
2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10,
};
static const uint16_t mpeg1_vlc[113][2] = {
{ 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 },
{ 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 },
{ 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 },
{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 },
{ 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 },
{ 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 },
{ 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 },
{ 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 },
{ 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 },
{ 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 },
{ 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 },
{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 },
{ 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 },
{ 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 },
{ 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 },
{ 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 },
{ 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 },
{ 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 },
{ 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 },
{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 },
{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
{ 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 },
{ 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 },
{ 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 },
{ 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 },
{ 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 },
{ 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 },
{ 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 },
{ 0x1, 6 }, /* escape */
{ 0x2, 2 }, /* EOB */
};
static const uint16_t mpeg2_vlc[113][2] = {
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
{0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7},
{0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5},
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6},
{0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9},
{0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16},
{0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12},
{0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13},
{0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16},
{0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16},
{0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16},
{0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12},
{0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13},
{0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16},
{0x1d,16}, {0x1c,16}, {0x1b,16},
{0x01,6}, /* escape */
{0x06,4}, /* EOB */
};
static const int8_t mpeg1_level[111] = {
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,
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 1, 2, 3, 4, 5, 1,
2, 3, 4, 1, 2, 3, 1, 2,
3, 1, 2, 3, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1,
};
static const int8_t mpeg1_run[111] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 15, 15, 16, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31,
};
RLTable ff_rl_mpeg1 = {
111,
111,
mpeg1_vlc,
mpeg1_run,
mpeg1_level,
};
RLTable ff_rl_mpeg2 = {
111,
111,
mpeg2_vlc,
mpeg1_run,
mpeg1_level,
};
const uint8_t ff_mpeg12_mbAddrIncrTable[36][2] = {
{0x1, 1},
{0x3, 3},
{0x2, 3},
{0x3, 4},
{0x2, 4},
{0x3, 5},
{0x2, 5},
{0x7, 7},
{0x6, 7},
{0xb, 8},
{0xa, 8},
{0x9, 8},
{0x8, 8},
{0x7, 8},
{0x6, 8},
{0x17, 10},
{0x16, 10},
{0x15, 10},
{0x14, 10},
{0x13, 10},
{0x12, 10},
{0x23, 11},
{0x22, 11},
{0x21, 11},
{0x20, 11},
{0x1f, 11},
{0x1e, 11},
{0x1d, 11},
{0x1c, 11},
{0x1b, 11},
{0x1a, 11},
{0x19, 11},
{0x18, 11},
{0x8, 11}, /* escape */
{0xf, 11}, /* stuffing */
{0x0, 8}, /* end (and 15 more 0 bits should follow) */
};
const uint8_t ff_mpeg12_mbPatTable[64][2] = {
{0x1, 9},
{0xb, 5},
{0x9, 5},
{0xd, 6},
{0xd, 4},
{0x17, 7},
{0x13, 7},
{0x1f, 8},
{0xc, 4},
{0x16, 7},
{0x12, 7},
{0x1e, 8},
{0x13, 5},
{0x1b, 8},
{0x17, 8},
{0x13, 8},
{0xb, 4},
{0x15, 7},
{0x11, 7},
{0x1d, 8},
{0x11, 5},
{0x19, 8},
{0x15, 8},
{0x11, 8},
{0xf, 6},
{0xf, 8},
{0xd, 8},
{0x3, 9},
{0xf, 5},
{0xb, 8},
{0x7, 8},
{0x7, 9},
{0xa, 4},
{0x14, 7},
{0x10, 7},
{0x1c, 8},
{0xe, 6},
{0xe, 8},
{0xc, 8},
{0x2, 9},
{0x10, 5},
{0x18, 8},
{0x14, 8},
{0x10, 8},
{0xe, 5},
{0xa, 8},
{0x6, 8},
{0x6, 9},
{0x12, 5},
{0x1a, 8},
{0x16, 8},
{0x12, 8},
{0xd, 5},
{0x9, 8},
{0x5, 8},
{0x5, 9},
{0xc, 5},
{0x8, 8},
{0x4, 8},
{0x4, 9},
{0x7, 3},
{0xa, 5},
{0x8, 5},
{0xc, 6}
};
const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = {
{ 0x1, 1 },
{ 0x1, 2 },
{ 0x1, 3 },
{ 0x1, 4 },
{ 0x3, 6 },
{ 0x5, 7 },
{ 0x4, 7 },
{ 0x3, 7 },
{ 0xb, 9 },
{ 0xa, 9 },
{ 0x9, 9 },
{ 0x11, 10 },
{ 0x10, 10 },
{ 0xf, 10 },
{ 0xe, 10 },
{ 0xd, 10 },
{ 0xc, 10 },
};
const AVRational ff_frame_rate_tab[] = {
{ 0, 0},
{24000, 1001},
{ 24, 1},
{ 25, 1},
{30000, 1001},
{ 30, 1},
{ 50, 1},
{60000, 1001},
{ 60, 1},
// Xing's 15fps: (9)
{ 15, 1},
// libmpeg3's "Unofficial economy rates": (10-13)
{ 5, 1},
{ 10, 1},
{ 12, 1},
{ 15, 1},
{ 0, 0},
};
const float ff_mpeg1_aspect[16]={
0.0000,
1.0000,
0.6735,
0.7031,
0.7615,
0.8055,
0.8437,
0.8935,
0.9157,
0.9815,
1.0255,
1.0695,
1.0950,
1.1575,
1.2015,
};
const AVRational ff_mpeg2_aspect[16]={
{0,1},
{1,1},
{4,3},
{16,9},
{221,100},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
};

View File

@ -1,442 +1,56 @@
/*
* MPEG1/2 tables
* copyright (c) 2000,2001 Fabrice Bellard
* copyright (c) 2002-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 mpeg12data.h
* MPEG1/2 tables.
*/
const int16_t ff_mpeg1_default_intra_matrix[64] = {
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
19, 22, 26, 27, 29, 34, 34, 38,
22, 22, 26, 27, 29, 34, 37, 40,
22, 26, 27, 29, 32, 35, 40, 48,
26, 27, 29, 32, 35, 40, 48, 58,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
#ifndef FFMPEG_MPEG12DATA_H
#define FFMPEG_MPEG12DATA_H
const int16_t ff_mpeg1_default_non_intra_matrix[64] = {
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
};
#include <stdint.h>
#include "rational.h"
#include "rl.h"
static const unsigned char vlc_dc_table[256] = {
0, 1, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
extern const uint16_t ff_mpeg1_default_intra_matrix[64];
extern const uint16_t ff_mpeg1_default_non_intra_matrix[64];
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12];
extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12];
extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12];
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
extern RLTable ff_rl_mpeg1;
extern RLTable ff_rl_mpeg2;
static const uint16_t vlc_dc_lum_code[12] = {
0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff,
};
static const unsigned char vlc_dc_lum_bits[12] = {
3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9,
};
extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2];
extern const uint8_t ff_mpeg12_mbPatTable[64][2];
const uint16_t vlc_dc_chroma_code[12] = {
0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff,
};
const unsigned char vlc_dc_chroma_bits[12] = {
2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10,
};
extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2];
static const uint16_t mpeg1_vlc[113][2] = {
{ 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 },
{ 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 },
{ 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 },
{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 },
{ 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 },
{ 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 },
{ 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 },
{ 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 },
{ 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 },
{ 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 },
{ 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 },
{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 },
{ 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 },
{ 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 },
{ 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 },
{ 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 },
{ 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 },
{ 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 },
{ 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 },
{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 },
{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
{ 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 },
{ 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 },
{ 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 },
{ 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 },
{ 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 },
{ 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 },
{ 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 },
{ 0x1, 6 }, /* escape */
{ 0x2, 2 }, /* EOB */
};
extern const AVRational ff_frame_rate_tab[];
static const uint16_t mpeg2_vlc[113][2] = {
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
{0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7},
{0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5},
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6},
{0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9},
{0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16},
{0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12},
{0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13},
{0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16},
{0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16},
{0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16},
{0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12},
{0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13},
{0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16},
{0x1d,16}, {0x1c,16}, {0x1b,16},
{0x01,6}, /* escape */
{0x06,4}, /* EOB */
};
extern const float ff_mpeg1_aspect[16];
extern const AVRational ff_mpeg2_aspect[16];
static const int8_t mpeg1_level[111] = {
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,
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 1, 2, 3, 4, 5, 1,
2, 3, 4, 1, 2, 3, 1, 2,
3, 1, 2, 3, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1,
};
static const int8_t mpeg1_run[111] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 2, 2, 3,
3, 3, 3, 4, 4, 4, 5, 5,
5, 6, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 15, 15, 16, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31,
};
static RLTable rl_mpeg1 = {
111,
111,
mpeg1_vlc,
mpeg1_run,
mpeg1_level,
};
static RLTable rl_mpeg2 = {
111,
111,
mpeg2_vlc,
mpeg1_run,
mpeg1_level,
};
static const uint8_t mbAddrIncrTable[36][2] = {
{0x1, 1},
{0x3, 3},
{0x2, 3},
{0x3, 4},
{0x2, 4},
{0x3, 5},
{0x2, 5},
{0x7, 7},
{0x6, 7},
{0xb, 8},
{0xa, 8},
{0x9, 8},
{0x8, 8},
{0x7, 8},
{0x6, 8},
{0x17, 10},
{0x16, 10},
{0x15, 10},
{0x14, 10},
{0x13, 10},
{0x12, 10},
{0x23, 11},
{0x22, 11},
{0x21, 11},
{0x20, 11},
{0x1f, 11},
{0x1e, 11},
{0x1d, 11},
{0x1c, 11},
{0x1b, 11},
{0x1a, 11},
{0x19, 11},
{0x18, 11},
{0x8, 11}, /* escape */
{0xf, 11}, /* stuffing */
{0x0, 8}, /* end (and 15 more 0 bits should follow) */
};
static const uint8_t mbPatTable[63][2] = {
{0xb, 5},
{0x9, 5},
{0xd, 6},
{0xd, 4},
{0x17, 7},
{0x13, 7},
{0x1f, 8},
{0xc, 4},
{0x16, 7},
{0x12, 7},
{0x1e, 8},
{0x13, 5},
{0x1b, 8},
{0x17, 8},
{0x13, 8},
{0xb, 4},
{0x15, 7},
{0x11, 7},
{0x1d, 8},
{0x11, 5},
{0x19, 8},
{0x15, 8},
{0x11, 8},
{0xf, 6},
{0xf, 8},
{0xd, 8},
{0x3, 9},
{0xf, 5},
{0xb, 8},
{0x7, 8},
{0x7, 9},
{0xa, 4},
{0x14, 7},
{0x10, 7},
{0x1c, 8},
{0xe, 6},
{0xe, 8},
{0xc, 8},
{0x2, 9},
{0x10, 5},
{0x18, 8},
{0x14, 8},
{0x10, 8},
{0xe, 5},
{0xa, 8},
{0x6, 8},
{0x6, 9},
{0x12, 5},
{0x1a, 8},
{0x16, 8},
{0x12, 8},
{0xd, 5},
{0x9, 8},
{0x5, 8},
{0x5, 9},
{0xc, 5},
{0x8, 8},
{0x4, 8},
{0x4, 9},
{0x7, 3},
{0xa, 5},
{0x8, 5},
{0xc, 6}
};
#define MB_TYPE_ZERO_MV 0x20000000
#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV)
static const uint8_t table_mb_ptype[7][2] = {
{ 3, 5 }, // 0x01 MB_INTRA
{ 1, 2 }, // 0x02 MB_PAT
{ 1, 3 }, // 0x08 MB_FOR
{ 1, 1 }, // 0x0A MB_FOR|MB_PAT
{ 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
{ 1, 5 }, // 0x12 MB_QUANT|MB_PAT
{ 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
};
static const uint32_t ptype2mb_type[7] = {
MB_TYPE_INTRA,
MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
};
static const uint8_t table_mb_btype[11][2] = {
{ 3, 5 }, // 0x01 MB_INTRA
{ 2, 3 }, // 0x04 MB_BACK
{ 3, 3 }, // 0x06 MB_BACK|MB_PAT
{ 2, 4 }, // 0x08 MB_FOR
{ 3, 4 }, // 0x0A MB_FOR|MB_PAT
{ 2, 2 }, // 0x0C MB_FOR|MB_BACK
{ 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
{ 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
{ 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
{ 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
{ 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
};
static const uint32_t btype2mb_type[11] = {
MB_TYPE_INTRA,
MB_TYPE_L1,
MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_L0L1,
MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
};
static const uint8_t mbMotionVectorTable[17][2] = {
{ 0x1, 1 },
{ 0x1, 2 },
{ 0x1, 3 },
{ 0x1, 4 },
{ 0x3, 6 },
{ 0x5, 7 },
{ 0x4, 7 },
{ 0x3, 7 },
{ 0xb, 9 },
{ 0xa, 9 },
{ 0x9, 9 },
{ 0x11, 10 },
{ 0x10, 10 },
{ 0xf, 10 },
{ 0xe, 10 },
{ 0xd, 10 },
{ 0xc, 10 },
};
#define MPEG1_FRAME_RATE_BASE 1001
static const int frame_rate_tab[16] = {
0,
24000,
24024,
25025,
30000,
30030,
50050,
60000,
60060,
// Xing's 15fps: (9)
15015,
// libmpeg3's "Unofficial economy rates": (10-13)
5005,
10010,
12012,
15015,
// random, just to avoid segfault !never encode these
25025,
25025,
};
static const uint8_t non_linear_qscale[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8,10,12,14,16,18,20,22,
24,28,32,36,40,44,48,52,
56,64,72,80,88,96,104,112,
};
uint8_t ff_mpeg1_dc_scale_table[128]={ // MN: mpeg2 really can have such large qscales?
// 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
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
static const float mpeg1_aspect[16]={
0.0000,
1.0000,
0.6735,
0.7031,
0.7615,
0.8055,
0.8437,
0.8935,
0.9157,
0.9815,
1.0255,
1.0695,
1.0950,
1.1575,
1.2015,
};
static const AVRational mpeg2_aspect[16]={
{0,1},
{1,1},
{4,3},
{16,9},
{221,100},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
{0,1},
};
static const uint8_t svcd_scan_offset_placeholder[14]={
0x10, 0x0E,
0x00, 0x80, 0x81,
0x00, 0x80, 0x81,
0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
};
#endif /* FFMPEG_MPEG12DATA_H */

View File

@ -0,0 +1,124 @@
/*
* MPEG1/2 decoder tables
* copyright (c) 2000,2001 Fabrice Bellard
* copyright (c) 2002-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 mpeg12decdata.h
* MPEG1/2 decoder tables.
*/
#ifndef FFMPEG_MPEG12DECDATA_H
#define FFMPEG_MPEG12DECDATA_H
#include <stdint.h>
#include "mpegvideo.h"
#define MB_TYPE_ZERO_MV 0x20000000
#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV)
static const uint8_t table_mb_ptype[7][2] = {
{ 3, 5 }, // 0x01 MB_INTRA
{ 1, 2 }, // 0x02 MB_PAT
{ 1, 3 }, // 0x08 MB_FOR
{ 1, 1 }, // 0x0A MB_FOR|MB_PAT
{ 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
{ 1, 5 }, // 0x12 MB_QUANT|MB_PAT
{ 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
};
static const uint32_t ptype2mb_type[7] = {
MB_TYPE_INTRA,
MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
};
static const uint8_t table_mb_btype[11][2] = {
{ 3, 5 }, // 0x01 MB_INTRA
{ 2, 3 }, // 0x04 MB_BACK
{ 3, 3 }, // 0x06 MB_BACK|MB_PAT
{ 2, 4 }, // 0x08 MB_FOR
{ 3, 4 }, // 0x0A MB_FOR|MB_PAT
{ 2, 2 }, // 0x0C MB_FOR|MB_BACK
{ 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
{ 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
{ 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
{ 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
{ 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
};
static const uint32_t btype2mb_type[11] = {
MB_TYPE_INTRA,
MB_TYPE_L1,
MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_L0L1,
MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
};
static const uint8_t non_linear_qscale[32] = {
0, 1, 2, 3, 4, 5, 6, 7,
8,10,12,14,16,18,20,22,
24,28,32,36,40,44,48,52,
56,64,72,80,88,96,104,112,
};
static const uint8_t mpeg2_dc_scale_table1[128]={
// 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
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
};
static const uint8_t mpeg2_dc_scale_table2[128]={
// 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
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};
static const uint8_t mpeg2_dc_scale_table3[128]={
// 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
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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
static const uint8_t * const mpeg2_dc_scale_table[4]={
ff_mpeg1_dc_scale_table,
mpeg2_dc_scale_table1,
mpeg2_dc_scale_table2,
mpeg2_dc_scale_table3,
};
#endif /* FFMPEG_MPEG12DECDATA_H */

View File

@ -0,0 +1,956 @@
/*
* MPEG1/2 encoder
* Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-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 mpeg12enc.c
* MPEG1/2 encoder
*/
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "mpeg12.h"
#include "mpeg12data.h"
#include "bytestream.h"
static const uint8_t inv_non_linear_qscale[13] = {
0, 2, 4, 6, 8,
9,10,11,12,13,14,15,16,
};
static const uint8_t svcd_scan_offset_placeholder[14] = {
0x10, 0x0E,
0x00, 0x80, 0x81,
0x00, 0x80, 0x81,
0xff, 0xff, 0xff,
0xff, 0xff, 0xff,
};
static void mpeg1_encode_block(MpegEncContext *s,
DCTELEM *block,
int component);
static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added
static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
static uint8_t fcode_tab[MAX_MV*2+1];
static uint8_t uni_mpeg1_ac_vlc_len [64*64*2];
static uint8_t uni_mpeg2_ac_vlc_len [64*64*2];
/* simple include everything table for dc, first byte is bits number next 3 are code*/
static uint32_t mpeg1_lum_dc_uni[512];
static uint32_t mpeg1_chr_dc_uni[512];
static uint8_t mpeg1_index_run[2][64];
static int8_t mpeg1_max_level[2][64];
static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){
int i;
for(i=0; i<128; i++){
int level= i-64;
int run;
for(run=0; run<64; run++){
int len, bits, code;
int alevel= FFABS(level);
int sign= (level>>31)&1;
if (alevel > rl->max_level[0][run])
code= 111; /*rl->n*/
else
code= rl->index_run[0][run] + alevel - 1;
if (code < 111 /* rl->n */) {
/* store the vlc & sign at once */
len= rl->table_vlc[code][1]+1;
bits= (rl->table_vlc[code][0]<<1) + sign;
} else {
len= rl->table_vlc[111/*rl->n*/][1]+6;
bits= rl->table_vlc[111/*rl->n*/][0]<<6;
bits|= run;
if (alevel < 128) {
bits<<=8; len+=8;
bits|= level & 0xff;
} else {
bits<<=16; len+=16;
bits|= level & 0xff;
if (level < 0) {
bits|= 0x8001 + level + 255;
} else {
bits|= level & 0xffff;
}
}
}
uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len;
}
}
}
static int find_frame_rate_index(MpegEncContext *s){
int i;
int64_t dmin= INT64_MAX;
int64_t d;
for(i=1;i<14;i++) {
int64_t n0= 1001LL/ff_frame_rate_tab[i].den*ff_frame_rate_tab[i].num*s->avctx->time_base.num;
int64_t n1= 1001LL*s->avctx->time_base.den;
if(s->avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL && i>=9) break;
d = FFABS(n0 - n1);
if(d < dmin){
dmin=d;
s->frame_rate_index= i;
}
}
if(dmin)
return -1;
else
return 0;
}
static av_cold int encode_init(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
if(MPV_encode_init(avctx) < 0)
return -1;
if(find_frame_rate_index(s) < 0){
if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num);
return -1;
}else{
av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num);
}
}
if(avctx->profile == FF_PROFILE_UNKNOWN){
if(avctx->level != FF_LEVEL_UNKNOWN){
av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
return -1;
}
avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */
}
if(avctx->level == FF_LEVEL_UNKNOWN){
if(avctx->profile == 0){ /* 4:2:2 */
if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */
else avctx->level = 2; /* High */
}else{
if(avctx->profile != 1 && s->chroma_format != CHROMA_420){
av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n");
return -1;
}
if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */
else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */
else avctx->level = 4; /* High */
}
}
if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){
av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n");
return -1;
}
return 0;
}
static void put_header(MpegEncContext *s, int header)
{
align_put_bits(&s->pb);
put_bits(&s->pb, 16, header>>16);
put_sbits(&s->pb, 16, header);
}
/* put sequence header if needed */
static void mpeg1_encode_sequence_header(MpegEncContext *s)
{
unsigned int vbv_buffer_size;
unsigned int fps, v;
int i;
uint64_t time_code;
float best_aspect_error= 1E10;
float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio);
int constraint_parameter_flag;
if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA)
if (s->current_picture.key_frame) {
AVRational framerate= ff_frame_rate_tab[s->frame_rate_index];
/* mpeg1 header repeated every gop */
put_header(s, SEQ_START_CODE);
put_sbits(&s->pb, 12, s->width );
put_sbits(&s->pb, 12, s->height);
for(i=1; i<15; i++){
float error= aspect_ratio;
if(s->codec_id == CODEC_ID_MPEG1VIDEO || i <=1)
error-= 1.0/ff_mpeg1_aspect[i];
else
error-= av_q2d(ff_mpeg2_aspect[i])*s->height/s->width;
error= FFABS(error);
if(error < best_aspect_error){
best_aspect_error= error;
s->aspect_ratio_info= i;
}
}
put_bits(&s->pb, 4, s->aspect_ratio_info);
put_bits(&s->pb, 4, s->frame_rate_index);
if(s->avctx->rc_max_rate){
v = (s->avctx->rc_max_rate + 399) / 400;
if (v > 0x3ffff && s->codec_id == CODEC_ID_MPEG1VIDEO)
v = 0x3ffff;
}else{
v= 0x3FFFF;
}
if(s->avctx->rc_buffer_size)
vbv_buffer_size = s->avctx->rc_buffer_size;
else
/* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */
vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024;
vbv_buffer_size= (vbv_buffer_size + 16383) / 16384;
put_sbits(&s->pb, 18, v);
put_bits(&s->pb, 1, 1); /* marker */
put_sbits(&s->pb, 10, vbv_buffer_size);
constraint_parameter_flag=
s->width <= 768 && s->height <= 576 &&
s->mb_width * s->mb_height <= 396 &&
s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 &&
framerate.num <= framerate.den*30 &&
s->avctx->me_range && s->avctx->me_range < 128 &&
vbv_buffer_size <= 20 &&
v <= 1856000/400 &&
s->codec_id == CODEC_ID_MPEG1VIDEO;
put_bits(&s->pb, 1, constraint_parameter_flag);
ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
if(s->codec_id == CODEC_ID_MPEG2VIDEO){
put_header(s, EXT_START_CODE);
put_bits(&s->pb, 4, 1); //seq ext
put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */
put_bits(&s->pb, 3, s->avctx->profile); //profile
put_bits(&s->pb, 4, s->avctx->level); //level
put_bits(&s->pb, 1, s->progressive_sequence);
put_bits(&s->pb, 2, s->chroma_format);
put_bits(&s->pb, 2, s->width >>12);
put_bits(&s->pb, 2, s->height>>12);
put_bits(&s->pb, 12, v>>18); //bitrate ext
put_bits(&s->pb, 1, 1); //marker
put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext
put_bits(&s->pb, 1, s->low_delay);
put_bits(&s->pb, 2, 0); // frame_rate_ext_n
put_bits(&s->pb, 5, 0); // frame_rate_ext_d
}
put_header(s, GOP_START_CODE);
put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */
/* time code : we must convert from the real frame rate to a
fake mpeg frame rate in case of low frame rate */
fps = (framerate.num + framerate.den/2)/ framerate.den;
time_code = s->current_picture_ptr->coded_picture_number + s->avctx->timecode_frame_start;
s->gop_picture_number = s->current_picture_ptr->coded_picture_number;
if (s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) {
/* only works for NTSC 29.97 */
int d = time_code / 17982;
int m = time_code % 17982;
//if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
time_code += 18 * d + 2 * ((m - 2) / 1798);
}
put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
put_bits(&s->pb, 1, 1);
put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP));
put_bits(&s->pb, 1, 0); /* broken link */
}
}
static inline void encode_mb_skip_run(MpegEncContext *s, int run){
while (run >= 33) {
put_bits(&s->pb, 11, 0x008);
run -= 33;
}
put_bits(&s->pb, ff_mpeg12_mbAddrIncrTable[run][1],
ff_mpeg12_mbAddrIncrTable[run][0]);
}
static av_always_inline void put_qscale(MpegEncContext *s)
{
if(s->q_scale_type){
assert(s->qscale>=1 && s->qscale <=12);
put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]);
}else{
put_bits(&s->pb, 5, s->qscale);
}
}
void ff_mpeg1_encode_slice_header(MpegEncContext *s){
put_header(s, SLICE_MIN_START_CODE + s->mb_y);
put_qscale(s);
put_bits(&s->pb, 1, 0); /* slice extra information */
}
void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
{
mpeg1_encode_sequence_header(s);
/* mpeg1 picture header */
put_header(s, PICTURE_START_CODE);
/* temporal reference */
// RAL: s->picture_number instead of s->fake_picture_number
put_bits(&s->pb, 10, (s->picture_number -
s->gop_picture_number) & 0x3ff);
put_bits(&s->pb, 3, s->pict_type);
s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8;
put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */
// RAL: Forward f_code also needed for B frames
if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) {
put_bits(&s->pb, 1, 0); /* half pel coordinates */
if(s->codec_id == CODEC_ID_MPEG1VIDEO)
put_bits(&s->pb, 3, s->f_code); /* forward_f_code */
else
put_bits(&s->pb, 3, 7); /* forward_f_code */
}
// RAL: Backward f_code necessary for B frames
if (s->pict_type == FF_B_TYPE) {
put_bits(&s->pb, 1, 0); /* half pel coordinates */
if(s->codec_id == CODEC_ID_MPEG1VIDEO)
put_bits(&s->pb, 3, s->b_code); /* backward_f_code */
else
put_bits(&s->pb, 3, 7); /* backward_f_code */
}
put_bits(&s->pb, 1, 0); /* extra bit picture */
s->frame_pred_frame_dct = 1;
if(s->codec_id == CODEC_ID_MPEG2VIDEO){
put_header(s, EXT_START_CODE);
put_bits(&s->pb, 4, 8); //pic ext
if (s->pict_type == FF_P_TYPE || s->pict_type == FF_B_TYPE) {
put_bits(&s->pb, 4, s->f_code);
put_bits(&s->pb, 4, s->f_code);
}else{
put_bits(&s->pb, 8, 255);
}
if (s->pict_type == FF_B_TYPE) {
put_bits(&s->pb, 4, s->b_code);
put_bits(&s->pb, 4, s->b_code);
}else{
put_bits(&s->pb, 8, 255);
}
put_bits(&s->pb, 2, s->intra_dc_precision);
assert(s->picture_structure == PICT_FRAME);
put_bits(&s->pb, 2, s->picture_structure);
if (s->progressive_sequence) {
put_bits(&s->pb, 1, 0); /* no repeat */
} else {
put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first);
}
/* XXX: optimize the generation of this flag with entropy
measures */
s->frame_pred_frame_dct = s->progressive_sequence;
put_bits(&s->pb, 1, s->frame_pred_frame_dct);
put_bits(&s->pb, 1, s->concealment_motion_vectors);
put_bits(&s->pb, 1, s->q_scale_type);
put_bits(&s->pb, 1, s->intra_vlc_format);
put_bits(&s->pb, 1, s->alternate_scan);
put_bits(&s->pb, 1, s->repeat_first_field);
s->progressive_frame = s->progressive_sequence;
put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */
put_bits(&s->pb, 1, s->progressive_frame);
put_bits(&s->pb, 1, 0); //composite_display_flag
}
if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){
int i;
put_header(s, USER_START_CODE);
for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){
put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
}
}
s->mb_y=0;
ff_mpeg1_encode_slice_header(s);
}
static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
int has_mv, int field_motion)
{
put_bits(&s->pb, n, bits);
if (!s->frame_pred_frame_dct) {
if (has_mv)
put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */
put_bits(&s->pb, 1, s->interlaced_dct);
}
}
static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
DCTELEM block[6][64],
int motion_x, int motion_y,
int mb_block_count)
{
int i, cbp;
const int mb_x = s->mb_x;
const int mb_y = s->mb_y;
const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;
/* compute cbp */
cbp = 0;
for(i=0;i<mb_block_count;i++) {
if (s->block_last_index[i] >= 0)
cbp |= 1 << (mb_block_count - 1 - i);
}
if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
(mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
((s->pict_type == FF_P_TYPE && (motion_x | motion_y) == 0) ||
(s->pict_type == FF_B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
s->mb_skip_run++;
s->qscale -= s->dquant;
s->skip_count++;
s->misc_bits++;
s->last_bits++;
if(s->pict_type == FF_P_TYPE){
s->last_mv[0][1][0]= s->last_mv[0][0][0]=
s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
}
} else {
if(first_mb){
assert(s->mb_skip_run == 0);
encode_mb_skip_run(s, s->mb_x);
}else{
encode_mb_skip_run(s, s->mb_skip_run);
}
if (s->pict_type == FF_I_TYPE) {
if(s->dquant && cbp){
put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */
put_qscale(s);
}else{
put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */
s->qscale -= s->dquant;
}
s->misc_bits+= get_bits_diff(s);
s->i_count++;
} else if (s->mb_intra) {
if(s->dquant && cbp){
put_mb_modes(s, 6, 0x01, 0, 0);
put_qscale(s);
}else{
put_mb_modes(s, 5, 0x03, 0, 0);
s->qscale -= s->dquant;
}
s->misc_bits+= get_bits_diff(s);
s->i_count++;
memset(s->last_mv, 0, sizeof(s->last_mv));
} else if (s->pict_type == FF_P_TYPE) {
if(s->mv_type == MV_TYPE_16X16){
if (cbp != 0) {
if ((motion_x|motion_y) == 0) {
if(s->dquant){
put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */
put_qscale(s);
}else{
put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */
}
s->misc_bits+= get_bits_diff(s);
} else {
if(s->dquant){
put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */
put_qscale(s);
}else{
put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */
}
s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->mv_bits+= get_bits_diff(s);
}
} else {
put_bits(&s->pb, 3, 1); /* motion only */
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
s->misc_bits+= get_bits_diff(s);
mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added
mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added
s->qscale -= s->dquant;
s->mv_bits+= get_bits_diff(s);
}
s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;
s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;
}else{
assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
if (cbp) {
if(s->dquant){
put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */
put_qscale(s);
}else{
put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */
}
} else {
put_bits(&s->pb, 3, 1); /* motion only */
put_bits(&s->pb, 2, 1); /* motion_type: field */
s->qscale -= s->dquant;
}
s->misc_bits+= get_bits_diff(s);
for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[0][i]);
mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= 2*s->mv[0][i][1];
}
s->mv_bits+= get_bits_diff(s);
}
if(cbp) {
if (s->chroma_y_shift) {
put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]);
} else {
put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]);
put_sbits(&s->pb, 2, cbp);
}
}
s->f_count++;
} else{
if(s->mv_type == MV_TYPE_16X16){
if (cbp){ // With coded bloc pattern
if (s->dquant) {
if(s->mv_dir == MV_DIR_FORWARD)
put_mb_modes(s, 6, 3, 1, 0);
else
put_mb_modes(s, 8-s->mv_dir, 2, 1, 0);
put_qscale(s);
} else {
put_mb_modes(s, 5-s->mv_dir, 3, 1, 0);
}
}else{ // No coded bloc pattern
put_bits(&s->pb, 5-s->mv_dir, 2);
if (!s->frame_pred_frame_dct)
put_bits(&s->pb, 2, 2); /* motion_type: frame */
s->qscale -= s->dquant;
}
s->misc_bits += get_bits_diff(s);
if (s->mv_dir&MV_DIR_FORWARD){
mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];
s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];
s->f_count++;
}
if (s->mv_dir&MV_DIR_BACKWARD){
mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];
s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];
s->b_count++;
}
}else{
assert(s->mv_type == MV_TYPE_FIELD);
assert(!s->frame_pred_frame_dct);
if (cbp){ // With coded bloc pattern
if (s->dquant) {
if(s->mv_dir == MV_DIR_FORWARD)
put_mb_modes(s, 6, 3, 1, 1);
else
put_mb_modes(s, 8-s->mv_dir, 2, 1, 1);
put_qscale(s);
} else {
put_mb_modes(s, 5-s->mv_dir, 3, 1, 1);
}
}else{ // No coded bloc pattern
put_bits(&s->pb, 5-s->mv_dir, 2);
put_bits(&s->pb, 2, 1); /* motion_type: field */
s->qscale -= s->dquant;
}
s->misc_bits += get_bits_diff(s);
if (s->mv_dir&MV_DIR_FORWARD){
for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[0][i]);
mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code);
mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
s->last_mv[0][i][0]= s->mv[0][i][0];
s->last_mv[0][i][1]= 2*s->mv[0][i][1];
}
s->f_count++;
}
if (s->mv_dir&MV_DIR_BACKWARD){
for(i=0; i<2; i++){
put_bits(&s->pb, 1, s->field_select[1][i]);
mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code);
mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);
s->last_mv[1][i][0]= s->mv[1][i][0];
s->last_mv[1][i][1]= 2*s->mv[1][i][1];
}
s->b_count++;
}
}
s->mv_bits += get_bits_diff(s);
if(cbp) {
if (s->chroma_y_shift) {
put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]);
} else {
put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]);
put_sbits(&s->pb, 2, cbp);
}
}
}
for(i=0;i<mb_block_count;i++) {
if (cbp & (1 << (mb_block_count - 1 - i))) {
mpeg1_encode_block(s, block[i], i);
}
}
s->mb_skip_run = 0;
if(s->mb_intra)
s->i_tex_bits+= get_bits_diff(s);
else
s->p_tex_bits+= get_bits_diff(s);
}
}
void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y)
{
if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6);
else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8);
}
// RAL: Parameter added: f_or_b_code
static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
{
int code, bit_size, l, bits, range, sign;
if (val == 0) {
/* zero vector */
code = 0;
put_bits(&s->pb,
ff_mpeg12_mbMotionVectorTable[0][1],
ff_mpeg12_mbMotionVectorTable[0][0]);
} else {
bit_size = f_or_b_code - 1;
range = 1 << bit_size;
/* modulo encoding */
l= INT_BIT - 5 - bit_size;
val= (val<<l)>>l;
if (val >= 0) {
val--;
code = (val >> bit_size) + 1;
bits = val & (range - 1);
sign = 0;
} else {
val = -val;
val--;
code = (val >> bit_size) + 1;
bits = val & (range - 1);
sign = 1;
}
assert(code > 0 && code <= 16);
put_bits(&s->pb,
ff_mpeg12_mbMotionVectorTable[code][1],
ff_mpeg12_mbMotionVectorTable[code][0]);
put_bits(&s->pb, 1, sign);
if (bit_size > 0) {
put_bits(&s->pb, bit_size, bits);
}
}
}
void ff_mpeg1_encode_init(MpegEncContext *s)
{
static int done=0;
ff_mpeg12_common_init(s);
if(!done){
int f_code;
int mv;
int i;
done=1;
init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
for(i=0; i<64; i++)
{
mpeg1_max_level[0][i]= ff_rl_mpeg1.max_level[0][i];
mpeg1_index_run[0][i]= ff_rl_mpeg1.index_run[0][i];
}
init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len);
if(s->intra_vlc_format)
init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len);
/* build unified dc encoding tables */
for(i=-255; i<256; i++)
{
int adiff, index;
int bits, code;
int diff=i;
adiff = FFABS(diff);
if(diff<0) diff--;
index = av_log2(2*adiff);
bits= ff_mpeg12_vlc_dc_lum_bits[index] + index;
code= (ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1));
mpeg1_lum_dc_uni[i+255]= bits + (code<<8);
bits= ff_mpeg12_vlc_dc_chroma_bits[index] + index;
code= (ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1));
mpeg1_chr_dc_uni[i+255]= bits + (code<<8);
}
for(f_code=1; f_code<=MAX_FCODE; f_code++){
for(mv=-MAX_MV; mv<=MAX_MV; mv++){
int len;
if(mv==0) len= ff_mpeg12_mbMotionVectorTable[0][1];
else{
int val, bit_size, range, code;
bit_size = f_code - 1;
range = 1 << bit_size;
val=mv;
if (val < 0)
val = -val;
val--;
code = (val >> bit_size) + 1;
if(code<17){
len= ff_mpeg12_mbMotionVectorTable[code][1] + 1 + bit_size;
}else{
len= ff_mpeg12_mbMotionVectorTable[16][1] + 2 + bit_size;
}
}
mv_penalty[f_code][mv+MAX_MV]= len;
}
}
for(f_code=MAX_FCODE; f_code>0; f_code--){
for(mv=-(8<<f_code); mv<(8<<f_code); mv++){
fcode_tab[mv+MAX_MV]= f_code;
}
}
}
s->me.mv_penalty= mv_penalty;
s->fcode_tab= fcode_tab;
if(s->codec_id == CODEC_ID_MPEG1VIDEO){
s->min_qcoeff=-255;
s->max_qcoeff= 255;
}else{
s->min_qcoeff=-2047;
s->max_qcoeff= 2047;
}
if (s->intra_vlc_format) {
s->intra_ac_vlc_length=
s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len;
} else {
s->intra_ac_vlc_length=
s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len;
}
s->inter_ac_vlc_length=
s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len;
}
static inline void encode_dc(MpegEncContext *s, int diff, int component)
{
if(((unsigned) (diff+255)) >= 511){
int index;
if(diff<0){
index= av_log2_16bit(-2*diff);
diff--;
}else{
index= av_log2_16bit(2*diff);
}
if (component == 0) {
put_bits(
&s->pb,
ff_mpeg12_vlc_dc_lum_bits[index] + index,
(ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)));
}else{
put_bits(
&s->pb,
ff_mpeg12_vlc_dc_chroma_bits[index] + index,
(ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)));
}
}else{
if (component == 0) {
put_bits(
&s->pb,
mpeg1_lum_dc_uni[diff+255]&0xFF,
mpeg1_lum_dc_uni[diff+255]>>8);
} else {
put_bits(
&s->pb,
mpeg1_chr_dc_uni[diff+255]&0xFF,
mpeg1_chr_dc_uni[diff+255]>>8);
}
}
}
static void mpeg1_encode_block(MpegEncContext *s,
DCTELEM *block,
int n)
{
int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
int code, component;
const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc;
last_index = s->block_last_index[n];
/* DC coef */
if (s->mb_intra) {
component = (n <= 3 ? 0 : (n&1) + 1);
dc = block[0]; /* overflow is impossible */
diff = dc - s->last_dc[component];
encode_dc(s, diff, component);
s->last_dc[component] = dc;
i = 1;
if (s->intra_vlc_format)
table_vlc = ff_rl_mpeg2.table_vlc;
} else {
/* encode the first coefficient : needs to be done here because
it is handled slightly differently */
level = block[0];
if (abs(level) == 1) {
code = ((uint32_t)level >> 31); /* the sign bit */
put_bits(&s->pb, 2, code | 0x02);
i = 1;
} else {
i = 0;
last_non_zero = -1;
goto next_coef;
}
}
/* now quantify & encode AC coefs */
last_non_zero = i - 1;
for(;i<=last_index;i++) {
j = s->intra_scantable.permutated[i];
level = block[j];
next_coef:
#if 0
if (level != 0)
dprintf(s->avctx, "level[%d]=%d\n", i, level);
#endif
/* encode using VLC */
if (level != 0) {
run = i - last_non_zero - 1;
alevel= level;
MASK_ABS(sign, alevel)
sign&=1;
if (alevel <= mpeg1_max_level[0][run]){
code= mpeg1_index_run[0][run] + alevel - 1;
/* store the vlc & sign at once */
put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign);
} else {
/* escape seems to be pretty rare <5% so I do not optimize it */
put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]);
/* escape: only clip in this case */
put_bits(&s->pb, 6, run);
if(s->codec_id == CODEC_ID_MPEG1VIDEO){
if (alevel < 128) {
put_sbits(&s->pb, 8, level);
} else {
if (level < 0) {
put_bits(&s->pb, 16, 0x8001 + level + 255);
} else {
put_sbits(&s->pb, 16, level);
}
}
}else{
put_sbits(&s->pb, 12, level);
}
}
last_non_zero = i;
}
}
/* end of block */
put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]);
}
AVCodec mpeg1video_encoder = {
"mpeg1video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG1VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
.supported_framerates= ff_frame_rate_tab+1,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.capabilities= CODEC_CAP_DELAY,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
};
AVCodec mpeg2video_encoder = {
"mpeg2video",
CODEC_TYPE_VIDEO,
CODEC_ID_MPEG2VIDEO,
sizeof(MpegEncContext),
encode_init,
MPV_encode_picture,
MPV_encode_end,
.supported_framerates= ff_frame_rate_tab+1,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE},
.capabilities= CODEC_CAP_DELAY,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"),
};

View File

@ -0,0 +1,83 @@
/*
* MPEG-4 Audio common code
* 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
*/
#include "bitstream.h"
#include "mpeg4audio.h"
const int ff_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 == 31)
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) :
ff_mpeg4audio_sample_rates[*index];
}
int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size)
{
GetBitContext gb;
int specific_config_bitindex;
init_get_bits(&gb, buf, buf_size*8);
c->object_type = get_object_type(&gb);
c->sample_rate = get_sample_rate(&gb, &c->sampling_index);
c->chan_config = get_bits(&gb, 4);
c->sbr = -1;
if (c->object_type == 5) {
c->ext_object_type = c->object_type;
c->sbr = 1;
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
c->object_type = get_object_type(&gb);
} else
c->ext_object_type = 0;
specific_config_bitindex = get_bits_count(&gb);
if (c->ext_object_type != 5) {
int bits_left = buf_size*8 - specific_config_bitindex;
for (; bits_left > 15; bits_left--) {
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 == 5 && (c->sbr = get_bits1(&gb)) == 1)
c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
break;
} else
get_bits1(&gb); // skip 1 bit
}
}
return specific_config_bitindex;
}

View File

@ -0,0 +1,49 @@
/*
* 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 FFMPEG_MPEG4AUDIO_H
#define FFMPEG_MPEG4AUDIO_H
#include <stdint.h>
typedef struct {
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;
} MPEG4AudioConfig;
extern const int ff_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] buf_size Extradata size.
* @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata.
*/
int ff_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int buf_size);
#endif /* FFMPEG_MPEGAUDIO_H */

View File

@ -1,8 +1,36 @@
/*
* copyright (c) 2000,2001 Fabrice Bellard
* H263+ support
* copyright (c) 2002-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 mpeg4data.h
* mpeg4 tables.
*/
#ifndef FFMPEG_MPEG4DATA_H
#define FFMPEG_MPEG4DATA_H
#include <stdint.h>
#include "mpegvideo.h"
// shapes
#define RECT_SHAPE 0
#define BIN_SHAPE 1
@ -123,7 +151,8 @@ static RLTable rl_intra = {
intra_level,
};
static const uint16_t inter_rvlc[170][2]={ //note this is identical to the intra rvlc except that its reordered
/* Note this is identical to the intra rvlc except that it is reordered. */
static const uint16_t inter_rvlc[170][2]={
{0x0006, 3},{0x0001, 4},{0x0004, 5},{0x001C, 7},
{0x003C, 8},{0x003D, 8},{0x007C, 9},{0x00FC, 10},
{0x00FD, 10},{0x01FC, 11},{0x01FD, 11},{0x03FC, 12},
@ -169,7 +198,7 @@ static const uint16_t inter_rvlc[170][2]={ //note this is identical to the intra
{0x3F7C, 15},{0x3F7D, 15},{0x0000, 4}
};
static const uint8_t inter_rvlc_run[169]={
static const int8_t inter_rvlc_run[169]={
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1,
@ -194,7 +223,7 @@ static const uint8_t inter_rvlc_run[169]={
43, 44,
};
static const uint8_t inter_rvlc_level[169]={
static const int8_t inter_rvlc_level[169]={
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 1, 2, 3, 4, 5,
@ -273,7 +302,7 @@ static const uint16_t intra_rvlc[170][2]={
{0x3F7C, 15},{0x3F7D, 15},{0x0000, 4}
};
static const uint8_t intra_rvlc_run[169]={
static const int8_t intra_rvlc_run[169]={
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -298,7 +327,7 @@ static const uint8_t intra_rvlc_run[169]={
43, 44,
};
static const uint8_t intra_rvlc_level[169]={
static const int8_t intra_rvlc_level[169]={
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
@ -383,11 +412,11 @@ const int16_t ff_mpeg4_default_non_intra_matrix[64] = {
23, 24, 25, 27, 28, 30, 31, 33,
};
uint8_t ff_mpeg4_y_dc_scale_table[32]={
const uint8_t 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
};
uint8_t ff_mpeg4_c_dc_scale_table[32]={
const uint8_t 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
};
@ -399,3 +428,5 @@ const uint16_t ff_mpeg4_resync_prefix[8]={
static const uint8_t mpeg4_dc_threshold[8]={
99, 13, 15, 17, 19, 21, 23, 0
};
#endif /* FFMPEG_MPEG4DATA_H */

View File

@ -0,0 +1,138 @@
/*
* MPEG4 Video frame extraction
* Copyright (c) 2003 Fabrice Bellard.
* Copyright (c) 2003 Michael Niedermayer.
*
* 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 "parser.h"
#include "mpegvideo.h"
#include "mpeg4video_parser.h"
int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int vop_found, i;
uint32_t state;
vop_found= pc->frame_start_found;
state= pc->state;
i=0;
if(!vop_found){
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state == 0x1B6){
i++;
vop_found=1;
break;
}
}
}
if(vop_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if((state&0xFFFFFF00) == 0x100){
pc->frame_start_found=0;
pc->state=-1;
return i-3;
}
}
}
pc->frame_start_found= vop_found;
pc->state= state;
return END_NOT_FOUND;
}
/* XXX: make it use less memory */
static int av_mpeg4_decode_header(AVCodecParserContext *s1,
AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s1->priv_data;
MpegEncContext *s = pc->enc;
GetBitContext gb1, *gb = &gb1;
int ret;
s->avctx = avctx;
s->current_picture_ptr = &s->current_picture;
if (avctx->extradata_size && pc->first_picture){
init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
ret = ff_mpeg4_decode_picture_header(s, gb);
}
init_get_bits(gb, buf, 8 * buf_size);
ret = ff_mpeg4_decode_picture_header(s, gb);
if (s->width) {
avcodec_set_dimensions(avctx, s->width, s->height);
}
s1->pict_type= s->pict_type;
pc->first_picture = 0;
return ret;
}
static int mpeg4video_parse_init(AVCodecParserContext *s)
{
ParseContext1 *pc = s->priv_data;
pc->enc = av_mallocz(sizeof(MpegEncContext));
if (!pc->enc)
return -1;
pc->first_picture = 1;
return 0;
}
static int mpeg4video_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
next= buf_size;
}else{
next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
av_mpeg4_decode_header(s, avctx, buf, buf_size);
*poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
AVCodecParser mpeg4video_parser = {
{ CODEC_ID_MPEG4 },
sizeof(ParseContext1),
mpeg4video_parse_init,
mpeg4video_parse,
ff_parse1_close,
ff_mpeg4video_split,
};

View File

@ -0,0 +1,34 @@
/*
* MPEG4 video parser prototypes
* Copyright (c) 2003 Fabrice Bellard.
* Copyright (c) 2003 Michael Niedermayer.
*
* 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 FFMPEG_MPEG4VIDEO_PARSER_H
#define FFMPEG_MPEG4VIDEO_PARSER_H
#include "parser.h"
/**
* finds the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
#endif /* FFMPEG_MPEG4VIDEO_PARSER_H */

View File

@ -1,793 +1,50 @@
/*
* The simplest mpeg audio layer 2 encoder
* Copyright (c) 2000, 2001 Fabrice Bellard.
* MPEG Audio common code
* Copyright (c) 2001, 2002 Fabrice Bellard.
*
* This library is free software; you can redistribute it and/or
* 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 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file mpegaudio.c
* The simplest mpeg audio layer 2 encoder.
* MPEG Audio common code.
*/
#include "avcodec.h"
#include "mpegaudio.h"
/* currently, cannot change these constants (need to modify
quantization stage) */
#define FRAC_BITS 15
#define WFRAC_BITS 14
#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS)
#define FIX(a) ((int)((a) * (1 << FRAC_BITS)))
#define SAMPLES_BUF_SIZE 4096
typedef struct MpegAudioContext {
PutBitContext pb;
int nb_channels;
int freq, bit_rate;
int lsf; /* 1 if mpeg2 low bitrate selected */
int bitrate_index; /* bit rate */
int freq_index;
int frame_size; /* frame size, in bits, without padding */
int64_t nb_samples; /* total number of samples encoded */
/* padding computation */
int frame_frac, frame_frac_incr, do_padding;
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */
int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT];
unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */
/* code to group 3 scale factors */
unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
int sblimit; /* number of used subbands */
const unsigned char *alloc_table;
} MpegAudioContext;
/* define it to use floats in quantization (I don't like floats !) */
//#define USE_FLOATS
#include "mpegaudiotab.h"
static int MPA_encode_init(AVCodecContext *avctx)
/* bitrate is in kb/s */
int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf)
{
MpegAudioContext *s = avctx->priv_data;
int freq = avctx->sample_rate;
int bitrate = avctx->bit_rate;
int channels = avctx->channels;
int i, v, table;
float a;
int ch_bitrate, table;
if (channels > 2)
return -1;
bitrate = bitrate / 1000;
s->nb_channels = channels;
s->freq = freq;
s->bit_rate = bitrate * 1000;
avctx->frame_size = MPA_FRAME_SIZE;
/* encoding freq */
s->lsf = 0;
for(i=0;i<3;i++) {
if (mpa_freq_tab[i] == freq)
break;
if ((mpa_freq_tab[i] / 2) == freq) {
s->lsf = 1;
break;
}
}
if (i == 3)
return -1;
s->freq_index = i;
/* encoding bitrate & frequency */
for(i=0;i<15;i++) {
if (mpa_bitrate_tab[s->lsf][1][i] == bitrate)
break;
}
if (i == 15)
return -1;
s->bitrate_index = i;
/* compute total header size & pad bit */
a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);
s->frame_size = ((int)a) * 8;
/* frame fractional size to compute padding */
s->frame_frac = 0;
s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);
/* select the right allocation table */
table = l2_select_table(bitrate, s->nb_channels, freq, s->lsf);
/* number of used subbands */
s->sblimit = sblimit_table[table];
s->alloc_table = alloc_tables[table];
#ifdef DEBUG
av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",
bitrate, freq, s->frame_size, table, s->frame_frac_incr);
#endif
for(i=0;i<s->nb_channels;i++)
s->samples_offset[i] = 0;
for(i=0;i<257;i++) {
int v;
v = mpa_enwindow[i];
#if WFRAC_BITS != 16
v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
#endif
filter_bank[i] = v;
if ((i & 63) != 0)
v = -v;
if (i != 0)
filter_bank[512 - i] = v;
}
for(i=0;i<64;i++) {
v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20));
if (v <= 0)
v = 1;
scale_factor_table[i] = v;
#ifdef USE_FLOATS
scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);
#else
#define P 15
scale_factor_shift[i] = 21 - P - (i / 3);
scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0);
#endif
}
for(i=0;i<128;i++) {
v = i - 64;
if (v <= -3)
v = 0;
else if (v < 0)
v = 1;
else if (v == 0)
v = 2;
else if (v < 3)
v = 3;
ch_bitrate = bitrate / nb_channels;
if (!lsf) {
if ((freq == 48000 && ch_bitrate >= 56) ||
(ch_bitrate >= 56 && ch_bitrate <= 80))
table = 0;
else if (freq != 48000 && ch_bitrate >= 96)
table = 1;
else if (freq != 32000 && ch_bitrate <= 48)
table = 2;
else
v = 4;
scale_diff_table[i] = v;
}
for(i=0;i<17;i++) {
v = quant_bits[i];
if (v < 0)
v = -v;
else
v = v * 3;
total_quant_bits[i] = 12 * v;
}
avctx->coded_frame= avcodec_alloc_frame();
avctx->coded_frame->key_frame= 1;
return 0;
}
/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */
static void idct32(int *out, int *tab)
{
int i, j;
int *t, *t1, xr;
const int *xp = costab32;
for(j=31;j>=3;j-=2) tab[j] += tab[j - 2];
t = tab + 30;
t1 = tab + 2;
do {
t[0] += t[-4];
t[1] += t[1 - 4];
t -= 4;
} while (t != t1);
t = tab + 28;
t1 = tab + 4;
do {
t[0] += t[-8];
t[1] += t[1-8];
t[2] += t[2-8];
t[3] += t[3-8];
t -= 8;
} while (t != t1);
t = tab;
t1 = tab + 32;
do {
t[ 3] = -t[ 3];
t[ 6] = -t[ 6];
t[11] = -t[11];
t[12] = -t[12];
t[13] = -t[13];
t[15] = -t[15];
t += 16;
} while (t != t1);
t = tab;
t1 = tab + 8;
do {
int x1, x2, x3, x4;
x3 = MUL(t[16], FIX(SQRT2*0.5));
x4 = t[0] - x3;
x3 = t[0] + x3;
x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5));
x1 = MUL((t[8] - x2), xp[0]);
x2 = MUL((t[8] + x2), xp[1]);
t[ 0] = x3 + x1;
t[ 8] = x4 - x2;
t[16] = x4 + x2;
t[24] = x3 - x1;
t++;
} while (t != t1);
xp += 2;
t = tab;
t1 = tab + 4;
do {
xr = MUL(t[28],xp[0]);
t[28] = (t[0] - xr);
t[0] = (t[0] + xr);
xr = MUL(t[4],xp[1]);
t[ 4] = (t[24] - xr);
t[24] = (t[24] + xr);
xr = MUL(t[20],xp[2]);
t[20] = (t[8] - xr);
t[ 8] = (t[8] + xr);
xr = MUL(t[12],xp[3]);
t[12] = (t[16] - xr);
t[16] = (t[16] + xr);
t++;
} while (t != t1);
xp += 4;
for (i = 0; i < 4; i++) {
xr = MUL(tab[30-i*4],xp[0]);
tab[30-i*4] = (tab[i*4] - xr);
tab[ i*4] = (tab[i*4] + xr);
xr = MUL(tab[ 2+i*4],xp[1]);
tab[ 2+i*4] = (tab[28-i*4] - xr);
tab[28-i*4] = (tab[28-i*4] + xr);
xr = MUL(tab[31-i*4],xp[0]);
tab[31-i*4] = (tab[1+i*4] - xr);
tab[ 1+i*4] = (tab[1+i*4] + xr);
xr = MUL(tab[ 3+i*4],xp[1]);
tab[ 3+i*4] = (tab[29-i*4] - xr);
tab[29-i*4] = (tab[29-i*4] + xr);
xp += 2;
}
t = tab + 30;
t1 = tab + 1;
do {
xr = MUL(t1[0], *xp);
t1[0] = (t[0] - xr);
t[0] = (t[0] + xr);
t -= 2;
t1 += 2;
xp++;
} while (t >= tab);
for(i=0;i<32;i++) {
out[i] = tab[bitinv32[i]];
}
}
#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS)
static void filter(MpegAudioContext *s, int ch, short *samples, int incr)
{
short *p, *q;
int sum, offset, i, j;
int tmp[64];
int tmp1[32];
int *out;
// print_pow1(samples, 1152);
offset = s->samples_offset[ch];
out = &s->sb_samples[ch][0][0][0];
for(j=0;j<36;j++) {
/* 32 samples at once */
for(i=0;i<32;i++) {
s->samples_buf[ch][offset + (31 - i)] = samples[0];
samples += incr;
}
/* filter */
p = s->samples_buf[ch] + offset;
q = filter_bank;
/* maxsum = 23169 */
for(i=0;i<64;i++) {
sum = p[0*64] * q[0*64];
sum += p[1*64] * q[1*64];
sum += p[2*64] * q[2*64];
sum += p[3*64] * q[3*64];
sum += p[4*64] * q[4*64];
sum += p[5*64] * q[5*64];
sum += p[6*64] * q[6*64];
sum += p[7*64] * q[7*64];
tmp[i] = sum;
p++;
q++;
}
tmp1[0] = tmp[16] >> WSHIFT;
for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT;
for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT;
idct32(out, tmp1);
/* advance of 32 samples */
offset -= 32;
out += 32;
/* handle the wrap around */
if (offset < 0) {
memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32),
s->samples_buf[ch], (512 - 32) * 2);
offset = SAMPLES_BUF_SIZE - 512;
}
}
s->samples_offset[ch] = offset;
// print_pow(s->sb_samples, 1152);
}
static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
unsigned char scale_factors[SBLIMIT][3],
int sb_samples[3][12][SBLIMIT],
int sblimit)
{
int *p, vmax, v, n, i, j, k, code;
int index, d1, d2;
unsigned char *sf = &scale_factors[0][0];
for(j=0;j<sblimit;j++) {
for(i=0;i<3;i++) {
/* find the max absolute value */
p = &sb_samples[i][0][j];
vmax = abs(*p);
for(k=1;k<12;k++) {
p += SBLIMIT;
v = abs(*p);
if (v > vmax)
vmax = v;
}
/* compute the scale factor index using log 2 computations */
if (vmax > 0) {
n = av_log2(vmax);
/* n is the position of the MSB of vmax. now
use at most 2 compares to find the index */
index = (21 - n) * 3 - 3;
if (index >= 0) {
while (vmax <= scale_factor_table[index+1])
index++;
table = 3;
} else {
index = 0; /* very unlikely case of overflow */
}
} else {
index = 62; /* value 63 is not allowed */
}
#if 0
printf("%2d:%d in=%x %x %d\n",
j, i, vmax, scale_factor_table[index], index);
#endif
/* store the scale factor */
assert(index >=0 && index <= 63);
sf[i] = index;
}
/* compute the transmission factor : look if the scale factors
are close enough to each other */
d1 = scale_diff_table[sf[0] - sf[1] + 64];
d2 = scale_diff_table[sf[1] - sf[2] + 64];
/* handle the 25 cases */
switch(d1 * 5 + d2) {
case 0*5+0:
case 0*5+4:
case 3*5+4:
case 4*5+0:
case 4*5+4:
code = 0;
break;
case 0*5+1:
case 0*5+2:
case 4*5+1:
case 4*5+2:
code = 3;
sf[2] = sf[1];
break;
case 0*5+3:
case 4*5+3:
code = 3;
sf[1] = sf[2];
break;
case 1*5+0:
case 1*5+4:
case 2*5+4:
code = 1;
sf[1] = sf[0];
break;
case 1*5+1:
case 1*5+2:
case 2*5+0:
case 2*5+1:
case 2*5+2:
code = 2;
sf[1] = sf[2] = sf[0];
break;
case 2*5+3:
case 3*5+3:
code = 2;
sf[0] = sf[1] = sf[2];
break;
case 3*5+0:
case 3*5+1:
case 3*5+2:
code = 2;
sf[0] = sf[2] = sf[1];
break;
case 1*5+3:
code = 2;
if (sf[0] > sf[2])
sf[0] = sf[2];
sf[1] = sf[2] = sf[0];
break;
default:
av_abort();
}
#if 0
printf("%d: %2d %2d %2d %d %d -> %d\n", j,
sf[0], sf[1], sf[2], d1, d2, code);
#endif
scale_code[j] = code;
sf += 3;
table = 4;
}
return table;
}
/* The most important function : psycho acoustic module. In this
encoder there is basically none, so this is the worst you can do,
but also this is the simpler. */
static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT])
{
int i;
for(i=0;i<s->sblimit;i++) {
smr[i] = (int)(fixed_smr[i] * 10);
}
}
#define SB_NOTALLOCATED 0
#define SB_ALLOCATED 1
#define SB_NOMORE 2
/* Try to maximize the smr while using a number of bits inferior to
the frame size. I tried to make the code simpler, faster and
smaller than other encoders :-) */
static void compute_bit_allocation(MpegAudioContext *s,
short smr1[MPA_MAX_CHANNELS][SBLIMIT],
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
int *padding)
{
int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size;
int incr;
short smr[MPA_MAX_CHANNELS][SBLIMIT];
unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT];
const unsigned char *alloc;
memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT);
memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT);
memset(bit_alloc, 0, s->nb_channels * SBLIMIT);
/* compute frame size and padding */
max_frame_size = s->frame_size;
s->frame_frac += s->frame_frac_incr;
if (s->frame_frac >= 65536) {
s->frame_frac -= 65536;
s->do_padding = 1;
max_frame_size += 8;
} else {
s->do_padding = 0;
}
/* compute the header + bit alloc size */
current_frame_size = 32;
alloc = s->alloc_table;
for(i=0;i<s->sblimit;i++) {
incr = alloc[0];
current_frame_size += incr * s->nb_channels;
alloc += 1 << incr;
}
for(;;) {
/* look for the subband with the largest signal to mask ratio */
max_sb = -1;
max_ch = -1;
max_smr = 0x80000000;
for(ch=0;ch<s->nb_channels;ch++) {
for(i=0;i<s->sblimit;i++) {
if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) {
max_smr = smr[ch][i];
max_sb = i;
max_ch = ch;
}
}
}
#if 0
printf("current=%d max=%d max_sb=%d alloc=%d\n",
current_frame_size, max_frame_size, max_sb,
bit_alloc[max_sb]);
#endif
if (max_sb < 0)
break;
/* find alloc table entry (XXX: not optimal, should use
pointer table) */
alloc = s->alloc_table;
for(i=0;i<max_sb;i++) {
alloc += 1 << alloc[0];
}
if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) {
/* nothing was coded for this band: add the necessary bits */
incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6;
incr += total_quant_bits[alloc[1]];
} else {
/* increments bit allocation */
b = bit_alloc[max_ch][max_sb];
incr = total_quant_bits[alloc[b + 1]] -
total_quant_bits[alloc[b]];
}
if (current_frame_size + incr <= max_frame_size) {
/* can increase size */
b = ++bit_alloc[max_ch][max_sb];
current_frame_size += incr;
/* decrease smr by the resolution we added */
smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]];
/* max allocation size reached ? */
if (b == ((1 << alloc[0]) - 1))
subband_status[max_ch][max_sb] = SB_NOMORE;
else
subband_status[max_ch][max_sb] = SB_ALLOCATED;
} else {
/* cannot increase the size of this subband */
subband_status[max_ch][max_sb] = SB_NOMORE;
}
}
*padding = max_frame_size - current_frame_size;
assert(*padding >= 0);
#if 0
for(i=0;i<s->sblimit;i++) {
printf("%d ", bit_alloc[i]);
}
printf("\n");
#endif
}
/*
* Output the mpeg audio layer 2 frame. Note how the code is small
* compared to other encoders :-)
*/
static void encode_frame(MpegAudioContext *s,
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
int padding)
{
int i, j, k, l, bit_alloc_bits, b, ch;
unsigned char *sf;
int q[3];
PutBitContext *p = &s->pb;
/* header */
put_bits(p, 12, 0xfff);
put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */
put_bits(p, 2, 4-2); /* layer 2 */
put_bits(p, 1, 1); /* no error protection */
put_bits(p, 4, s->bitrate_index);
put_bits(p, 2, s->freq_index);
put_bits(p, 1, s->do_padding); /* use padding */
put_bits(p, 1, 0); /* private_bit */
put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO);
put_bits(p, 2, 0); /* mode_ext */
put_bits(p, 1, 0); /* no copyright */
put_bits(p, 1, 1); /* original */
put_bits(p, 2, 0); /* no emphasis */
/* bit allocation */
j = 0;
for(i=0;i<s->sblimit;i++) {
bit_alloc_bits = s->alloc_table[j];
for(ch=0;ch<s->nb_channels;ch++) {
put_bits(p, bit_alloc_bits, bit_alloc[ch][i]);
}
j += 1 << bit_alloc_bits;
}
/* scale codes */
for(i=0;i<s->sblimit;i++) {
for(ch=0;ch<s->nb_channels;ch++) {
if (bit_alloc[ch][i])
put_bits(p, 2, s->scale_code[ch][i]);
}
}
/* scale factors */
for(i=0;i<s->sblimit;i++) {
for(ch=0;ch<s->nb_channels;ch++) {
if (bit_alloc[ch][i]) {
sf = &s->scale_factors[ch][i][0];
switch(s->scale_code[ch][i]) {
case 0:
put_bits(p, 6, sf[0]);
put_bits(p, 6, sf[1]);
put_bits(p, 6, sf[2]);
break;
case 3:
case 1:
put_bits(p, 6, sf[0]);
put_bits(p, 6, sf[2]);
break;
case 2:
put_bits(p, 6, sf[0]);
break;
}
}
}
}
/* quantization & write sub band samples */
for(k=0;k<3;k++) {
for(l=0;l<12;l+=3) {
j = 0;
for(i=0;i<s->sblimit;i++) {
bit_alloc_bits = s->alloc_table[j];
for(ch=0;ch<s->nb_channels;ch++) {
b = bit_alloc[ch][i];
if (b) {
int qindex, steps, m, sample, bits;
/* we encode 3 sub band samples of the same sub band at a time */
qindex = s->alloc_table[j+b];
steps = quant_steps[qindex];
for(m=0;m<3;m++) {
sample = s->sb_samples[ch][k][l + m][i];
/* divide by scale factor */
#ifdef USE_FLOATS
{
float a;
a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]];
q[m] = (int)((a + 1.0) * steps * 0.5);
}
#else
{
int q1, e, shift, mult;
e = s->scale_factors[ch][i][k];
shift = scale_factor_shift[e];
mult = scale_factor_mult[e];
/* normalize to P bits */
if (shift < 0)
q1 = sample << (-shift);
else
q1 = sample >> shift;
q1 = (q1 * mult) >> P;
q[m] = ((q1 + (1 << P)) * steps) >> (P + 1);
}
#endif
if (q[m] >= steps)
q[m] = steps - 1;
assert(q[m] >= 0 && q[m] < steps);
}
bits = quant_bits[qindex];
if (bits < 0) {
/* group the 3 values to save bits */
put_bits(p, -bits,
q[0] + steps * (q[1] + steps * q[2]));
#if 0
printf("%d: gr1 %d\n",
i, q[0] + steps * (q[1] + steps * q[2]));
#endif
} else {
#if 0
printf("%d: gr3 %d %d %d\n",
i, q[0], q[1], q[2]);
#endif
put_bits(p, bits, q[0]);
put_bits(p, bits, q[1]);
put_bits(p, bits, q[2]);
}
}
}
/* next subband in alloc table */
j += 1 << bit_alloc_bits;
}
}
}
/* padding */
for(i=0;i<padding;i++)
put_bits(p, 1, 0);
/* flush */
flush_put_bits(p);
}
static int MPA_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data)
{
MpegAudioContext *s = avctx->priv_data;
short *samples = data;
short smr[MPA_MAX_CHANNELS][SBLIMIT];
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
int padding, i;
for(i=0;i<s->nb_channels;i++) {
filter(s, i, samples + i, s->nb_channels);
}
for(i=0;i<s->nb_channels;i++) {
compute_scale_factors(s->scale_code[i], s->scale_factors[i],
s->sb_samples[i], s->sblimit);
}
for(i=0;i<s->nb_channels;i++) {
psycho_acoustic_model(s, smr[i]);
}
compute_bit_allocation(s, smr, bit_alloc, &padding);
init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE);
encode_frame(s, bit_alloc, padding);
s->nb_samples += MPA_FRAME_SIZE;
return pbBufPtr(&s->pb) - s->pb.buf;
}
static int MPA_encode_close(AVCodecContext *avctx)
{
av_freep(&avctx->coded_frame);
return 0;
}
AVCodec mp2_encoder = {
"mp2",
CODEC_TYPE_AUDIO,
CODEC_ID_MP2,
sizeof(MpegAudioContext),
MPA_encode_init,
MPA_encode_frame,
MPA_encode_close,
NULL,
};
#undef FIX

View File

@ -1,8 +1,35 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
* 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 mpegaudio.h
* mpeg audio declarations for both encoder and decoder.
*/
#ifndef FFMPEG_MPEGAUDIO_H
#define FFMPEG_MPEGAUDIO_H
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
/* max frame size, in samples */
#define MPA_FRAME_SIZE 1152
@ -18,14 +45,111 @@
#define MPA_DUAL 2
#define MPA_MONO 3
int l2_select_table(int bitrate, int nb_channels, int freq, int lsf);
int mpa_decode_header(AVCodecContext *avctx, uint32_t head);
/* header + layer + bitrate + freq + lsf/mpeg25 */
#define SAME_HEADER_MASK \
(0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))
extern const uint16_t mpa_bitrate_tab[2][3][15];
extern const uint16_t mpa_freq_tab[3];
extern const unsigned char *alloc_tables[5];
extern const double enwindow[512];
extern const int sblimit_table[5];
extern const int quant_steps[17];
extern const int quant_bits[17];
extern const int32_t mpa_enwindow[257];
#define MP3_MASK 0xFFFE0CCF
/* define USE_HIGHPRECISION to have a bit exact (but slower) mpeg
audio decoder */
#ifdef USE_HIGHPRECISION
#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */
#define WFRAC_BITS 16 /* fractional bits for window */
#else
#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */
#define WFRAC_BITS 14 /* fractional bits for window */
#endif
#define FRAC_ONE (1 << FRAC_BITS)
#define FIX(a) ((int)((a) * FRAC_ONE))
#if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT)
typedef int32_t OUT_INT;
#define OUT_MAX INT32_MAX
#define OUT_MIN INT32_MIN
#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 31)
#else
typedef int16_t OUT_INT;
#define OUT_MAX INT16_MAX
#define OUT_MIN INT16_MIN
#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15)
#endif
#if FRAC_BITS <= 15
typedef int16_t MPA_INT;
#else
typedef int32_t MPA_INT;
#endif
#define BACKSTEP_SIZE 512
#define EXTRABYTES 24
struct GranuleDef;
typedef struct MPADecodeContext {
DECLARE_ALIGNED_8(uint8_t, last_buf[2*BACKSTEP_SIZE + EXTRABYTES]);
int last_buf_size;
int frame_size;
/* next header (used in free format parsing) */
uint32_t free_format_next_header;
int error_protection;
int layer;
int sample_rate;
int sample_rate_index; /* between 0 and 8 */
int bit_rate;
GetBitContext gb;
GetBitContext in_gb;
int nb_channels;
int mode;
int mode_ext;
int lsf;
DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512 * 2]);
int synth_buf_offset[MPA_MAX_CHANNELS];
DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]);
int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
#ifdef DEBUG
int frame_count;
#endif
void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g);
int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
int dither_state;
int error_resilience;
AVCodecContext* avctx;
} MPADecodeContext;
/* layer 3 huffman tables */
typedef struct HuffTable {
int xsize;
const uint8_t *bits;
const uint16_t *codes;
} HuffTable;
int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf);
int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate);
void ff_mpa_synth_init(MPA_INT *window);
void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset,
MPA_INT *window, int *dither_state,
OUT_INT *samples, int incr,
int32_t sb_samples[SBLIMIT]);
/* fast header check for resync */
static inline int ff_mpa_check_header(uint32_t header){
/* header */
if ((header & 0xffe00000) != 0xffe00000)
return -1;
/* layer check */
if ((header & (3<<17)) == 0)
return -1;
/* bit rate */
if ((header & (0xf<<12)) == 0xf<<12)
return -1;
/* frequency */
if ((header & (3<<10)) == 3<<10)
return -1;
return 0;
}
#endif /* FFMPEG_MPEGAUDIO_H */

View File

@ -0,0 +1,252 @@
/*
* MPEG Audio parser
* Copyright (c) 2003 Fabrice Bellard.
* Copyright (c) 2003 Michael Niedermayer.
*
* 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 "parser.h"
#include "mpegaudio.h"
#include "mpegaudiodecheader.h"
typedef struct MpegAudioParseContext {
uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
uint8_t *inbuf_ptr;
int frame_size;
int free_format_frame_size;
int free_format_next_header;
uint32_t header;
int header_count;
} MpegAudioParseContext;
#define MPA_HEADER_SIZE 4
/* header + layer + bitrate + freq + lsf/mpeg25 */
#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */
#define SAME_HEADER_MASK \
(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
/* useful helper to get mpeg audio stream infos. Return -1 if error in
header, otherwise the coded frame size in bytes */
int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate)
{
MPADecodeContext s1, *s = &s1;
s1.avctx = avctx;
if (ff_mpa_check_header(head) != 0)
return -1;
if (ff_mpegaudio_decode_header(s, head) != 0) {
return -1;
}
switch(s->layer) {
case 1:
avctx->frame_size = 384;
break;
case 2:
avctx->frame_size = 1152;
break;
default:
case 3:
if (s->lsf)
avctx->frame_size = 576;
else
avctx->frame_size = 1152;
break;
}
*sample_rate = s->sample_rate;
avctx->channels = s->nb_channels;
avctx->bit_rate = s->bit_rate;
avctx->sub_id = s->layer;
return s->frame_size;
}
static int mpegaudio_parse_init(AVCodecParserContext *s1)
{
MpegAudioParseContext *s = s1->priv_data;
s->inbuf_ptr = s->inbuf;
return 0;
}
static int mpegaudio_parse(AVCodecParserContext *s1,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
MpegAudioParseContext *s = s1->priv_data;
int len, ret, sr;
uint32_t header;
const uint8_t *buf_ptr;
*poutbuf = NULL;
*poutbuf_size = 0;
buf_ptr = buf;
while (buf_size > 0) {
len = s->inbuf_ptr - s->inbuf;
if (s->frame_size == 0) {
/* special case for next header for first frame in free
format case (XXX: find a simpler method) */
if (s->free_format_next_header != 0) {
AV_WB32(s->inbuf, s->free_format_next_header);
s->inbuf_ptr = s->inbuf + 4;
s->free_format_next_header = 0;
goto got_header;
}
/* no header seen : find one. We need at least MPA_HEADER_SIZE
bytes to parse it */
len = FFMIN(MPA_HEADER_SIZE - len, buf_size);
if (len > 0) {
memcpy(s->inbuf_ptr, buf_ptr, len);
buf_ptr += len;
buf_size -= len;
s->inbuf_ptr += len;
}
if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
got_header:
header = AV_RB32(s->inbuf);
ret = ff_mpa_decode_header(avctx, header, &sr);
if (ret < 0) {
s->header_count= -2;
/* no sync found : move by one byte (inefficient, but simple!) */
memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
s->inbuf_ptr--;
dprintf(avctx, "skip %x\n", header);
/* reset free format frame size to give a chance
to get a new bitrate */
s->free_format_frame_size = 0;
} else {
if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
s->header_count= -3;
s->header= header;
s->header_count++;
s->frame_size = ret;
#if 0
/* free format: prepare to compute frame size */
if (ff_mpegaudio_decode_header(s, header) == 1) {
s->frame_size = -1;
}
#endif
if(s->header_count > 1)
avctx->sample_rate= sr;
}
}
} else
#if 0
if (s->frame_size == -1) {
/* free format : find next sync to compute frame size */
len = MPA_MAX_CODED_FRAME_SIZE - len;
if (len > buf_size)
len = buf_size;
if (len == 0) {
/* frame too long: resync */
s->frame_size = 0;
memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
s->inbuf_ptr--;
} else {
uint8_t *p, *pend;
uint32_t header1;
int padding;
memcpy(s->inbuf_ptr, buf_ptr, len);
/* check for header */
p = s->inbuf_ptr - 3;
pend = s->inbuf_ptr + len - 4;
while (p <= pend) {
header = AV_RB32(p);
header1 = AV_RB32(s->inbuf);
/* check with high probability that we have a
valid header */
if ((header & SAME_HEADER_MASK) ==
(header1 & SAME_HEADER_MASK)) {
/* header found: update pointers */
len = (p + 4) - s->inbuf_ptr;
buf_ptr += len;
buf_size -= len;
s->inbuf_ptr = p;
/* compute frame size */
s->free_format_next_header = header;
s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
padding = (header1 >> 9) & 1;
if (s->layer == 1)
s->free_format_frame_size -= padding * 4;
else
s->free_format_frame_size -= padding;
dprintf(avctx, "free frame size=%d padding=%d\n",
s->free_format_frame_size, padding);
ff_mpegaudio_decode_header(s, header1);
goto next_data;
}
p++;
}
/* not found: simply increase pointers */
buf_ptr += len;
s->inbuf_ptr += len;
buf_size -= len;
}
} else
#endif
if (len < s->frame_size) {
if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
len = FFMIN(s->frame_size - len, buf_size);
memcpy(s->inbuf_ptr, buf_ptr, len);
buf_ptr += len;
s->inbuf_ptr += len;
buf_size -= len;
}
if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf
&& buf_size + buf_ptr - buf >= s->frame_size){
if(s->header_count > 0){
*poutbuf = buf;
*poutbuf_size = s->frame_size;
}
buf_ptr = buf + s->frame_size;
s->inbuf_ptr = s->inbuf;
s->frame_size = 0;
break;
}
// next_data:
if (s->frame_size > 0 &&
(s->inbuf_ptr - s->inbuf) >= s->frame_size) {
if(s->header_count > 0){
*poutbuf = s->inbuf;
*poutbuf_size = s->inbuf_ptr - s->inbuf;
}
s->inbuf_ptr = s->inbuf;
s->frame_size = 0;
break;
}
}
return buf_ptr - buf;
}
AVCodecParser mpegaudio_parser = {
{ CODEC_ID_MP2, CODEC_ID_MP3 },
sizeof(MpegAudioParseContext),
mpegaudio_parse_init,
mpegaudio_parse,
NULL,
};

View File

@ -0,0 +1,225 @@
/*
* MPEG Audio common tables
* copyright (c) 2002 Fabrice Bellard
*
* 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 mpegaudiodata.c
* mpeg audio layer common tables.
*/
#include "mpegaudiodata.h"
const uint16_t ff_mpa_bitrate_tab[2][3][15] = {
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
{ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
}
};
const uint16_t ff_mpa_freq_tab[3] = { 44100, 48000, 32000 };
/*******************************************************/
/* half mpeg encoding window (full precision) */
const int32_t ff_mpa_enwindow[257] = {
0, -1, -1, -1, -1, -1, -1, -2,
-2, -2, -2, -3, -3, -4, -4, -5,
-5, -6, -7, -7, -8, -9, -10, -11,
-13, -14, -16, -17, -19, -21, -24, -26,
-29, -31, -35, -38, -41, -45, -49, -53,
-58, -63, -68, -73, -79, -85, -91, -97,
-104, -111, -117, -125, -132, -139, -147, -154,
-161, -169, -176, -183, -190, -196, -202, -208,
213, 218, 222, 225, 227, 228, 228, 227,
224, 221, 215, 208, 200, 189, 177, 163,
146, 127, 106, 83, 57, 29, -2, -36,
-72, -111, -153, -197, -244, -294, -347, -401,
-459, -519, -581, -645, -711, -779, -848, -919,
-991, -1064, -1137, -1210, -1283, -1356, -1428, -1498,
-1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962,
-2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063,
2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535,
1414, 1280, 1131, 970, 794, 605, 402, 185,
-45, -288, -545, -814, -1095, -1388, -1692, -2006,
-2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597,
-7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585,
-9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750,
-9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134,
6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082,
70, -998, -2122, -3300, -4533, -5818, -7154, -8540,
-9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189,
-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640,
-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137,
-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684,
-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420,
-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992,
75038,
};
/*******************************************************/
/* layer 2 tables */
const int ff_mpa_sblimit_table[5] = { 27 , 30 , 8, 12 , 30 };
const int ff_mpa_quant_steps[17] = {
3, 5, 7, 9, 15,
31, 63, 127, 255, 511,
1023, 2047, 4095, 8191, 16383,
32767, 65535
};
/* we use a negative value if grouped */
const int ff_mpa_quant_bits[17] = {
-5, -7, 3, -10, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14,
15, 16
};
/* encoding tables which give the quantization index. Note how it is
possible to store them efficiently ! */
static const unsigned char alloc_table_0[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_1[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_2[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_3[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_4[] = {
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
};
const unsigned char * const ff_mpa_alloc_tables[5] =
{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, };

View File

@ -0,0 +1,43 @@
/*
* MPEG Audio common tables
* copyright (c) 2002 Fabrice Bellard
*
* 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 mpegaudiodata.h
* mpeg audio layer common tables.
*/
#ifndef FFMPEG_MPEGAUDIODATA_H
#define FFMPEG_MPEGAUDIODATA_H
#include "common.h"
#define MODE_EXT_MS_STEREO 2
#define MODE_EXT_I_STEREO 1
extern const uint16_t ff_mpa_bitrate_tab[2][3][15];
extern const uint16_t ff_mpa_freq_tab[3];
extern const int32_t ff_mpa_enwindow[257];
extern const int ff_mpa_sblimit_table[5];
extern const int ff_mpa_quant_steps[17];
extern const int ff_mpa_quant_bits[17];
extern const unsigned char * const ff_mpa_alloc_tables[5];
#endif /* FFMPEG_MPEGAUDIODATA_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
/*
* MPEG Audio header decoder
* Copyright (c) 2001, 2002 Fabrice Bellard.
*
* 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 mpegaudiodecheader.c
* MPEG Audio header decoder.
*/
//#define DEBUG
#include "avcodec.h"
#include "mpegaudio.h"
#include "mpegaudiodata.h"
int ff_mpegaudio_decode_header(MPADecodeContext *s, uint32_t header)
{
int sample_rate, frame_size, mpeg25, padding;
int sample_rate_index, bitrate_index;
if (header & (1<<20)) {
s->lsf = (header & (1<<19)) ? 0 : 1;
mpeg25 = 0;
} else {
s->lsf = 1;
mpeg25 = 1;
}
s->layer = 4 - ((header >> 17) & 3);
/* extract frequency */
sample_rate_index = (header >> 10) & 3;
sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);
sample_rate_index += 3 * (s->lsf + mpeg25);
s->sample_rate_index = sample_rate_index;
s->error_protection = ((header >> 16) & 1) ^ 1;
s->sample_rate = sample_rate;
bitrate_index = (header >> 12) & 0xf;
padding = (header >> 9) & 1;
//extension = (header >> 8) & 1;
s->mode = (header >> 6) & 3;
s->mode_ext = (header >> 4) & 3;
//copyright = (header >> 3) & 1;
//original = (header >> 2) & 1;
//emphasis = header & 3;
if (s->mode == MPA_MONO)
s->nb_channels = 1;
else
s->nb_channels = 2;
if (bitrate_index != 0) {
frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
s->bit_rate = frame_size * 1000;
switch(s->layer) {
case 1:
frame_size = (frame_size * 12000) / sample_rate;
frame_size = (frame_size + padding) * 4;
break;
case 2:
frame_size = (frame_size * 144000) / sample_rate;
frame_size += padding;
break;
default:
case 3:
frame_size = (frame_size * 144000) / (sample_rate << s->lsf);
frame_size += padding;
break;
}
s->frame_size = frame_size;
} else {
/* if no frame size computed, signal it */
return 1;
}
#if defined(DEBUG)
dprintf(s->avctx, "layer%d, %d Hz, %d kbits/s, ",
s->layer, s->sample_rate, s->bit_rate);
if (s->nb_channels == 2) {
if (s->layer == 3) {
if (s->mode_ext & MODE_EXT_MS_STEREO)
dprintf(s->avctx, "ms-");
if (s->mode_ext & MODE_EXT_I_STEREO)
dprintf(s->avctx, "i-");
}
dprintf(s->avctx, "stereo");
} else {
dprintf(s->avctx, "mono");
}
dprintf(s->avctx, "\n");
#endif
return 0;
}

View File

@ -0,0 +1,39 @@
/*
* MPEG Audio header decoder
* Copyright (c) 2001, 2002 Fabrice Bellard.
*
* 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 mpegaudiodecheader.c
* MPEG Audio header decoder.
*/
#ifndef FFMPEG_MPEGAUDIODECHEADER_H
#define FFMPEG_MPEGAUDIODECHEADER_H
#include "common.h"
#include "mpegaudio.h"
/* header decoding. MUST check the header before because no
consistency check is done there. Return 1 if free format found and
that the frame size must be computed externally */
int ff_mpegaudio_decode_header(MPADecodeContext *s, uint32_t header);
#endif /* FFMPEG_MPEGAUDIODECHEADER_H */

View File

@ -1,204 +1,34 @@
/*
* MPEG Audio decoder
* copyright (c) 2002 Fabrice Bellard
*
* 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 mpegaudiodectab.h
* mpeg audio layer decoder tables.
*/
const uint16_t mpa_bitrate_tab[2][3][15] = {
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
{ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
}
};
#ifndef FFMPEG_MPEGAUDIODECTAB_H
#define FFMPEG_MPEGAUDIODECTAB_H
const uint16_t mpa_freq_tab[3] = { 44100, 48000, 32000 };
/*******************************************************/
/* half mpeg encoding window (full precision) */
const int32_t mpa_enwindow[257] = {
0, -1, -1, -1, -1, -1, -1, -2,
-2, -2, -2, -3, -3, -4, -4, -5,
-5, -6, -7, -7, -8, -9, -10, -11,
-13, -14, -16, -17, -19, -21, -24, -26,
-29, -31, -35, -38, -41, -45, -49, -53,
-58, -63, -68, -73, -79, -85, -91, -97,
-104, -111, -117, -125, -132, -139, -147, -154,
-161, -169, -176, -183, -190, -196, -202, -208,
213, 218, 222, 225, 227, 228, 228, 227,
224, 221, 215, 208, 200, 189, 177, 163,
146, 127, 106, 83, 57, 29, -2, -36,
-72, -111, -153, -197, -244, -294, -347, -401,
-459, -519, -581, -645, -711, -779, -848, -919,
-991, -1064, -1137, -1210, -1283, -1356, -1428, -1498,
-1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962,
-2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063,
2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535,
1414, 1280, 1131, 970, 794, 605, 402, 185,
-45, -288, -545, -814, -1095, -1388, -1692, -2006,
-2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597,
-7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585,
-9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750,
-9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134,
6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082,
70, -998, -2122, -3300, -4533, -5818, -7154, -8540,
-9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189,
-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640,
-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137,
-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684,
-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420,
-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992,
75038,
};
/*******************************************************/
/* layer 2 tables */
const int sblimit_table[5] = { 27 , 30 , 8, 12 , 30 };
const int quant_steps[17] = {
3, 5, 7, 9, 15,
31, 63, 127, 255, 511,
1023, 2047, 4095, 8191, 16383,
32767, 65535
};
/* we use a negative value if grouped */
const int quant_bits[17] = {
-5, -7, 3, -10, 4,
5, 6, 7, 8, 9,
10, 11, 12, 13, 14,
15, 16
};
/* encoding tables which give the quantization index. Note how it is
possible to store them efficiently ! */
static const unsigned char alloc_table_0[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_1[] = {
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
3, 0, 1, 2, 3, 4, 5, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
2, 0, 1, 16,
};
static const unsigned char alloc_table_2[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_3[] = {
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
};
static const unsigned char alloc_table_4[] = {
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
3, 0, 1, 3, 4, 5, 6, 7,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
2, 0, 1, 3,
};
const unsigned char *alloc_tables[5] =
{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, };
#include <stdint.h>
#include "mpegaudio.h"
/*******************************************************/
/* layer 3 tables */
@ -221,55 +51,55 @@ static const uint8_t lsf_nsf_table[6][3][4] = {
/* mpegaudio layer 3 huffman tables */
const uint16_t mpa_huffcodes_1[4] = {
static const uint16_t mpa_huffcodes_1[4] = {
0x0001, 0x0001, 0x0001, 0x0000,
};
const uint8_t mpa_huffbits_1[4] = {
static const uint8_t mpa_huffbits_1[4] = {
1, 3, 2, 3,
};
const uint16_t mpa_huffcodes_2[9] = {
static const uint16_t mpa_huffcodes_2[9] = {
0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002,
0x0000,
};
const uint8_t mpa_huffbits_2[9] = {
static const uint8_t mpa_huffbits_2[9] = {
1, 3, 6, 3, 3, 5, 5, 5,
6,
};
const uint16_t mpa_huffcodes_3[9] = {
static const uint16_t mpa_huffcodes_3[9] = {
0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002,
0x0000,
};
const uint8_t mpa_huffbits_3[9] = {
static const uint8_t mpa_huffbits_3[9] = {
2, 2, 6, 3, 2, 5, 5, 5,
6,
};
const uint16_t mpa_huffcodes_5[16] = {
static const uint16_t mpa_huffcodes_5[16] = {
0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004,
0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000,
};
const uint8_t mpa_huffbits_5[16] = {
static const uint8_t mpa_huffbits_5[16] = {
1, 3, 6, 7, 3, 3, 6, 7,
6, 6, 7, 8, 7, 6, 7, 8,
};
const uint16_t mpa_huffcodes_6[16] = {
static const uint16_t mpa_huffcodes_6[16] = {
0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002,
0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000,
};
const uint8_t mpa_huffbits_6[16] = {
static const uint8_t mpa_huffbits_6[16] = {
3, 3, 5, 7, 3, 2, 4, 5,
4, 4, 5, 6, 6, 5, 6, 7,
};
const uint16_t mpa_huffcodes_7[36] = {
static const uint16_t mpa_huffcodes_7[36] = {
0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003,
0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011,
0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002,
@ -277,7 +107,7 @@ const uint16_t mpa_huffcodes_7[36] = {
0x0005, 0x0003, 0x0002, 0x0000,
};
const uint8_t mpa_huffbits_7[36] = {
static const uint8_t mpa_huffbits_7[36] = {
1, 3, 6, 8, 8, 9, 3, 4,
6, 7, 7, 8, 6, 5, 7, 8,
8, 9, 7, 7, 8, 9, 9, 9,
@ -285,7 +115,7 @@ const uint8_t mpa_huffbits_7[36] = {
9, 10, 10, 10,
};
const uint16_t mpa_huffcodes_8[36] = {
static const uint16_t mpa_huffcodes_8[36] = {
0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001,
0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e,
0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004,
@ -293,7 +123,7 @@ const uint16_t mpa_huffcodes_8[36] = {
0x0004, 0x0001, 0x0001, 0x0000,
};
const uint8_t mpa_huffbits_8[36] = {
static const uint8_t mpa_huffbits_8[36] = {
2, 3, 6, 8, 8, 9, 3, 2,
4, 8, 8, 8, 6, 4, 6, 8,
8, 9, 8, 8, 8, 9, 9, 10,
@ -301,7 +131,7 @@ const uint8_t mpa_huffbits_8[36] = {
9, 9, 11, 11,
};
const uint16_t mpa_huffcodes_9[36] = {
static const uint16_t mpa_huffcodes_9[36] = {
0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004,
0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008,
0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001,
@ -309,7 +139,7 @@ const uint16_t mpa_huffcodes_9[36] = {
0x0006, 0x0002, 0x0006, 0x0000,
};
const uint8_t mpa_huffbits_9[36] = {
static const uint8_t mpa_huffbits_9[36] = {
3, 3, 5, 6, 8, 9, 3, 3,
4, 5, 6, 8, 4, 4, 5, 6,
7, 8, 6, 5, 6, 7, 7, 8,
@ -317,7 +147,7 @@ const uint8_t mpa_huffbits_9[36] = {
8, 8, 9, 9,
};
const uint16_t mpa_huffcodes_10[64] = {
static const uint16_t mpa_huffcodes_10[64] = {
0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011,
0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007,
0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006,
@ -328,7 +158,7 @@ const uint16_t mpa_huffcodes_10[64] = {
0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000,
};
const uint8_t mpa_huffbits_10[64] = {
static const uint8_t mpa_huffbits_10[64] = {
1, 3, 6, 8, 9, 9, 9, 10,
3, 4, 6, 7, 8, 9, 8, 8,
6, 6, 7, 8, 9, 10, 9, 9,
@ -339,7 +169,7 @@ const uint8_t mpa_huffbits_10[64] = {
9, 8, 9, 10, 10, 11, 11, 11,
};
const uint16_t mpa_huffcodes_11[64] = {
static const uint16_t mpa_huffcodes_11[64] = {
0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f,
0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a,
0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005,
@ -350,7 +180,7 @@ const uint16_t mpa_huffcodes_11[64] = {
0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000,
};
const uint8_t mpa_huffbits_11[64] = {
static const uint8_t mpa_huffbits_11[64] = {
2, 3, 5, 7, 8, 9, 8, 9,
3, 3, 4, 6, 8, 8, 7, 8,
5, 5, 6, 7, 8, 9, 8, 8,
@ -361,7 +191,7 @@ const uint8_t mpa_huffbits_11[64] = {
8, 7, 8, 9, 10, 10, 10, 10,
};
const uint16_t mpa_huffcodes_12[64] = {
static const uint16_t mpa_huffcodes_12[64] = {
0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a,
0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b,
0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007,
@ -372,7 +202,7 @@ const uint16_t mpa_huffcodes_12[64] = {
0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000,
};
const uint8_t mpa_huffbits_12[64] = {
static const uint8_t mpa_huffbits_12[64] = {
4, 3, 5, 7, 8, 9, 9, 9,
3, 3, 4, 5, 7, 7, 8, 8,
5, 4, 5, 6, 7, 8, 7, 8,
@ -383,7 +213,7 @@ const uint8_t mpa_huffbits_12[64] = {
9, 8, 8, 9, 9, 9, 9, 10,
};
const uint16_t mpa_huffcodes_13[256] = {
static const uint16_t mpa_huffcodes_13[256] = {
0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047,
0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013,
0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021,
@ -418,7 +248,7 @@ const uint16_t mpa_huffcodes_13[256] = {
0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001,
};
const uint8_t mpa_huffbits_13[256] = {
static const uint8_t mpa_huffbits_13[256] = {
1, 4, 6, 7, 8, 9, 9, 10,
9, 10, 11, 11, 12, 12, 13, 13,
3, 4, 6, 7, 8, 8, 9, 9,
@ -453,7 +283,7 @@ const uint8_t mpa_huffbits_13[256] = {
15, 15, 16, 16, 19, 18, 19, 16,
};
const uint16_t mpa_huffcodes_15[256] = {
static const uint16_t mpa_huffcodes_15[256] = {
0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c,
0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f,
0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033,
@ -488,7 +318,7 @@ const uint16_t mpa_huffcodes_15[256] = {
0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000,
};
const uint8_t mpa_huffbits_15[256] = {
static const uint8_t mpa_huffbits_15[256] = {
3, 4, 5, 7, 7, 8, 9, 9,
9, 10, 10, 11, 11, 11, 12, 13,
4, 3, 5, 6, 7, 7, 8, 8,
@ -523,7 +353,7 @@ const uint8_t mpa_huffbits_15[256] = {
12, 12, 12, 12, 13, 13, 13, 13,
};
const uint16_t mpa_huffcodes_16[256] = {
static const uint16_t mpa_huffcodes_16[256] = {
0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d,
0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011,
0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f,
@ -558,7 +388,7 @@ const uint16_t mpa_huffcodes_16[256] = {
0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
};
const uint8_t mpa_huffbits_16[256] = {
static const uint8_t mpa_huffbits_16[256] = {
1, 4, 6, 8, 9, 9, 10, 10,
11, 11, 11, 12, 12, 12, 13, 9,
3, 4, 6, 7, 8, 9, 9, 9,
@ -593,7 +423,7 @@ const uint8_t mpa_huffbits_16[256] = {
11, 11, 11, 11, 11, 11, 11, 8,
};
const uint16_t mpa_huffcodes_24[256] = {
static const uint16_t mpa_huffcodes_24[256] = {
0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2,
0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058,
0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8,
@ -628,7 +458,7 @@ const uint16_t mpa_huffcodes_24[256] = {
0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
};
const uint8_t mpa_huffbits_24[256] = {
static const uint8_t mpa_huffbits_24[256] = {
4, 4, 6, 7, 8, 9, 9, 10,
10, 11, 11, 11, 11, 11, 12, 9,
4, 4, 5, 6, 7, 8, 8, 9,
@ -663,7 +493,7 @@ const uint8_t mpa_huffbits_24[256] = {
7, 7, 7, 8, 8, 8, 8, 4,
};
const HuffTable mpa_huff_tables[16] = {
static const HuffTable mpa_huff_tables[16] = {
{ 1, NULL, NULL },
{ 2, mpa_huffbits_1, mpa_huffcodes_1 },
{ 3, mpa_huffbits_2, mpa_huffcodes_2 },
@ -682,7 +512,7 @@ const HuffTable mpa_huff_tables[16] = {
{ 16, mpa_huffbits_24, mpa_huffcodes_24 },
};
const uint8_t mpa_huff_data[32][2] = {
static const uint8_t mpa_huff_data[32][2] = {
{ 0, 0 },
{ 1, 0 },
{ 2, 0 },
@ -719,18 +549,18 @@ const uint8_t mpa_huff_data[32][2] = {
/* huffman tables for quadrules */
static uint8_t mpa_quad_codes[2][16] = {
static const uint8_t mpa_quad_codes[2][16] = {
{ 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, },
{ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
};
static uint8_t mpa_quad_bits[2][16] = {
static const uint8_t mpa_quad_bits[2][16] = {
{ 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, },
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, },
};
/* band size tables */
const uint8_t band_size_long[9][22] = {
static const uint8_t band_size_long[9][22] = {
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */
{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
@ -751,7 +581,7 @@ const uint8_t band_size_long[9][22] = {
40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */
};
const uint8_t band_size_short[9][13] = {
static const uint8_t band_size_short[9][13] = {
{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */
{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */
{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */
@ -763,12 +593,14 @@ const uint8_t band_size_short[9][13] = {
{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */
};
const uint8_t mpa_pretab[2][22] = {
static const uint8_t mpa_pretab[2][22] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 },
};
/* table for alias reduction (XXX: store it as integer !) */
const float ci_table[8] = {
static const float ci_table[8] = {
-0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037,
};
#endif /* FFMPEG_MPEGAUDIODECTAB_H */

View File

@ -0,0 +1,803 @@
/*
* The simplest mpeg audio layer 2 encoder
* Copyright (c) 2000, 2001 Fabrice Bellard.
*
* 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 mpegaudio.c
* The simplest mpeg audio layer 2 encoder.
*/
#include "avcodec.h"
#include "bitstream.h"
#include "mpegaudio.h"
/* currently, cannot change these constants (need to modify
quantization stage) */
#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS)
#define SAMPLES_BUF_SIZE 4096
typedef struct MpegAudioContext {
PutBitContext pb;
int nb_channels;
int freq, bit_rate;
int lsf; /* 1 if mpeg2 low bitrate selected */
int bitrate_index; /* bit rate */
int freq_index;
int frame_size; /* frame size, in bits, without padding */
int64_t nb_samples; /* total number of samples encoded */
/* padding computation */
int frame_frac, frame_frac_incr, do_padding;
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */
int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT];
unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */
/* code to group 3 scale factors */
unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
int sblimit; /* number of used subbands */
const unsigned char *alloc_table;
} MpegAudioContext;
/* define it to use floats in quantization (I don't like floats !) */
//#define USE_FLOATS
#include "mpegaudiodata.h"
#include "mpegaudiotab.h"
static av_cold int MPA_encode_init(AVCodecContext *avctx)
{
MpegAudioContext *s = avctx->priv_data;
int freq = avctx->sample_rate;
int bitrate = avctx->bit_rate;
int channels = avctx->channels;
int i, v, table;
float a;
if (channels <= 0 || channels > 2){
av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels);
return -1;
}
bitrate = bitrate / 1000;
s->nb_channels = channels;
s->freq = freq;
s->bit_rate = bitrate * 1000;
avctx->frame_size = MPA_FRAME_SIZE;
/* encoding freq */
s->lsf = 0;
for(i=0;i<3;i++) {
if (ff_mpa_freq_tab[i] == freq)
break;
if ((ff_mpa_freq_tab[i] / 2) == freq) {
s->lsf = 1;
break;
}
}
if (i == 3){
av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq);
return -1;
}
s->freq_index = i;
/* encoding bitrate & frequency */
for(i=0;i<15;i++) {
if (ff_mpa_bitrate_tab[s->lsf][1][i] == bitrate)
break;
}
if (i == 15){
av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate);
return -1;
}
s->bitrate_index = i;
/* compute total header size & pad bit */
a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);
s->frame_size = ((int)a) * 8;
/* frame fractional size to compute padding */
s->frame_frac = 0;
s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);
/* select the right allocation table */
table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf);
/* number of used subbands */
s->sblimit = ff_mpa_sblimit_table[table];
s->alloc_table = ff_mpa_alloc_tables[table];
#ifdef DEBUG
av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",
bitrate, freq, s->frame_size, table, s->frame_frac_incr);
#endif
for(i=0;i<s->nb_channels;i++)
s->samples_offset[i] = 0;
for(i=0;i<257;i++) {
int v;
v = ff_mpa_enwindow[i];
#if WFRAC_BITS != 16
v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
#endif
filter_bank[i] = v;
if ((i & 63) != 0)
v = -v;
if (i != 0)
filter_bank[512 - i] = v;
}
for(i=0;i<64;i++) {
v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20));
if (v <= 0)
v = 1;
scale_factor_table[i] = v;
#ifdef USE_FLOATS
scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);
#else
#define P 15
scale_factor_shift[i] = 21 - P - (i / 3);
scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0);
#endif
}
for(i=0;i<128;i++) {
v = i - 64;
if (v <= -3)
v = 0;
else if (v < 0)
v = 1;
else if (v == 0)
v = 2;
else if (v < 3)
v = 3;
else
v = 4;
scale_diff_table[i] = v;
}
for(i=0;i<17;i++) {
v = ff_mpa_quant_bits[i];
if (v < 0)
v = -v;
else
v = v * 3;
total_quant_bits[i] = 12 * v;
}
avctx->coded_frame= avcodec_alloc_frame();
avctx->coded_frame->key_frame= 1;
return 0;
}
/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */
static void idct32(int *out, int *tab)
{
int i, j;
int *t, *t1, xr;
const int *xp = costab32;
for(j=31;j>=3;j-=2) tab[j] += tab[j - 2];
t = tab + 30;
t1 = tab + 2;
do {
t[0] += t[-4];
t[1] += t[1 - 4];
t -= 4;
} while (t != t1);
t = tab + 28;
t1 = tab + 4;
do {
t[0] += t[-8];
t[1] += t[1-8];
t[2] += t[2-8];
t[3] += t[3-8];
t -= 8;
} while (t != t1);
t = tab;
t1 = tab + 32;
do {
t[ 3] = -t[ 3];
t[ 6] = -t[ 6];
t[11] = -t[11];
t[12] = -t[12];
t[13] = -t[13];
t[15] = -t[15];
t += 16;
} while (t != t1);
t = tab;
t1 = tab + 8;
do {
int x1, x2, x3, x4;
x3 = MUL(t[16], FIX(SQRT2*0.5));
x4 = t[0] - x3;
x3 = t[0] + x3;
x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5));
x1 = MUL((t[8] - x2), xp[0]);
x2 = MUL((t[8] + x2), xp[1]);
t[ 0] = x3 + x1;
t[ 8] = x4 - x2;
t[16] = x4 + x2;
t[24] = x3 - x1;
t++;
} while (t != t1);
xp += 2;
t = tab;
t1 = tab + 4;
do {
xr = MUL(t[28],xp[0]);
t[28] = (t[0] - xr);
t[0] = (t[0] + xr);
xr = MUL(t[4],xp[1]);
t[ 4] = (t[24] - xr);
t[24] = (t[24] + xr);
xr = MUL(t[20],xp[2]);
t[20] = (t[8] - xr);
t[ 8] = (t[8] + xr);
xr = MUL(t[12],xp[3]);
t[12] = (t[16] - xr);
t[16] = (t[16] + xr);
t++;
} while (t != t1);
xp += 4;
for (i = 0; i < 4; i++) {
xr = MUL(tab[30-i*4],xp[0]);
tab[30-i*4] = (tab[i*4] - xr);
tab[ i*4] = (tab[i*4] + xr);
xr = MUL(tab[ 2+i*4],xp[1]);
tab[ 2+i*4] = (tab[28-i*4] - xr);
tab[28-i*4] = (tab[28-i*4] + xr);
xr = MUL(tab[31-i*4],xp[0]);
tab[31-i*4] = (tab[1+i*4] - xr);
tab[ 1+i*4] = (tab[1+i*4] + xr);
xr = MUL(tab[ 3+i*4],xp[1]);
tab[ 3+i*4] = (tab[29-i*4] - xr);
tab[29-i*4] = (tab[29-i*4] + xr);
xp += 2;
}
t = tab + 30;
t1 = tab + 1;
do {
xr = MUL(t1[0], *xp);
t1[0] = (t[0] - xr);
t[0] = (t[0] + xr);
t -= 2;
t1 += 2;
xp++;
} while (t >= tab);
for(i=0;i<32;i++) {
out[i] = tab[bitinv32[i]];
}
}
#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS)
static void filter(MpegAudioContext *s, int ch, short *samples, int incr)
{
short *p, *q;
int sum, offset, i, j;
int tmp[64];
int tmp1[32];
int *out;
// print_pow1(samples, 1152);
offset = s->samples_offset[ch];
out = &s->sb_samples[ch][0][0][0];
for(j=0;j<36;j++) {
/* 32 samples at once */
for(i=0;i<32;i++) {
s->samples_buf[ch][offset + (31 - i)] = samples[0];
samples += incr;
}
/* filter */
p = s->samples_buf[ch] + offset;
q = filter_bank;
/* maxsum = 23169 */
for(i=0;i<64;i++) {
sum = p[0*64] * q[0*64];
sum += p[1*64] * q[1*64];
sum += p[2*64] * q[2*64];
sum += p[3*64] * q[3*64];
sum += p[4*64] * q[4*64];
sum += p[5*64] * q[5*64];
sum += p[6*64] * q[6*64];
sum += p[7*64] * q[7*64];
tmp[i] = sum;
p++;
q++;
}
tmp1[0] = tmp[16] >> WSHIFT;
for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT;
for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT;
idct32(out, tmp1);
/* advance of 32 samples */
offset -= 32;
out += 32;
/* handle the wrap around */
if (offset < 0) {
memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32),
s->samples_buf[ch], (512 - 32) * 2);
offset = SAMPLES_BUF_SIZE - 512;
}
}
s->samples_offset[ch] = offset;
// print_pow(s->sb_samples, 1152);
}
static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
unsigned char scale_factors[SBLIMIT][3],
int sb_samples[3][12][SBLIMIT],
int sblimit)
{
int *p, vmax, v, n, i, j, k, code;
int index, d1, d2;
unsigned char *sf = &scale_factors[0][0];
for(j=0;j<sblimit;j++) {
for(i=0;i<3;i++) {
/* find the max absolute value */
p = &sb_samples[i][0][j];
vmax = abs(*p);
for(k=1;k<12;k++) {
p += SBLIMIT;
v = abs(*p);
if (v > vmax)
vmax = v;
}
/* compute the scale factor index using log 2 computations */
if (vmax > 1) {
n = av_log2(vmax);
/* n is the position of the MSB of vmax. now
use at most 2 compares to find the index */
index = (21 - n) * 3 - 3;
if (index >= 0) {
while (vmax <= scale_factor_table[index+1])
index++;
} else {
index = 0; /* very unlikely case of overflow */
}
} else {
index = 62; /* value 63 is not allowed */
}
#if 0
printf("%2d:%d in=%x %x %d\n",
j, i, vmax, scale_factor_table[index], index);
#endif
/* store the scale factor */
assert(index >=0 && index <= 63);
sf[i] = index;
}
/* compute the transmission factor : look if the scale factors
are close enough to each other */
d1 = scale_diff_table[sf[0] - sf[1] + 64];
d2 = scale_diff_table[sf[1] - sf[2] + 64];
/* handle the 25 cases */
switch(d1 * 5 + d2) {
case 0*5+0:
case 0*5+4:
case 3*5+4:
case 4*5+0:
case 4*5+4:
code = 0;
break;
case 0*5+1:
case 0*5+2:
case 4*5+1:
case 4*5+2:
code = 3;
sf[2] = sf[1];
break;
case 0*5+3:
case 4*5+3:
code = 3;
sf[1] = sf[2];
break;
case 1*5+0:
case 1*5+4:
case 2*5+4:
code = 1;
sf[1] = sf[0];
break;
case 1*5+1:
case 1*5+2:
case 2*5+0:
case 2*5+1:
case 2*5+2:
code = 2;
sf[1] = sf[2] = sf[0];
break;
case 2*5+3:
case 3*5+3:
code = 2;
sf[0] = sf[1] = sf[2];
break;
case 3*5+0:
case 3*5+1:
case 3*5+2:
code = 2;
sf[0] = sf[2] = sf[1];
break;
case 1*5+3:
code = 2;
if (sf[0] > sf[2])
sf[0] = sf[2];
sf[1] = sf[2] = sf[0];
break;
default:
assert(0); //cannot happen
code = 0; /* kill warning */
}
#if 0
printf("%d: %2d %2d %2d %d %d -> %d\n", j,
sf[0], sf[1], sf[2], d1, d2, code);
#endif
scale_code[j] = code;
sf += 3;
}
}
/* The most important function : psycho acoustic module. In this
encoder there is basically none, so this is the worst you can do,
but also this is the simpler. */
static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT])
{
int i;
for(i=0;i<s->sblimit;i++) {
smr[i] = (int)(fixed_smr[i] * 10);
}
}
#define SB_NOTALLOCATED 0
#define SB_ALLOCATED 1
#define SB_NOMORE 2
/* Try to maximize the smr while using a number of bits inferior to
the frame size. I tried to make the code simpler, faster and
smaller than other encoders :-) */
static void compute_bit_allocation(MpegAudioContext *s,
short smr1[MPA_MAX_CHANNELS][SBLIMIT],
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
int *padding)
{
int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size;
int incr;
short smr[MPA_MAX_CHANNELS][SBLIMIT];
unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT];
const unsigned char *alloc;
memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT);
memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT);
memset(bit_alloc, 0, s->nb_channels * SBLIMIT);
/* compute frame size and padding */
max_frame_size = s->frame_size;
s->frame_frac += s->frame_frac_incr;
if (s->frame_frac >= 65536) {
s->frame_frac -= 65536;
s->do_padding = 1;
max_frame_size += 8;
} else {
s->do_padding = 0;
}
/* compute the header + bit alloc size */
current_frame_size = 32;
alloc = s->alloc_table;
for(i=0;i<s->sblimit;i++) {
incr = alloc[0];
current_frame_size += incr * s->nb_channels;
alloc += 1 << incr;
}
for(;;) {
/* look for the subband with the largest signal to mask ratio */
max_sb = -1;
max_ch = -1;
max_smr = INT_MIN;
for(ch=0;ch<s->nb_channels;ch++) {
for(i=0;i<s->sblimit;i++) {
if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) {
max_smr = smr[ch][i];
max_sb = i;
max_ch = ch;
}
}
}
#if 0
printf("current=%d max=%d max_sb=%d alloc=%d\n",
current_frame_size, max_frame_size, max_sb,
bit_alloc[max_sb]);
#endif
if (max_sb < 0)
break;
/* find alloc table entry (XXX: not optimal, should use
pointer table) */
alloc = s->alloc_table;
for(i=0;i<max_sb;i++) {
alloc += 1 << alloc[0];
}
if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) {
/* nothing was coded for this band: add the necessary bits */
incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6;
incr += total_quant_bits[alloc[1]];
} else {
/* increments bit allocation */
b = bit_alloc[max_ch][max_sb];
incr = total_quant_bits[alloc[b + 1]] -
total_quant_bits[alloc[b]];
}
if (current_frame_size + incr <= max_frame_size) {
/* can increase size */
b = ++bit_alloc[max_ch][max_sb];
current_frame_size += incr;
/* decrease smr by the resolution we added */
smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]];
/* max allocation size reached ? */
if (b == ((1 << alloc[0]) - 1))
subband_status[max_ch][max_sb] = SB_NOMORE;
else
subband_status[max_ch][max_sb] = SB_ALLOCATED;
} else {
/* cannot increase the size of this subband */
subband_status[max_ch][max_sb] = SB_NOMORE;
}
}
*padding = max_frame_size - current_frame_size;
assert(*padding >= 0);
#if 0
for(i=0;i<s->sblimit;i++) {
printf("%d ", bit_alloc[i]);
}
printf("\n");
#endif
}
/*
* Output the mpeg audio layer 2 frame. Note how the code is small
* compared to other encoders :-)
*/
static void encode_frame(MpegAudioContext *s,
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
int padding)
{
int i, j, k, l, bit_alloc_bits, b, ch;
unsigned char *sf;
int q[3];
PutBitContext *p = &s->pb;
/* header */
put_bits(p, 12, 0xfff);
put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */
put_bits(p, 2, 4-2); /* layer 2 */
put_bits(p, 1, 1); /* no error protection */
put_bits(p, 4, s->bitrate_index);
put_bits(p, 2, s->freq_index);
put_bits(p, 1, s->do_padding); /* use padding */
put_bits(p, 1, 0); /* private_bit */
put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO);
put_bits(p, 2, 0); /* mode_ext */
put_bits(p, 1, 0); /* no copyright */
put_bits(p, 1, 1); /* original */
put_bits(p, 2, 0); /* no emphasis */
/* bit allocation */
j = 0;
for(i=0;i<s->sblimit;i++) {
bit_alloc_bits = s->alloc_table[j];
for(ch=0;ch<s->nb_channels;ch++) {
put_bits(p, bit_alloc_bits, bit_alloc[ch][i]);
}
j += 1 << bit_alloc_bits;
}
/* scale codes */
for(i=0;i<s->sblimit;i++) {
for(ch=0;ch<s->nb_channels;ch++) {
if (bit_alloc[ch][i])
put_bits(p, 2, s->scale_code[ch][i]);
}
}
/* scale factors */
for(i=0;i<s->sblimit;i++) {
for(ch=0;ch<s->nb_channels;ch++) {
if (bit_alloc[ch][i]) {
sf = &s->scale_factors[ch][i][0];
switch(s->scale_code[ch][i]) {
case 0:
put_bits(p, 6, sf[0]);
put_bits(p, 6, sf[1]);
put_bits(p, 6, sf[2]);
break;
case 3:
case 1:
put_bits(p, 6, sf[0]);
put_bits(p, 6, sf[2]);
break;
case 2:
put_bits(p, 6, sf[0]);
break;
}
}
}
}
/* quantization & write sub band samples */
for(k=0;k<3;k++) {
for(l=0;l<12;l+=3) {
j = 0;
for(i=0;i<s->sblimit;i++) {
bit_alloc_bits = s->alloc_table[j];
for(ch=0;ch<s->nb_channels;ch++) {
b = bit_alloc[ch][i];
if (b) {
int qindex, steps, m, sample, bits;
/* we encode 3 sub band samples of the same sub band at a time */
qindex = s->alloc_table[j+b];
steps = ff_mpa_quant_steps[qindex];
for(m=0;m<3;m++) {
sample = s->sb_samples[ch][k][l + m][i];
/* divide by scale factor */
#ifdef USE_FLOATS
{
float a;
a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]];
q[m] = (int)((a + 1.0) * steps * 0.5);
}
#else
{
int q1, e, shift, mult;
e = s->scale_factors[ch][i][k];
shift = scale_factor_shift[e];
mult = scale_factor_mult[e];
/* normalize to P bits */
if (shift < 0)
q1 = sample << (-shift);
else
q1 = sample >> shift;
q1 = (q1 * mult) >> P;
q[m] = ((q1 + (1 << P)) * steps) >> (P + 1);
}
#endif
if (q[m] >= steps)
q[m] = steps - 1;
assert(q[m] >= 0 && q[m] < steps);
}
bits = ff_mpa_quant_bits[qindex];
if (bits < 0) {
/* group the 3 values to save bits */
put_bits(p, -bits,
q[0] + steps * (q[1] + steps * q[2]));
#if 0
printf("%d: gr1 %d\n",
i, q[0] + steps * (q[1] + steps * q[2]));
#endif
} else {
#if 0
printf("%d: gr3 %d %d %d\n",
i, q[0], q[1], q[2]);
#endif
put_bits(p, bits, q[0]);
put_bits(p, bits, q[1]);
put_bits(p, bits, q[2]);
}
}
}
/* next subband in alloc table */
j += 1 << bit_alloc_bits;
}
}
}
/* padding */
for(i=0;i<padding;i++)
put_bits(p, 1, 0);
/* flush */
flush_put_bits(p);
}
static int MPA_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data)
{
MpegAudioContext *s = avctx->priv_data;
short *samples = data;
short smr[MPA_MAX_CHANNELS][SBLIMIT];
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
int padding, i;
for(i=0;i<s->nb_channels;i++) {
filter(s, i, samples + i, s->nb_channels);
}
for(i=0;i<s->nb_channels;i++) {
compute_scale_factors(s->scale_code[i], s->scale_factors[i],
s->sb_samples[i], s->sblimit);
}
for(i=0;i<s->nb_channels;i++) {
psycho_acoustic_model(s, smr[i]);
}
compute_bit_allocation(s, smr, bit_alloc, &padding);
init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE);
encode_frame(s, bit_alloc, padding);
s->nb_samples += MPA_FRAME_SIZE;
return pbBufPtr(&s->pb) - s->pb.buf;
}
static av_cold int MPA_encode_close(AVCodecContext *avctx)
{
av_freep(&avctx->coded_frame);
return 0;
}
AVCodec mp2_encoder = {
"mp2",
CODEC_TYPE_AUDIO,
CODEC_ID_MP2,
sizeof(MpegAudioContext),
MPA_encode_init,
MPA_encode_frame,
MPA_encode_close,
NULL,
.sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
};
#undef FIX

View File

@ -4,8 +4,21 @@
*
* Copyright (c) 2000, 2001 Fabrice Bellard.
*
* The licence of this code is contained in file LICENCE found in the
* same archive
* 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
*/
/**
@ -14,6 +27,12 @@
* Most of them come from the mpeg audio specification.
*/
#ifndef FFMPEG_MPEGAUDIOTAB_H
#define FFMPEG_MPEGAUDIOTAB_H
#include <stdint.h>
#include "mpegaudio.h"
#define SQRT2 1.41421356237309514547
static const int costab32[30] = {
@ -77,7 +96,7 @@ static unsigned short total_quant_bits[17];
/* signal to noise ratio of each quantification step (could be
computed from quant_steps[]). The values are dB multiplied by 10
*/
static unsigned short quant_snr[17] = {
static const unsigned short quant_snr[17] = {
70, 110, 160, 208,
253, 316, 378, 439,
499, 559, 620, 680,
@ -96,3 +115,4 @@ static const float fixed_smr[SBLIMIT] = {
static const unsigned char nb_scale_factors[4] = { 3, 2, 1, 2 };
#endif /* FFMPEG_MPEGAUDIOTAB_H */

File diff suppressed because it is too large Load Diff

View File

@ -3,19 +3,21 @@
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This library is free software; you can redistribute it and/or
* 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 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* 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 this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@ -23,22 +25,26 @@
* mpegvideo header.
*/
#ifndef AVCODEC_MPEGVIDEO_H
#define AVCODEC_MPEGVIDEO_H
#ifndef FFMPEG_MPEGVIDEO_H
#define FFMPEG_MPEGVIDEO_H
#include "dsputil.h"
#include "bitstream.h"
#include "ratecontrol.h"
#include "parser.h"
#include "mpeg12data.h"
#include "rl.h"
#define FRAME_SKIPED 100 ///< return value for header parsers if frame is not coded
#define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded
enum OutputFormat {
FMT_MPEG1,
FMT_H261,
FMT_H263,
FMT_MJPEG,
FMT_H264,
};
#define EDGE_WIDTH 16
#define MPEG_BUF_SIZE (16 * 1024)
#define QMAT_SHIFT_MMX 16
@ -47,83 +53,27 @@ enum OutputFormat {
#define MAX_FCODE 7
#define MAX_MV 2048
#define MAX_PICTURE_COUNT 15
#define MAX_THREADS 8
#define MAX_PICTURE_COUNT 32
#define ME_MAP_SIZE 64
#define ME_MAP_SHIFT 3
#define ME_MAP_MV_BITS 11
/* run length table */
#define MAX_RUN 64
#define MAX_LEVEL 64
#define MAX_MB_BYTES (30*16*16*3/8 + 120)
#define I_TYPE FF_I_TYPE ///< Intra
#define P_TYPE FF_P_TYPE ///< Predicted
#define B_TYPE FF_B_TYPE ///< Bi-dir predicted
#define S_TYPE FF_S_TYPE ///< S(GMC)-VOP MPEG4
#define SI_TYPE FF_SI_TYPE ///< Switching Intra
#define SP_TYPE FF_SP_TYPE ///< Switching Predicted
#define INPLACE_OFFSET 16
typedef struct Predictor{
double coeff;
double count;
double decay;
} Predictor;
typedef struct RateControlEntry{
int pict_type;
float qscale;
int mv_bits;
int i_tex_bits;
int p_tex_bits;
int misc_bits;
uint64_t expected_bits;
int new_pict_type;
float new_qscale;
int mc_mb_var_sum;
int mb_var_sum;
int i_count;
int f_code;
int b_code;
}RateControlEntry;
/**
* rate control context.
*/
typedef struct RateControlContext{
FILE *stats_file;
int num_entries; ///< number of RateControlEntries
RateControlEntry *entry;
double buffer_index; ///< amount of bits in the video/audio buffer
Predictor pred[5];
double short_term_qsum; ///< sum of recent qscales
double short_term_qcount; ///< count of recent qscales
double pass1_rc_eq_output_sum;///< sum of the output of the rc equation, this is used for normalization
double pass1_wanted_bits; ///< bits which should have been outputed by the pass1 code (including complexity init)
double last_qscale;
double last_qscale_for[5]; ///< last qscale for a specific pict type, used for max_diff & ipb factor stuff
int last_mc_mb_var_sum;
int last_mb_var_sum;
uint64_t i_cplx_sum[5];
uint64_t p_cplx_sum[5];
uint64_t mv_bits_sum[5];
uint64_t qscale_sum[5];
int frame_count[5];
int last_non_b_pict_type;
}RateControlContext;
/**
* Scantable.
*/
typedef struct ScanTable{
const uint8_t *scantable;
uint8_t permutated[64];
uint8_t raster_end[64];
#ifdef ARCH_POWERPC
/** Used by dct_quantise_alitvec to find last-non-zero */
uint8_t __align8 inverse[64];
#endif
} ScanTable;
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
#define GOP_START_CODE 0x000001b8
#define PICTURE_START_CODE 0x00000100
#define SLICE_MIN_START_CODE 0x00000101
#define SLICE_MAX_START_CODE 0x000001af
#define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2
/**
* Picture.
@ -136,9 +86,8 @@ typedef struct Picture{
*/
uint8_t *interpolated[3];
int16_t (*motion_val_base[2])[2];
int8_t *ref_index[2];
uint32_t *mb_type_base;
#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if theres just one type
#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type
#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
#define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM)
@ -160,77 +109,83 @@ typedef struct Picture{
#define IS_ACPRED(a) ((a)&MB_TYPE_ACPRED)
#define IS_QUANT(a) ((a)&MB_TYPE_QUANT)
#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0<<((part)+2*(list))))
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note doesnt work if subMBs
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note does not work if subMBs
#define HAS_CBP(a) ((a)&MB_TYPE_CBP)
int field_poc[2]; ///< h264 top/bottom POC
int poc; ///< h264 frame POC
int frame_num; ///< h264 frame_num
int pic_id; ///< h264 pic_num or long_term_pic_idx
int frame_num; ///< h264 frame_num (raw frame_num from slice header)
int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num,
pic_num & max_pic_num; long -> long_pic_num) */
int long_ref; ///< 1->long term reference 0->short term reference
int ref_poc[2][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice)
int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice)
int mb_var_sum; ///< sum of MB variance for current frame
int mc_mb_var_sum; ///< motion compensated MB variance for current frame
uint16_t *mb_var; ///< Table for MB variances
uint16_t *mc_mb_var; ///< Table for motion compensated MB variances
uint8_t *mb_mean; ///< Table for MB luminance
int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decission FIXME remove
int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove
int b_frame_score; /* */
} Picture;
typedef struct ParseContext{
uint8_t *buffer;
int index;
int last_index;
int buffer_size;
uint32_t state; ///< contains the last few bytes in MSB order
int frame_start_found;
int overread; ///< the number of bytes which where irreversibly read from the next frame
int overread_index; ///< the index into ParseContext.buffer of the overreaded bytes
} ParseContext;
struct MpegEncContext;
/**
* Motion estimation context.
*/
typedef struct MotionEstContext{
int skip; ///< set if ME is skiped for the current MB
int co_located_mv[4][2]; ///< mv from last p frame for direct mode ME
AVCodecContext *avctx;
int skip; ///< set if ME is skipped for the current MB
int co_located_mv[4][2]; ///< mv from last P-frame for direct mode ME
int direct_basis_mv[4][2];
uint8_t *scratchpad; ///< data area for the me algo, so that the ME doesnt need to malloc/free
uint8_t *scratchpad; ///< data area for the ME algo, so that the ME does not need to malloc/free
uint8_t *best_mb;
uint8_t *temp_mb[2];
uint8_t *temp;
int best_bits;
uint32_t *map; ///< map to avoid duplicate evaluations
uint32_t *score_map; ///< map to store the scores
int map_generation;
int pre_penalty_factor;
int penalty_factor;
int penalty_factor; /*!< an estimate of the bits required to
code a given mv value, e.g. (1,0) takes
more bits than (0,0). We have to
estimate whether any reduction in
residual is worth the extra bits. */
int sub_penalty_factor;
int mb_penalty_factor;
int flags;
int sub_flags;
int mb_flags;
int pre_pass; ///< = 1 for the pre pass
int dia_size;
int xmin;
int xmax;
int ymin;
int ymax;
int pred_x;
int pred_y;
uint8_t *src[4][4];
uint8_t *ref[4][4];
int stride;
int uvstride;
/* temp variables for picture complexity calculation */
int mc_mb_var_sum_temp;
int mb_var_sum_temp;
int scene_change_score;
/* cmp, chroma_cmp;*/
op_pixels_func (*hpel_put)[4];
op_pixels_func (*hpel_avg)[4];
qpel_mc_func (*qpel_put)[16];
qpel_mc_func (*qpel_avg)[16];
uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV
uint8_t *current_mv_penalty;
int (*sub_motion_search)(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[6], int stride, int uvstride,
int size, int h, uint8_t * const mv_penalty);
int (*motion_search[7])(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[6], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty);
int (*pre_motion_search)(struct MpegEncContext * s,
int *mx_ptr, int *my_ptr,
int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[6], int stride, int uvstride, int16_t (*last_mv)[2],
int ref_mv_scale, uint8_t * const mv_penalty);
int (*get_mb_score)(struct MpegEncContext * s, int mx, int my, int pred_x, int pred_y, uint8_t *src_data[3],
uint8_t *ref_data[6], int stride, int uvstride,
uint8_t * const mv_penalty);
int src_index, int ref_index,
int size, int h);
}MotionEstContext;
/**
@ -251,7 +206,7 @@ typedef struct MpegEncContext {
int h263_msmpeg4; ///< generate MSMPEG4 compatible stream (deprecated, use msmpeg4_version instead)
int h263_flv; ///< use flv h263 header
int codec_id; /* see CODEC_ID_xxx */
enum CodecID codec_id; /* see CODEC_ID_xxx */
int fixed_qscale; ///< fixed qscale if non zero
int encoding; ///< true if we are encoding (vs decoding)
int flags; ///< AVCodecContext.flags (HQ, MV4, ...)
@ -261,6 +216,8 @@ typedef struct MpegEncContext {
int chroma_elim_threshold;
int strict_std_compliance; ///< strictly follow the std (MPEG4, ...)
int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically
int codec_tag; ///< internal codec_tag upper case converted from avctx codec_tag
int stream_codec_tag; ///< internal stream_codec_tag upper case converted from avctx stream_codec_tag
/* the following fields are managed internally by the encoder */
/** bit output */
@ -268,16 +225,17 @@ typedef struct MpegEncContext {
/* sequence parameters */
int context_initialized;
int input_picture_number; ///< used to set pic->display_picture_number, shouldnt be used for/by anything else
int coded_picture_number; ///< used to set pic->coded_picture_number, shouldnt be used for/by anything else
int input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else
int coded_picture_number; ///< used to set pic->coded_picture_number, should not be used for/by anything else
int picture_number; //FIXME remove, unclear definition
int picture_in_gop_number; ///< 0-> first pic in gop, ...
int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input
int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video()
int mb_width, mb_height; ///< number of MBs horizontally & vertically
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressng of left & top MBs withoutt sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressng
int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressng
int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replicateion)
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing
int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing
int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication)
int mb_num; ///< number of MBs of a picture
int linesize; ///< line size, in bytes, may be different from width
int uvlinesize; ///< line size, for chroma in bytes, may be different from width
@ -285,6 +243,10 @@ typedef struct MpegEncContext {
Picture **input_picture; ///< next pictures on display order for encoding
Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding
int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
struct MpegEncContext *thread_context[MAX_THREADS];
/**
* copy of the previous picture structure.
* note, linesize & data, might not match the previous picture (for field pictures)
@ -314,18 +276,21 @@ typedef struct MpegEncContext {
Picture *current_picture_ptr; ///< pointer to the current picture
uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization
int last_dc[3]; ///< last DC values for MPEG1
int16_t *dc_val_base;
int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
int16_t dc_cache[4*5];
int y_dc_scale, c_dc_scale;
uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table
uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table
const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table
const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table
const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263)
uint8_t *coded_block_base;
uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
int16_t (*ac_val_base)[16];
int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous
int ac_pred;
uint8_t *prev_pict_types; ///< previous picture types in bitstream order, used for mb skip
#define PREV_PICT_TYPES_BUFFER_SIZE 256
int mb_skiped; ///< MUST BE SET only during DECODING
int mb_skipped; ///< MUST BE SET only during DECODING
uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example)
and used for b-frame encoding & decoding (contains skip table of next P Frame) */
uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding
@ -333,24 +298,31 @@ typedef struct MpegEncContext {
uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding
uint8_t *allocated_edge_emu_buffer;
uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer
uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision
uint8_t *obmc_scratchpad;
uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers
int qscale; ///< QP
int chroma_qscale; ///< chroma QP
int lambda; ///< lagrange multipler used in rate distortion
int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
unsigned int lambda; ///< lagrange multipler used in rate distortion
unsigned int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT
int *lambda_table;
int adaptive_quant; ///< use adaptive quantization
int dquant; ///< qscale difference to prev qscale
int pict_type; ///< I_TYPE, P_TYPE, B_TYPE, ...
int last_pict_type;
int pict_type; ///< FF_I_TYPE, FF_P_TYPE, FF_B_TYPE, ...
int last_pict_type; //FIXME removes
int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol
int dropable;
int frame_rate_index;
int last_lambda_for[5]; ///< last lambda for a specific pict type
int skipdct; ///< skip dct and code zero residual
/* motion compensation */
int unrestricted_mv; ///< mv can point outside of the coded picture
int h263_long_vectors; ///< use horrible h263v1 long vector mode
int decode; ///< if 0 then decoding will be skiped (for encoding b frames for example)
int decode; ///< if 0 then decoding will be skipped (for encoding b frames for example)
DSPContext dsp; ///< pointers for accelerated dsp fucntions
DSPContext dsp; ///< pointers for accelerated dsp functions
int f_code; ///< forward MV resolution
int b_code; ///< backward MV resolution for B Frames (mpeg4)
int16_t (*p_mv_table_base)[2];
@ -372,10 +344,9 @@ typedef struct MpegEncContext {
uint8_t (*p_field_select_table[2]);
uint8_t (*b_field_select_table[2][2]);
int me_method; ///< ME algorithm
int scene_change_score;
int mv_dir;
#define MV_DIR_BACKWARD 1
#define MV_DIR_FORWARD 2
#define MV_DIR_FORWARD 1
#define MV_DIR_BACKWARD 2
#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4)
int mv_type;
#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb
@ -392,13 +363,14 @@ typedef struct MpegEncContext {
int field_select[2][2];
int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG1 & B-frame MPEG4
uint8_t *fcode_tab; ///< smallest fcode needed for each MV
int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv
MotionEstContext me;
int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...)
for b-frames rounding mode is allways 0 */
for b-frames rounding mode is always 0 */
int hurry_up; /**< when set to 1 during decoding, b frames will be skiped
int hurry_up; /**< when set to 1 during decoding, b frames will be skipped
when set to 2 idct/dequant will be skipped too */
/* macroblock layer */
@ -409,7 +381,7 @@ typedef struct MpegEncContext {
#define CANDIDATE_MB_TYPE_INTRA 0x01
#define CANDIDATE_MB_TYPE_INTER 0x02
#define CANDIDATE_MB_TYPE_INTER4V 0x04
#define CANDIDATE_MB_TYPE_SKIPED 0x08
#define CANDIDATE_MB_TYPE_SKIPPED 0x08
//#define MB_TYPE_GMC 0x10
#define CANDIDATE_MB_TYPE_DIRECT 0x10
@ -422,6 +394,8 @@ typedef struct MpegEncContext {
#define CANDIDATE_MB_TYPE_BACKWARD_I 0x400
#define CANDIDATE_MB_TYPE_BIDIR_I 0x800
#define CANDIDATE_MB_TYPE_DIRECT0 0x1000
int block_index[6]; ///< index to current MB in block based arrays with edges
int block_wrap[6];
uint8_t *dest[3];
@ -447,7 +421,7 @@ typedef struct MpegEncContext {
uint8_t *chroma_dc_vlc_length;
#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
int coded_score[6];
int coded_score[8];
/** precomputed matrix (combine qscale and DCT renorm) */
int (*q_intra_matrix)[64];
@ -455,9 +429,9 @@ typedef struct MpegEncContext {
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
uint16_t (*q_intra_matrix16)[2][64];
uint16_t (*q_inter_matrix16)[2][64];
int block_last_index[6]; ///< last non zero coefficient in block
int block_last_index[12]; ///< last non zero coefficient in block
/* scantables */
ScanTable __align8 intra_scantable;
DECLARE_ALIGNED_8(ScanTable, intra_scantable);
ScanTable intra_h_scantable;
ScanTable intra_v_scantable;
ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce tha cache usage
@ -473,6 +447,7 @@ typedef struct MpegEncContext {
int64_t wanted_bits;
int64_t total_bits;
int frame_bits; ///< bits used for the current frame
int next_lambda; ///< next lambda used for retrying to encode a frame
RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
/* statistics, used for 2-pass encoding */
@ -520,9 +495,9 @@ typedef struct MpegEncContext {
int alt_inter_vlc; ///< alternative inter vlc
int modified_quant;
int loop_filter;
int custom_pcf;
/* mpeg4 specific */
int time_increment_resolution;
int time_increment_bits; ///< number of bits to represent the fractional part of time
int last_time_base;
int time_base; ///< time in seconds of last I,P,S Frame
@ -563,11 +538,9 @@ typedef struct MpegEncContext {
int vo_type;
int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders
int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc
int use_intra_dc_vlc;
PutBitContext tex_pb; ///< used for data partitioned VOPs
PutBitContext pb2; ///< used for data partitioned VOPs
#define PB_BUFFER_SIZE 1024*256
uint8_t *tex_pb_buffer;
uint8_t *pb2_buffer;
int mpeg_quant;
int t_frame; ///< time distance of first I -> B, used for interlaced b frames
int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4
@ -576,14 +549,13 @@ typedef struct MpegEncContext {
int divx_version;
int divx_build;
int divx_packed;
#define BITSTREAM_BUFFER_SIZE 1024*256
uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
int bitstream_buffer_size;
unsigned int allocated_bitstream_buffer_size;
int xvid_build;
/* lavc specific stuff, used to workaround bugs in libavcodec */
int ffmpeg_version;
int lavc_build;
/* RV10 specific */
@ -594,8 +566,6 @@ typedef struct MpegEncContext {
struct MJpegContext *mjpeg_ctx;
int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1}
int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1}
int mjpeg_write_tables; ///< do we want to have quantisation- and huffmantables in the jpeg file ?
int mjpeg_data_only_frames; ///< frames only with SOI, SOS and EOI markers
/* MSMPEG4 specific */
int mv_table_index;
@ -642,6 +612,13 @@ typedef struct MpegEncContext {
int alternate_scan;
int repeat_first_field;
int chroma_420_type;
int chroma_format;
#define CHROMA_420 1
#define CHROMA_422 2
#define CHROMA_444 3
int chroma_x_shift;//depend on pix_format, that depend on chroma_format
int chroma_y_shift;
int progressive_frame;
int full_pel[2];
int interlaced_dct;
@ -656,7 +633,7 @@ typedef struct MpegEncContext {
short * pblocks[12];
DCTELEM (*block)[64]; ///< points to one of the following blocks
DCTELEM (*blocks)[6][64]; // for HQ mode we need to keep the best block
DCTELEM (*blocks)[8][64]; // for HQ mode we need to keep the best block
int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
#define SLICE_OK 0
#define SLICE_ERROR -1
@ -675,6 +652,10 @@ typedef struct MpegEncContext {
DCTELEM *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
DCTELEM *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h261_intra)(struct MpegEncContext *s,
DCTELEM *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_h261_inter)(struct MpegEncContext *s,
DCTELEM *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
DCTELEM *block/*align 16*/, int n, int qscale);
void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
@ -685,71 +666,57 @@ typedef struct MpegEncContext {
} MpegEncContext;
int DCT_common_init(MpegEncContext *s);
void MPV_decode_defaults(MpegEncContext *s);
int MPV_common_init(MpegEncContext *s);
void MPV_common_end(MpegEncContext *s);
void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]);
int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
void MPV_frame_end(MpegEncContext *s);
int MPV_encode_init(AVCodecContext *avctx);
int MPV_encode_end(AVCodecContext *avctx);
int MPV_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data);
#ifdef HAVE_MMX
void MPV_common_init_mmx(MpegEncContext *s);
#endif
#ifdef ARCH_ALPHA
void MPV_common_init_axp(MpegEncContext *s);
#endif
#ifdef HAVE_MLIB
void MPV_common_init_mlib(MpegEncContext *s);
#endif
#ifdef HAVE_MMI
void MPV_common_init_mmi(MpegEncContext *s);
#endif
#ifdef ARCH_ARMV4L
void MPV_common_init_armv4l(MpegEncContext *s);
#endif
#ifdef ARCH_POWERPC
void MPV_common_init_ppc(MpegEncContext *s);
#endif
extern void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w);
void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length);
void MPV_common_init_altivec(MpegEncContext *s);
void ff_clean_intra_table_entries(MpegEncContext *s);
void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int block_h,
int src_x, int src_y, int w, int h);
#define END_NOT_FOUND -100
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix);
void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
const uint8_t *ff_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
void ff_er_frame_start(MpegEncContext *s);
void ff_er_frame_end(MpegEncContext *s);
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status);
extern enum PixelFormat ff_yuv420p_list[2];
int ff_dct_common_init(MpegEncContext *s);
void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
void ff_init_block_index(MpegEncContext *s);
static inline void ff_update_block_index(MpegEncContext *s){
const int block_size= 8>>s->avctx->lowres;
s->block_index[0]+=2;
s->block_index[1]+=2;
s->block_index[2]+=2;
s->block_index[3]+=2;
s->block_index[4]++;
s->block_index[5]++;
s->dest[0]+= 16;
s->dest[1]+= 8;
s->dest[2]+= 8;
s->dest[0]+= 2*block_size;
s->dest[1]+= block_size;
s->dest[2]+= block_size;
}
static inline int get_bits_diff(MpegEncContext *s){
const int bits= get_bit_count(&s->pb);
const int bits= put_bits_count(&s->pb);
const int last= s->last_bits;
s->last_bits = bits;
@ -757,6 +724,14 @@ static inline int get_bits_diff(MpegEncContext *s){
return bits - last;
}
static inline int ff_h263_round_chroma(int x){
static const uint8_t h263_chroma_roundtab[16] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
};
return h263_chroma_roundtab[x & 0xf] + (x >> 3);
}
/* motion_est.c */
void ff_estimate_p_frame_motion(MpegEncContext * s,
int mb_x, int mb_y);
@ -766,14 +741,16 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type);
void ff_fix_long_p_mvs(MpegEncContext * s);
void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select,
int16_t (*mv_table)[2], int f_code, int type, int truncate);
void ff_init_me(MpegEncContext *s);
int ff_init_me(MpegEncContext *s);
int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y);
int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr,
int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
int ref_mv_scale, int size, int h);
int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index,
int ref_index, int size, int h, int add_rate);
/* mpeg12.c */
extern const int16_t ff_mpeg1_default_intra_matrix[64];
extern const int16_t ff_mpeg1_default_non_intra_matrix[64];
extern uint8_t ff_mpeg1_dc_scale_table[128];
extern const uint8_t ff_mpeg1_dc_scale_table[128];
void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
void mpeg1_encode_mb(MpegEncContext *s,
@ -782,49 +759,32 @@ void mpeg1_encode_mb(MpegEncContext *s,
void ff_mpeg1_encode_init(MpegEncContext *s);
void ff_mpeg1_encode_slice_header(MpegEncContext *s);
void ff_mpeg1_clean_buffers(MpegEncContext *s);
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
/** RLTable. */
typedef struct RLTable {
int n; ///< number of entries of table_vlc minus 1
int last; ///< number of values for last = 0
const uint16_t (*table_vlc)[2];
const int8_t *table_run;
const int8_t *table_level;
uint8_t *index_run[2]; ///< encoding only
int8_t *max_level[2]; ///< encoding & decoding
int8_t *max_run[2]; ///< encoding & decoding
VLC vlc; ///< decoding only deprected FIXME remove
RL_VLC_ELEM *rl_vlc[32]; ///< decoding only
} RLTable;
void init_rl(RLTable *rl);
void init_vlc_rl(RLTable *rl);
static inline int get_rl_index(const RLTable *rl, int last, int run, int level)
{
int index;
index = rl->index_run[last][run];
if (index >= rl->n)
return rl->n;
if (level > rl->max_level[last][run])
return rl->n;
return index + level - 1;
}
extern uint8_t ff_mpeg4_y_dc_scale_table[32];
extern uint8_t ff_mpeg4_c_dc_scale_table[32];
extern uint8_t ff_aic_dc_scale_table[32];
extern const uint8_t ff_mpeg4_y_dc_scale_table[32];
extern const uint8_t ff_mpeg4_c_dc_scale_table[32];
extern const uint8_t ff_aic_dc_scale_table[32];
extern const int16_t ff_mpeg4_default_intra_matrix[64];
extern const int16_t ff_mpeg4_default_non_intra_matrix[64];
extern const uint8_t ff_h263_chroma_qscale_table[32];
extern const uint8_t ff_h263_loop_filter_strength[32];
/* h261.c */
void ff_h261_loop_filter(MpegEncContext *s);
void ff_h261_reorder_mb_index(MpegEncContext* s);
void ff_h261_encode_mb(MpegEncContext *s,
DCTELEM block[6][64],
int motion_x, int motion_y);
void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number);
void ff_h261_encode_init(MpegEncContext *s);
int ff_h261_get_picture_format(int width, int height);
/* h263.c, h263dec.c */
int ff_h263_decode_init(AVCodecContext *avctx);
int ff_h263_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size);
const uint8_t *buf, int buf_size);
int ff_h263_decode_end(AVCodecContext *avctx);
void h263_encode_mb(MpegEncContext *s,
DCTELEM block[6][64],
@ -835,11 +795,11 @@ void mpeg4_encode_mb(MpegEncContext *s,
void h263_encode_picture_header(MpegEncContext *s, int picture_number);
void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_gob_header(MpegEncContext * s, int mb_line);
int16_t *h263_pred_motion(MpegEncContext * s, int block,
int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
int *px, int *py);
void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
int dir);
void ff_set_mpeg4_time(MpegEncContext * s, int picture_number);
void ff_set_mpeg4_time(MpegEncContext * s);
void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
void h263_encode_init(MpegEncContext *s);
void h263_decode_init_vlc(MpegEncContext *s);
@ -870,13 +830,15 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s);
int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
int ff_h263_resync(MpegEncContext *s);
int ff_h263_get_gob_height(MpegEncContext *s);
void ff_mpeg4_init_direct_mv(MpegEncContext *s);
int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
inline int ff_h263_round_chroma(int x);
void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code);
/* rv10.c */
void rv10_encode_picture_header(MpegEncContext *s, int picture_number);
int rv_decode_dc(MpegEncContext *s, int n);
void rv20_encode_picture_header(MpegEncContext *s, int picture_number);
/* msmpeg4.c */
@ -901,25 +863,5 @@ void ff_wmv2_encode_mb(MpegEncContext * s,
DCTELEM block[6][64],
int motion_x, int motion_y);
/* mjpeg.c */
int mjpeg_init(MpegEncContext *s);
void mjpeg_close(MpegEncContext *s);
void mjpeg_encode_mb(MpegEncContext *s,
DCTELEM block[6][64]);
void mjpeg_picture_header(MpegEncContext *s);
void mjpeg_picture_trailer(MpegEncContext *s);
#endif /* FFMPEG_MPEGVIDEO_H */
/* rate control */
int ff_rate_control_init(MpegEncContext *s);
float ff_rate_estimate_qscale(MpegEncContext *s);
void ff_write_pass1_stats(MpegEncContext *s);
void ff_rate_control_uninit(MpegEncContext *s);
double ff_eval(char *s, double *const_value, const char **const_name,
double (**func1)(void *, double), const char **func1_name,
double (**func2)(void *, double, double), char **func2_name,
void *opaque);
int ff_vbv_update(MpegEncContext *s, int frame_size);
#endif /* AVCODEC_MPEGVIDEO_H */

View File

@ -0,0 +1,901 @@
/*
* The simplest mpeg encoder (well, it was the simplest!)
* Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* 4MV & hq & B-frame encoding stuff 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 mpegvideo_common.h
* The simplest mpeg encoder (well, it was the simplest!).
*/
#ifndef FFMPEG_MPEGVIDEO_COMMON_H
#define FFMPEG_MPEGVIDEO_COMMON_H
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "mjpegenc.h"
#include "msmpeg4.h"
#include "faandct.h"
#include <limits.h>
int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
void denoise_dct_c(MpegEncContext *s, DCTELEM *block);
void copy_picture(Picture *dst, Picture *src);
/**
* allocates a Picture
* The pixels are allocated/set by calling get_buffer() if shared=0
*/
int alloc_picture(MpegEncContext *s, Picture *pic, int shared);
/**
* sets the given MpegEncContext to common defaults (same for encoding and decoding).
* the changed fields will not depend upon the prior state of the MpegEncContext.
*/
void MPV_common_defaults(MpegEncContext *s);
static inline void gmc1_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
uint8_t **ref_picture)
{
uint8_t *ptr;
int offset, src_x, src_y, linesize, uvlinesize;
int motion_x, motion_y;
int emu=0;
motion_x= s->sprite_offset[0][0];
motion_y= s->sprite_offset[0][1];
src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
motion_x<<=(3-s->sprite_warping_accuracy);
motion_y<<=(3-s->sprite_warping_accuracy);
src_x = av_clip(src_x, -16, s->width);
if (src_x == s->width)
motion_x =0;
src_y = av_clip(src_y, -16, s->height);
if (src_y == s->height)
motion_y =0;
linesize = s->linesize;
uvlinesize = s->uvlinesize;
ptr = ref_picture[0] + (src_y * linesize) + src_x;
if(s->flags&CODEC_FLAG_EMU_EDGE){
if( (unsigned)src_x >= s->h_edge_pos - 17
|| (unsigned)src_y >= s->v_edge_pos - 17){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
ptr= s->edge_emu_buffer;
}
}
if((motion_x|motion_y)&7){
s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
}else{
int dxy;
dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
if (s->no_rounding){
s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
}else{
s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
}
}
if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;
motion_x= s->sprite_offset[1][0];
motion_y= s->sprite_offset[1][1];
src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
motion_x<<=(3-s->sprite_warping_accuracy);
motion_y<<=(3-s->sprite_warping_accuracy);
src_x = av_clip(src_x, -8, s->width>>1);
if (src_x == s->width>>1)
motion_x =0;
src_y = av_clip(src_y, -8, s->height>>1);
if (src_y == s->height>>1)
motion_y =0;
offset = (src_y * uvlinesize) + src_x;
ptr = ref_picture[1] + offset;
if(s->flags&CODEC_FLAG_EMU_EDGE){
if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9
|| (unsigned)src_y >= (s->v_edge_pos>>1) - 9){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr= s->edge_emu_buffer;
emu=1;
}
}
s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
ptr = ref_picture[2] + offset;
if(emu){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
return;
}
static inline void gmc_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
uint8_t **ref_picture)
{
uint8_t *ptr;
int linesize, uvlinesize;
const int a= s->sprite_warping_accuracy;
int ox, oy;
linesize = s->linesize;
uvlinesize = s->uvlinesize;
ptr = ref_picture[0];
ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
s->dsp.gmc(dest_y, ptr, linesize, 16,
ox,
oy,
s->sprite_delta[0][0], s->sprite_delta[0][1],
s->sprite_delta[1][0], s->sprite_delta[1][1],
a+1, (1<<(2*a+1)) - s->no_rounding,
s->h_edge_pos, s->v_edge_pos);
s->dsp.gmc(dest_y+8, ptr, linesize, 16,
ox + s->sprite_delta[0][0]*8,
oy + s->sprite_delta[1][0]*8,
s->sprite_delta[0][0], s->sprite_delta[0][1],
s->sprite_delta[1][0], s->sprite_delta[1][1],
a+1, (1<<(2*a+1)) - s->no_rounding,
s->h_edge_pos, s->v_edge_pos);
if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;
ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
ptr = ref_picture[1];
s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
ox,
oy,
s->sprite_delta[0][0], s->sprite_delta[0][1],
s->sprite_delta[1][0], s->sprite_delta[1][1],
a+1, (1<<(2*a+1)) - s->no_rounding,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr = ref_picture[2];
s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
ox,
oy,
s->sprite_delta[0][0], s->sprite_delta[0][1],
s->sprite_delta[1][0], s->sprite_delta[1][1],
a+1, (1<<(2*a+1)) - s->no_rounding,
s->h_edge_pos>>1, s->v_edge_pos>>1);
}
static inline int hpel_motion(MpegEncContext *s,
uint8_t *dest, uint8_t *src,
int field_based, int field_select,
int src_x, int src_y,
int width, int height, int stride,
int h_edge_pos, int v_edge_pos,
int w, int h, op_pixels_func *pix_op,
int motion_x, int motion_y)
{
int dxy;
int emu=0;
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
src_x += motion_x >> 1;
src_y += motion_y >> 1;
/* WARNING: do no forget half pels */
src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu?
if (src_x == width)
dxy &= ~1;
src_y = av_clip(src_y, -16, height);
if (src_y == height)
dxy &= ~2;
src += src_y * stride + src_x;
if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w
|| (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos);
src= s->edge_emu_buffer;
emu=1;
}
}
if(field_select)
src += s->linesize;
pix_op[dxy](dest, src, stride, h);
return emu;
}
static av_always_inline
void mpeg_motion_internal(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
int field_based, int bottom_field, int field_select,
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
int motion_x, int motion_y, int h, int is_mpeg12)
{
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
int dxy, uvdxy, mx, my, src_x, src_y,
uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize;
#if 0
if(s->quarter_sample)
{
motion_x>>=1;
motion_y>>=1;
}
#endif
v_edge_pos = s->v_edge_pos >> field_based;
linesize = s->current_picture.linesize[0] << field_based;
uvlinesize = s->current_picture.linesize[1] << field_based;
dxy = ((motion_y & 1) << 1) | (motion_x & 1);
src_x = s->mb_x* 16 + (motion_x >> 1);
src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1);
if (!is_mpeg12 && s->out_format == FMT_H263) {
if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){
mx = (motion_x>>1)|(motion_x&1);
my = motion_y >>1;
uvdxy = ((my & 1) << 1) | (mx & 1);
uvsrc_x = s->mb_x* 8 + (mx >> 1);
uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);
}else{
uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
uvsrc_x = src_x>>1;
uvsrc_y = src_y>>1;
}
}else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261
mx = motion_x / 4;
my = motion_y / 4;
uvdxy = 0;
uvsrc_x = s->mb_x*8 + mx;
uvsrc_y = s->mb_y*8 + my;
} else {
if(s->chroma_y_shift){
mx = motion_x / 2;
my = motion_y / 2;
uvdxy = ((my & 1) << 1) | (mx & 1);
uvsrc_x = s->mb_x* 8 + (mx >> 1);
uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1);
} else {
if(s->chroma_x_shift){
//Chroma422
mx = motion_x / 2;
uvdxy = ((motion_y & 1) << 1) | (mx & 1);
uvsrc_x = s->mb_x* 8 + (mx >> 1);
uvsrc_y = src_y;
} else {
//Chroma444
uvdxy = dxy;
uvsrc_x = src_x;
uvsrc_y = src_y;
}
}
}
ptr_y = ref_picture[0] + src_y * linesize + src_x;
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
if( (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16
|| (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
if(is_mpeg12 || s->codec_id == CODEC_ID_MPEG2VIDEO ||
s->codec_id == CODEC_ID_MPEG1VIDEO){
av_log(s->avctx,AV_LOG_DEBUG,
"MPEG motion vector out of boundary\n");
return ;
}
ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
17, 17+field_based,
src_x, src_y<<field_based,
s->h_edge_pos, s->v_edge_pos);
ptr_y = s->edge_emu_buffer;
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
ff_emulated_edge_mc(uvbuf ,
ptr_cb, s->uvlinesize,
9, 9+field_based,
uvsrc_x, uvsrc_y<<field_based,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ff_emulated_edge_mc(uvbuf+16,
ptr_cr, s->uvlinesize,
9, 9+field_based,
uvsrc_x, uvsrc_y<<field_based,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr_cb= uvbuf;
ptr_cr= uvbuf+16;
}
}
if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
dest_y += s->linesize;
dest_cb+= s->uvlinesize;
dest_cr+= s->uvlinesize;
}
if(field_select){
ptr_y += s->linesize;
ptr_cb+= s->uvlinesize;
ptr_cr+= s->uvlinesize;
}
pix_op[0][dxy](dest_y, ptr_y, linesize, h);
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
pix_op[s->chroma_x_shift][uvdxy]
(dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
pix_op[s->chroma_x_shift][uvdxy]
(dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
}
if(!is_mpeg12 && (ENABLE_H261_ENCODER || ENABLE_H261_DECODER) &&
s->out_format == FMT_H261){
ff_h261_loop_filter(s);
}
}
/* apply one mpeg motion vector to the three components */
static av_always_inline
void mpeg_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
int field_based, int bottom_field, int field_select,
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
int motion_x, int motion_y, int h)
{
#ifndef CONFIG_SMALL
if(s->out_format == FMT_MPEG1)
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
bottom_field, field_select, ref_picture, pix_op,
motion_x, motion_y, h, 1);
else
#endif
mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, field_based,
bottom_field, field_select, ref_picture, pix_op,
motion_x, motion_y, h, 0);
}
//FIXME move to dsputil, avg variant, 16x16 version
static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
int x;
uint8_t * const top = src[1];
uint8_t * const left = src[2];
uint8_t * const mid = src[0];
uint8_t * const right = src[3];
uint8_t * const bottom= src[4];
#define OBMC_FILTER(x, t, l, m, r, b)\
dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
#define OBMC_FILTER4(x, t, l, m, r, b)\
OBMC_FILTER(x , t, l, m, r, b);\
OBMC_FILTER(x+1 , t, l, m, r, b);\
OBMC_FILTER(x +stride, t, l, m, r, b);\
OBMC_FILTER(x+1+stride, t, l, m, r, b);
x=0;
OBMC_FILTER (x , 2, 2, 4, 0, 0);
OBMC_FILTER (x+1, 2, 1, 5, 0, 0);
OBMC_FILTER4(x+2, 2, 1, 5, 0, 0);
OBMC_FILTER4(x+4, 2, 0, 5, 1, 0);
OBMC_FILTER (x+6, 2, 0, 5, 1, 0);
OBMC_FILTER (x+7, 2, 0, 4, 2, 0);
x+= stride;
OBMC_FILTER (x , 1, 2, 5, 0, 0);
OBMC_FILTER (x+1, 1, 2, 5, 0, 0);
OBMC_FILTER (x+6, 1, 0, 5, 2, 0);
OBMC_FILTER (x+7, 1, 0, 5, 2, 0);
x+= stride;
OBMC_FILTER4(x , 1, 2, 5, 0, 0);
OBMC_FILTER4(x+2, 1, 1, 6, 0, 0);
OBMC_FILTER4(x+4, 1, 0, 6, 1, 0);
OBMC_FILTER4(x+6, 1, 0, 5, 2, 0);
x+= 2*stride;
OBMC_FILTER4(x , 0, 2, 5, 0, 1);
OBMC_FILTER4(x+2, 0, 1, 6, 0, 1);
OBMC_FILTER4(x+4, 0, 0, 6, 1, 1);
OBMC_FILTER4(x+6, 0, 0, 5, 2, 1);
x+= 2*stride;
OBMC_FILTER (x , 0, 2, 5, 0, 1);
OBMC_FILTER (x+1, 0, 2, 5, 0, 1);
OBMC_FILTER4(x+2, 0, 1, 5, 0, 2);
OBMC_FILTER4(x+4, 0, 0, 5, 1, 2);
OBMC_FILTER (x+6, 0, 0, 5, 2, 1);
OBMC_FILTER (x+7, 0, 0, 5, 2, 1);
x+= stride;
OBMC_FILTER (x , 0, 2, 4, 0, 2);
OBMC_FILTER (x+1, 0, 1, 5, 0, 2);
OBMC_FILTER (x+6, 0, 0, 5, 1, 2);
OBMC_FILTER (x+7, 0, 0, 4, 2, 2);
}
/* obmc for 1 8x8 luma block */
static inline void obmc_motion(MpegEncContext *s,
uint8_t *dest, uint8_t *src,
int src_x, int src_y,
op_pixels_func *pix_op,
int16_t mv[5][2]/* mid top left right bottom*/)
#define MID 0
{
int i;
uint8_t *ptr[5];
assert(s->quarter_sample==0);
for(i=0; i<5; i++){
if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
ptr[i]= ptr[MID];
}else{
ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
hpel_motion(s, ptr[i], src, 0, 0,
src_x, src_y,
s->width, s->height, s->linesize,
s->h_edge_pos, s->v_edge_pos,
8, 8, pix_op,
mv[i][0], mv[i][1]);
}
}
put_obmc(dest, ptr, s->linesize);
}
static inline void qpel_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
int field_based, int bottom_field, int field_select,
uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16],
int motion_x, int motion_y, int h)
{
uint8_t *ptr_y, *ptr_cb, *ptr_cr;
int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize;
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
src_x = s->mb_x * 16 + (motion_x >> 2);
src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
v_edge_pos = s->v_edge_pos >> field_based;
linesize = s->linesize << field_based;
uvlinesize = s->uvlinesize << field_based;
if(field_based){
mx= motion_x/2;
my= motion_y>>1;
}else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){
static const int rtab[8]= {0,0,1,1,0,0,0,1};
mx= (motion_x>>1) + rtab[motion_x&7];
my= (motion_y>>1) + rtab[motion_y&7];
}else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){
mx= (motion_x>>1)|(motion_x&1);
my= (motion_y>>1)|(motion_y&1);
}else{
mx= motion_x/2;
my= motion_y/2;
}
mx= (mx>>1)|(mx&1);
my= (my>>1)|(my&1);
uvdxy= (mx&1) | ((my&1)<<1);
mx>>=1;
my>>=1;
uvsrc_x = s->mb_x * 8 + mx;
uvsrc_y = s->mb_y * (8 >> field_based) + my;
ptr_y = ref_picture[0] + src_y * linesize + src_x;
ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
|| (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
17, 17+field_based, src_x, src_y<<field_based,
s->h_edge_pos, s->v_edge_pos);
ptr_y= s->edge_emu_buffer;
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
9, 9 + field_based,
uvsrc_x, uvsrc_y<<field_based,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
9, 9 + field_based,
uvsrc_x, uvsrc_y<<field_based,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr_cb= uvbuf;
ptr_cr= uvbuf + 16;
}
}
if(!field_based)
qpix_op[0][dxy](dest_y, ptr_y, linesize);
else{
if(bottom_field){
dest_y += s->linesize;
dest_cb+= s->uvlinesize;
dest_cr+= s->uvlinesize;
}
if(field_select){
ptr_y += s->linesize;
ptr_cb += s->uvlinesize;
ptr_cr += s->uvlinesize;
}
//damn interlaced mode
//FIXME boundary mirroring is not exactly correct here
qpix_op[1][dxy](dest_y , ptr_y , linesize);
qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize);
}
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
}
}
/**
* h263 chroma 4mv motion compensation.
*/
static inline void chroma_4mv_motion(MpegEncContext *s,
uint8_t *dest_cb, uint8_t *dest_cr,
uint8_t **ref_picture,
op_pixels_func *pix_op,
int mx, int my){
int dxy, emu=0, src_x, src_y, offset;
uint8_t *ptr;
/* In case of 8X8, we construct a single chroma motion vector
with a special rounding */
mx= ff_h263_round_chroma(mx);
my= ff_h263_round_chroma(my);
dxy = ((my & 1) << 1) | (mx & 1);
mx >>= 1;
my >>= 1;
src_x = s->mb_x * 8 + mx;
src_y = s->mb_y * 8 + my;
src_x = av_clip(src_x, -8, s->width/2);
if (src_x == s->width/2)
dxy &= ~1;
src_y = av_clip(src_y, -8, s->height/2);
if (src_y == s->height/2)
dxy &= ~2;
offset = (src_y * (s->uvlinesize)) + src_x;
ptr = ref_picture[1] + offset;
if(s->flags&CODEC_FLAG_EMU_EDGE){
if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8
|| (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
9, 9, src_x, src_y,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr= s->edge_emu_buffer;
emu=1;
}
}
pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
ptr = ref_picture[2] + offset;
if(emu){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
9, 9, src_x, src_y,
s->h_edge_pos>>1, s->v_edge_pos>>1);
ptr= s->edge_emu_buffer;
}
pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
}
static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
/* fetch pixels for estimated mv 4 macroblocks ahead
* optimized for 64byte cache lines */
const int shift = s->quarter_sample ? 2 : 1;
const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
s->dsp.prefetch(pix[0]+off, s->linesize, 4);
off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
}
/**
* motion compensation of a single macroblock
* @param s context
* @param dest_y luma destination pointer
* @param dest_cb chroma cb/u destination pointer
* @param dest_cr chroma cr/v destination pointer
* @param dir direction (0->forward, 1->backward)
* @param ref_picture array[3] of pointers to the 3 planes of the reference picture
* @param pic_op halfpel motion compensation function (average or put normally)
* @param pic_op qpel motion compensation function (average or put normally)
* the motion vectors are taken from s->mv and the MV type from s->mv_type
*/
static av_always_inline void MPV_motion_internal(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr, int dir,
uint8_t **ref_picture,
op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16], int is_mpeg12)
{
int dxy, mx, my, src_x, src_y, motion_x, motion_y;
int mb_x, mb_y, i;
uint8_t *ptr, *dest;
mb_x = s->mb_x;
mb_y = s->mb_y;
prefetch_motion(s, ref_picture, dir);
if(!is_mpeg12 && s->obmc && s->pict_type != FF_B_TYPE){
int16_t mv_cache[4][4][2];
const int xy= s->mb_x + s->mb_y*s->mb_stride;
const int mot_stride= s->b8_stride;
const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
assert(!s->mb_skipped);
memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4);
memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4);
if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){
memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4);
}else{
memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4);
}
if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){
*(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1];
*(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1];
}else{
*(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1];
*(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride];
}
if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){
*(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2];
*(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2];
}else{
*(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2];
*(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride];
}
mx = 0;
my = 0;
for(i=0;i<4;i++) {
const int x= (i&1)+1;
const int y= (i>>1)+1;
int16_t mv[5][2]= {
{mv_cache[y][x ][0], mv_cache[y][x ][1]},
{mv_cache[y-1][x][0], mv_cache[y-1][x][1]},
{mv_cache[y][x-1][0], mv_cache[y][x-1][1]},
{mv_cache[y][x+1][0], mv_cache[y][x+1][1]},
{mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};
//FIXME cleanup
obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
ref_picture[0],
mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
pix_op[1],
mv);
mx += mv[0][0];
my += mv[0][1];
}
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY))
chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
return;
}
switch(s->mv_type) {
case MV_TYPE_16X16:
if(s->mcsel){
if(s->real_sprite_warping_points==1){
gmc1_motion(s, dest_y, dest_cb, dest_cr,
ref_picture);
}else{
gmc_motion(s, dest_y, dest_cb, dest_cr,
ref_picture);
}
}else if(!is_mpeg12 && s->quarter_sample){
qpel_motion(s, dest_y, dest_cb, dest_cr,
0, 0, 0,
ref_picture, pix_op, qpix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
}else if(!is_mpeg12 && ENABLE_WMV2 && s->mspel){
ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
}else
{
mpeg_motion(s, dest_y, dest_cb, dest_cr,
0, 0, 0,
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
}
break;
case MV_TYPE_8X8:
if (!is_mpeg12) {
mx = 0;
my = 0;
if(s->quarter_sample){
for(i=0;i<4;i++) {
motion_x = s->mv[dir][i][0];
motion_y = s->mv[dir][i][1];
dxy = ((motion_y & 3) << 2) | (motion_x & 3);
src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
/* WARNING: do no forget half pels */
src_x = av_clip(src_x, -16, s->width);
if (src_x == s->width)
dxy &= ~3;
src_y = av_clip(src_y, -16, s->height);
if (src_y == s->height)
dxy &= ~12;
ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
if(s->flags&CODEC_FLAG_EMU_EDGE){
if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8
|| (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){
ff_emulated_edge_mc(s->edge_emu_buffer, ptr,
s->linesize, 9, 9,
src_x, src_y,
s->h_edge_pos, s->v_edge_pos);
ptr= s->edge_emu_buffer;
}
}
dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
qpix_op[1][dxy](dest, ptr, s->linesize);
mx += s->mv[dir][i][0]/2;
my += s->mv[dir][i][1]/2;
}
}else{
for(i=0;i<4;i++) {
hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
ref_picture[0], 0, 0,
mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
s->width, s->height, s->linesize,
s->h_edge_pos, s->v_edge_pos,
8, 8, pix_op[1],
s->mv[dir][i][0], s->mv[dir][i][1]);
mx += s->mv[dir][i][0];
my += s->mv[dir][i][1];
}
}
if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY))
chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
}
break;
case MV_TYPE_FIELD:
if (s->picture_structure == PICT_FRAME) {
if(!is_mpeg12 && s->quarter_sample){
for(i=0; i<2; i++){
qpel_motion(s, dest_y, dest_cb, dest_cr,
1, i, s->field_select[dir][i],
ref_picture, pix_op, qpix_op,
s->mv[dir][i][0], s->mv[dir][i][1], 8);
}
}else{
/* top field */
mpeg_motion(s, dest_y, dest_cb, dest_cr,
1, 0, s->field_select[dir][0],
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 8);
/* bottom field */
mpeg_motion(s, dest_y, dest_cb, dest_cr,
1, 1, s->field_select[dir][1],
ref_picture, pix_op,
s->mv[dir][1][0], s->mv[dir][1][1], 8);
}
} else {
if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){
ref_picture= s->current_picture_ptr->data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
0, 0, s->field_select[dir][0],
ref_picture, pix_op,
s->mv[dir][0][0], s->mv[dir][0][1], 16);
}
break;
case MV_TYPE_16X8:
for(i=0; i<2; i++){
uint8_t ** ref2picture;
if(s->picture_structure == s->field_select[dir][i] + 1
|| s->pict_type == FF_B_TYPE || s->first_field){
ref2picture= ref_picture;
}else{
ref2picture= s->current_picture_ptr->data;
}
mpeg_motion(s, dest_y, dest_cb, dest_cr,
0, 0, s->field_select[dir][i],
ref2picture, pix_op,
s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8);
dest_y += 16*s->linesize;
dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;
dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;
}
break;
case MV_TYPE_DMV:
if(s->picture_structure == PICT_FRAME){
for(i=0; i<2; i++){
int j;
for(j=0; j<2; j++){
mpeg_motion(s, dest_y, dest_cb, dest_cr,
1, j, j^i,
ref_picture, pix_op,
s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8);
}
pix_op = s->dsp.avg_pixels_tab;
}
}else{
for(i=0; i<2; i++){
mpeg_motion(s, dest_y, dest_cb, dest_cr,
0, 0, s->picture_structure != i+1,
ref_picture, pix_op,
s->mv[dir][2*i][0],s->mv[dir][2*i][1],16);
// after put we make avg of the same block
pix_op=s->dsp.avg_pixels_tab;
//opposite parity is always in the same frame if this is second field
if(!s->first_field){
ref_picture = s->current_picture_ptr->data;
}
}
}
break;
default: assert(0);
}
}
static inline void MPV_motion(MpegEncContext *s,
uint8_t *dest_y, uint8_t *dest_cb,
uint8_t *dest_cr, int dir,
uint8_t **ref_picture,
op_pixels_func (*pix_op)[4],
qpel_mc_func (*qpix_op)[16])
{
#ifndef CONFIG_SMALL
if(s->out_format == FMT_MPEG1)
MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
ref_picture, pix_op, qpix_op, 1);
else
#endif
MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
ref_picture, pix_op, qpix_op, 0);
}
#endif /* FFMPEG_MPEGVIDEO_COMMON_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,182 @@
/*
* MPEG1 / MPEG2 video parser
* Copyright (c) 2000,2001 Fabrice Bellard.
* Copyright (c) 2002-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
*/
#include "parser.h"
#include "mpegvideo.h"
static void mpegvideo_extract_headers(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s->priv_data;
const uint8_t *buf_end;
const uint8_t *buf_start= buf;
uint32_t start_code;
int frame_rate_index, ext_type, bytes_left;
int frame_rate_ext_n, frame_rate_ext_d;
int picture_structure, top_field_first, repeat_first_field, progressive_frame;
int horiz_size_ext, vert_size_ext, bit_rate_ext;
//FIXME replace the crap with get_bits()
s->repeat_pict = 0;
buf_end = buf + buf_size;
while (buf < buf_end) {
start_code= -1;
buf= ff_find_start_code(buf, buf_end, &start_code);
bytes_left = buf_end - buf;
switch(start_code) {
case PICTURE_START_CODE:
ff_fetch_timestamp(s, buf-buf_start-4, 1);
if (bytes_left >= 2) {
s->pict_type = (buf[1] >> 3) & 7;
}
break;
case SEQ_START_CODE:
if (bytes_left >= 7) {
pc->width = (buf[0] << 4) | (buf[1] >> 4);
pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
avcodec_set_dimensions(avctx, pc->width, pc->height);
frame_rate_index = buf[3] & 0xf;
pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num;
pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den;
avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
avctx->codec_id = CODEC_ID_MPEG1VIDEO;
avctx->sub_id = 1;
}
break;
case EXT_START_CODE:
if (bytes_left >= 1) {
ext_type = (buf[0] >> 4);
switch(ext_type) {
case 0x1: /* sequence extension */
if (bytes_left >= 6) {
horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
vert_size_ext = (buf[2] >> 5) & 3;
bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
frame_rate_ext_n = (buf[5] >> 5) & 3;
frame_rate_ext_d = (buf[5] & 0x1f);
pc->progressive_sequence = buf[1] & (1 << 3);
avctx->has_b_frames= !(buf[5] >> 7);
pc->width |=(horiz_size_ext << 12);
pc->height |=( vert_size_ext << 12);
avctx->bit_rate += (bit_rate_ext << 18) * 400;
avcodec_set_dimensions(avctx, pc->width, pc->height);
avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1);
avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
avctx->codec_id = CODEC_ID_MPEG2VIDEO;
avctx->sub_id = 2; /* forces MPEG2 */
}
break;
case 0x8: /* picture coding extension */
if (bytes_left >= 5) {
picture_structure = buf[2]&3;
top_field_first = buf[3] & (1 << 7);
repeat_first_field = buf[3] & (1 << 1);
progressive_frame = buf[4] & (1 << 7);
/* check if we must repeat the frame */
if (repeat_first_field) {
if (pc->progressive_sequence) {
if (top_field_first)
s->repeat_pict = 4;
else
s->repeat_pict = 2;
} else if (progressive_frame) {
s->repeat_pict = 1;
}
}
}
break;
}
}
break;
case -1:
goto the_end;
default:
/* we stop parsing when we encounter a slice. It ensures
that this function takes a negligible amount of time */
if (start_code >= SLICE_MIN_START_CODE &&
start_code <= SLICE_MAX_START_CODE)
goto the_end;
break;
}
}
the_end: ;
}
static int mpegvideo_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc1 = s->priv_data;
ParseContext *pc= &pc1->pc;
int next;
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
next= buf_size;
}else{
next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
/* we have a full frame : we just parse the first few MPEG headers
to have the full timing information. The time take by this
function should be negligible for uncorrupted streams */
mpegvideo_extract_headers(s, avctx, buf, buf_size);
#if 0
printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
#endif
*poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
static int mpegvideo_split(AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
int i;
uint32_t state= -1;
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
return i-3;
}
return 0;
}
AVCodecParser mpegvideo_parser = {
{ CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
sizeof(ParseContext1),
NULL,
mpegvideo_parse,
ff_parse1_close,
};