提交 0da71265 编写于 作者: M Michael Niedermayer

H264 decoder & demuxer

Originally committed as revision 1732 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 6aafe463
......@@ -2008,7 +2008,7 @@ static void opt_input_file(const char *filename)
enc->debug= debug;
/* if(enc->codec->capabilities & CODEC_CAP_TRUNCATED)
enc->flags|= CODEC_FLAG_TRUNCATED; */
if(/*enc->codec_id==CODEC_ID_MPEG4 || */enc->codec_id==CODEC_ID_MPEG1VIDEO)
if(/*enc->codec_id==CODEC_ID_MPEG4 || */enc->codec_id==CODEC_ID_MPEG1VIDEO || enc->codec_id==CODEC_ID_H264)
enc->flags|= CODEC_FLAG_TRUNCATED;
if(bitexact)
......
......@@ -16,7 +16,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \
motion_est.o imgconvert.o imgresample.o \
mpeg12.o mpegaudiodec.o pcm.o simple_idct.o \
ratecontrol.o adpcm.o eval.o dv.o error_resilience.o \
fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o raw.o
fft.o mdct.o mace.o huffyuv.o cyuv.o opts.o raw.o h264.o golomb.o
ASM_OBJS=
# codecs which are patented in some non free countries like the us
......
......@@ -50,6 +50,7 @@ void avcodec_register_all(void)
register_avcodec(&oggvorbis_decoder);
#endif
register_avcodec(&mpeg1video_encoder);
// register_avcodec(&h264_encoder);
#ifdef CONFIG_RISKY
register_avcodec(&h263_encoder);
register_avcodec(&h263p_encoder);
......@@ -93,6 +94,7 @@ void avcodec_register_all(void)
register_avcodec(&mace6_decoder);
register_avcodec(&huffyuv_decoder);
register_avcodec(&cyuv_decoder);
register_avcodec(&h264_decoder);
#ifdef CONFIG_AC3
register_avcodec(&ac3_decoder);
#endif
......
......@@ -49,6 +49,7 @@ enum CodecID {
CODEC_ID_MACE6,
CODEC_ID_HUFFYUV,
CODEC_ID_CYUV,
CODEC_ID_H264,
/* various pcm "codecs" */
CODEC_ID_PCM_S16LE,
......@@ -210,7 +211,7 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
int key_frame;\
\
/**\
* picture type of the frame, see ?_TYPE below\
* picture type of the frame, see ?_TYPE below.\
* - encoding: set by lavc for coded_picture (and set by user for input)\
* - decoding: set by lavc\
*/\
......@@ -320,7 +321,12 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG,
#define FF_P_TYPE 2 // Predicted
#define FF_B_TYPE 3 // Bi-dir predicted
#define FF_S_TYPE 4 // S(GMC)-VOP MPEG4
#define FF_SI_TYPE 5
#define FF_SP_TYPE 6
/**
* Audio Video Frame.
*/
typedef struct AVFrame {
FF_COMMON_FRAME
} AVFrame;
......@@ -906,6 +912,7 @@ typedef struct AVCodecContext {
#define FF_DEBUG_STARTCODE 0x00000100
#define FF_DEBUG_PTS 0x00000200
#define FF_DEBUG_ER 0x00000400
#define FF_DEBUG_MMCO 0x00000800
/**
* error.
......@@ -1149,6 +1156,7 @@ extern AVCodec msmpeg4v3_encoder;
extern AVCodec wmv1_encoder;
extern AVCodec wmv2_encoder;
extern AVCodec huffyuv_encoder;
extern AVCodec h264_encoder;
extern AVCodec h263_decoder;
extern AVCodec mpeg4_decoder;
......@@ -1174,6 +1182,7 @@ extern AVCodec mace6_decoder;
extern AVCodec huffyuv_decoder;
extern AVCodec oggvorbis_decoder;
extern AVCodec cyuv_decoder;
extern AVCodec h264_decoder;
/* pcm codecs */
#define PCM_CODEC(id, name) \
......
此差异已折叠。
......@@ -76,6 +76,7 @@ void clear_blocks_c(DCTELEM *blocks);
// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
#define DEF_OLD_QPEL(name)\
void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\
......@@ -107,6 +108,7 @@ typedef int (*op_pixels_abs_func)(uint8_t *blk1/*align width (8 or 16)*/, uint8_
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size)/* __attribute__ ((const))*/;
/**
* DSPContext.
*/
......@@ -187,7 +189,16 @@ typedef struct DSPContext {
qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16];
qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16];
qpel_mc_func put_mspel_pixels_tab[8];
/**
* h264 Chram MC
*/
h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
qpel_mc_func put_h264_qpel_pixels_tab[3][16];
qpel_mc_func avg_h264_qpel_pixels_tab[3][16];
op_pixels_abs_func pix_abs16x16;
op_pixels_abs_func pix_abs16x16_x2;
op_pixels_abs_func pix_abs16x16_y2;
......
/*
* exp golomb vlc stuff
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/**
* @file golomb.c
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include <inttypes.h>
const uint8_t ff_golomb_vlc_len[512]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
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,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
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,
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
};
const uint8_t ff_ue_golomb_vlc_code[512]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 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,
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,
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,
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, 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, 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, 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,
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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const int8_t ff_se_golomb_vlc_code[512]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15,
4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7,
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,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
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,
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, 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, 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, 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,
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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t ff_ue_golomb_len[256]={
1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,
};
/*
* exp golomb vlc stuff
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/**
* @file golomb.h
* @brief
* exp golomb vlc stuff
* @author Michael Niedermayer <michaelni@gmx.at>
*/
extern const uint8_t ff_golomb_vlc_len[512];
extern const uint8_t ff_ue_golomb_vlc_code[512];
extern const int8_t ff_se_golomb_vlc_code[512];
extern const uint8_t ff_ue_golomb_len[256];
/**
* read unsigned exp golomb code.
*/
static inline int get_ue_golomb(GetBitContext *gb){
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf=GET_CACHE(re, gb);
if(buf >= (1<<27)){
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_ue_golomb_vlc_code[buf];
}else{
log= 2*av_log2(buf) - 31;
buf>>= log;
buf--;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
return buf;
}
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te0_golomb(GetBitContext *gb, int range){
assert(range >= 1);
if(range==1) return 0;
else if(range==2) return get_bits1(gb);
else return get_ue_golomb(gb);
}
/**
* read unsigned truncated exp golomb code.
*/
static inline int get_te_golomb(GetBitContext *gb, int range){
assert(range >= 1);
if(range==2) return get_bits1(gb);
else return get_ue_golomb(gb);
}
/**
* read signed exp golomb code.
*/
static inline int get_se_golomb(GetBitContext *gb){
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf=GET_CACHE(re, gb);
if(buf >= (1<<27)){
buf >>= 32 - 9;
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
CLOSE_READER(re, gb);
return ff_se_golomb_vlc_code[buf];
}else{
log= 2*av_log2(buf) - 31;
buf>>= log;
LAST_SKIP_BITS(re, gb, 32 - log);
CLOSE_READER(re, gb);
if(buf&1) buf= -(buf>>1);
else buf= (buf>>1);
return buf;
}
}
#ifdef TRACE
static inline int get_ue(GetBitContext *s, char *file, char *func, int line){
int show= show_bits(s, 24);
int pos= get_bits_count(s);
int i= get_ue_golomb(s);
int len= get_bits_count(s) - pos;
int bits= show>>(24-len);
print_bin(bits, len);
printf("%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
return i;
}
static inline int get_se(GetBitContext *s, char *file, char *func, int line){
int show= show_bits(s, 24);
int pos= get_bits_count(s);
int i= get_se_golomb(s);
int len= get_bits_count(s) - pos;
int bits= show>>(24-len);
print_bin(bits, len);
printf("%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
return i;
}
static inline int get_te(GetBitContext *s, int r, char *file, char *func, int line){
int show= show_bits(s, 24);
int pos= get_bits_count(s);
int i= get_te0_golomb(s, r);
int len= get_bits_count(s) - pos;
int bits= show>>(24-len);
print_bin(bits, len);
printf("%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
return i;
}
#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#endif
/**
* write unsigned exp golomb code.
*/
static inline void set_ue_golomb(PutBitContext *pb, int i){
int e;
assert(i>=0);
#if 0
if(i=0){
put_bits(pb, 1, 1);
return;
}
#endif
if(i<256)
put_bits(pb, ff_ue_golomb_len[i], i+1);
else{
e= av_log2(i+1);
put_bits(pb, 2*e+1, i+1);
}
}
/**
* write truncated unsigned exp golomb code.
*/
static inline void set_te_golomb(PutBitContext *pb, int i, int range){
assert(range >= 1);
assert(i<=range);
if(range==2) put_bits(pb, 1, i);
else set_ue_golomb(pb, i);
}
/**
* write signed exp golomb code.
*/
static inline void set_se_golomb(PutBitContext *pb, int i){
#if 0
if(i<=0) i= -2*i;
else i= 2*i-1;
#elif 1
i= 2*i-1;
if(i<0) i^= -1; //FIXME check if gcc does the right thing
#else
i= 2*i-1;
i^= (i>>31);
#endif
set_ue_golomb(pb, i);
}
此差异已折叠。
此差异已折叠。
......@@ -227,7 +227,9 @@ int DCT_common_init(MpegEncContext *s)
* The pixels are allocated/set by calling get_buffer() if shared=0
*/
static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
const int big_mb_num= (s->mb_width+1)*(s->mb_height+1);
int i;
if(shared){
assert(pic->data[0]);
assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED);
......@@ -268,9 +270,17 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
CHECKED_ALLOCZ(pic->mbskip_table , s->mb_num * sizeof(uint8_t)+1) //the +1 is for the slice end check
CHECKED_ALLOCZ(pic->qscale_table , s->mb_num * sizeof(uint8_t))
if(s->out_format == FMT_H264){
CHECKED_ALLOCZ(pic->mb_type_base , big_mb_num * sizeof(uint16_t))
pic->mb_type= pic->mb_type_base + s->mb_width+2;
for(i=0; i<2; i++){
CHECKED_ALLOCZ(pic->motion_val[i], 2 * 16 * s->mb_num * sizeof(uint16_t))
CHECKED_ALLOCZ(pic->ref_index[i] , 4 * s->mb_num * sizeof(uint8_t))
}
}
pic->qstride= s->mb_width;
}
//it might be nicer if the application would keep track of these but it would require a API change
memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);
s->prev_pict_types[0]= s->pict_type;
......@@ -298,7 +308,13 @@ static void free_picture(MpegEncContext *s, Picture *pic){
av_freep(&pic->mb_cmp_score);
av_freep(&pic->mbskip_table);
av_freep(&pic->qscale_table);
av_freep(&pic->mb_type_base);
pic->mb_type= NULL;
for(i=0; i<2; i++){
av_freep(&pic->motion_val[i]);
av_freep(&pic->ref_index[i]);
}
if(pic->type == FF_BUFFER_TYPE_INTERNAL){
for(i=0; i<4; i++){
av_freep(&pic->base[i]);
......@@ -855,7 +871,7 @@ static int find_unused_picture(MpegEncContext *s, int shared){
}
}else{
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0]==NULL && s->picture[i].type!=0) break;
if(s->picture[i].data[0]==NULL && s->picture[i].type!=0) break; //FIXME
}
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0]==NULL) break;
......@@ -873,7 +889,9 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
AVFrame *pic;
s->mb_skiped = 0;
assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264);
/* mark&release old frames */
if (s->pict_type != B_TYPE && s->last_picture_ptr) {
avctx->release_buffer(avctx, (AVFrame*)s->last_picture_ptr);
......@@ -895,7 +913,7 @@ alloc:
i= find_unused_picture(s, 0);
pic= (AVFrame*)&s->picture[i];
pic->reference= s->pict_type != B_TYPE;
pic->reference= s->pict_type != B_TYPE ? 3 : 0;
if(s->current_picture_ptr)
pic->coded_picture_number= s->current_picture_ptr->coded_picture_number+1;
......@@ -905,11 +923,12 @@ alloc:
s->current_picture_ptr= &s->picture[i];
}
s->current_picture= *s->current_picture_ptr;
if(s->out_format != FMT_H264){
if (s->pict_type != B_TYPE) {
s->last_picture_ptr= s->next_picture_ptr;
s->next_picture_ptr= s->current_picture_ptr;
}
s->current_picture= *s->current_picture_ptr;
if(s->last_picture_ptr) s->last_picture= *s->last_picture_ptr;
if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr;
if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr;
......@@ -931,6 +950,7 @@ alloc:
assert(s->pict_type != B_TYPE); //these should have been dropped if we dont have a reference
goto alloc;
}
}
s->hurry_up= s->avctx->hurry_up;
s->error_resilience= avctx->error_resilience;
......@@ -1059,7 +1079,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
i= find_unused_picture(s, 1);
pic= (AVFrame*)&s->picture[i];
pic->reference= 1;
pic->reference= 3;
for(i=0; i<4; i++){
pic->data[i]= pic_arg->data[i];
......@@ -1070,7 +1090,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
i= find_unused_picture(s, 0);
pic= (AVFrame*)&s->picture[i];
pic->reference= 1;
pic->reference= 3;
alloc_picture(s, (Picture*)pic, 0);
for(i=0; i<4; i++){
......@@ -1215,7 +1235,7 @@ static void select_input_picture(MpegEncContext *s){
}
if(s->reordered_input_picture[0]){
s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE;
s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0;
s->new_picture= *s->reordered_input_picture[0];
......@@ -3944,6 +3964,8 @@ char ff_get_pict_type_char(int pict_type){
case P_TYPE: return 'P';
case B_TYPE: return 'B';
case S_TYPE: return 'S';
case SI_TYPE:return 'i';
case SP_TYPE:return 'p';
default: return '?';
}
}
......
......@@ -33,6 +33,7 @@ enum OutputFormat {
FMT_MPEG1,
FMT_H263,
FMT_MJPEG,
FMT_H264,
};
#define EDGE_WIDTH 16
......@@ -59,6 +60,8 @@ enum OutputFormat {
#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
typedef struct Predictor{
double coeff;
......@@ -127,6 +130,57 @@ typedef struct ScanTable{
typedef struct Picture{
FF_COMMON_FRAME
/**
* halfpel luma planes.
*/
uint8_t *interpolated[3];
int16_t (*motion_val[2])[2];
int8_t *ref_index[2];
uint16_t *mb_type_base;
uint16_t *mb_type; ///< mb_type_base + mb_width + 2
#define MB_TYPE_INTRA4x4 0x0001
#define MB_TYPE_INTRA16x16 0x0002
#define MB_TYPE_INTRA_PCM 0x0004
#define MB_TYPE_16x16 0x0008
#define MB_TYPE_16x8 0x0010
#define MB_TYPE_8x16 0x0020
#define MB_TYPE_8x8 0x0040
#define MB_TYPE_INTERLACED 0x0080
#define MB_TYPE_DIRECT2 0x0100 //FIXME
#define MB_TYPE_REF0 0x0200
#define MB_TYPE_GMC2 0x0400 //FIXME
#define MB_TYPE_P0L0 0x1000
#define MB_TYPE_P1L0 0x2000
#define MB_TYPE_P0L1 0x4000
#define MB_TYPE_P1L1 0x8000
#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
#define IS_INTRA(a) ((a)&3)
#define IS_INTER(a) ((a)&(MB_TYPE_16x16|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8))
#define IS_INTRA_PCM(a) ((a)&MB_TYPE_INTRA_PCM)
#define IS_INTERLACED(a) ((a)&MB_TYPE_INTERLACED)
#define IS_DIRECT(a) ((a)&MB_TYPE_DIRECT2)
#define IS_16X16(a) ((a)&MB_TYPE_16x16)
#define IS_16X8(a) ((a)&MB_TYPE_16x8)
#define IS_8X16(a) ((a)&MB_TYPE_8x16)
#define IS_8X8(a) ((a)&MB_TYPE_8x8)
#define IS_SUB_8X8(a) ((a)&MB_TYPE_16x16) //note reused
#define IS_SUB_8X4(a) ((a)&MB_TYPE_16x8) //note reused
#define IS_SUB_4X8(a) ((a)&MB_TYPE_8x16) //note reused
#define IS_SUB_4X4(a) ((a)&MB_TYPE_8x8) //note reused
#define IS_REF0(a) ((a)&MB_TYPE_REF0)
#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
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 long_ref; ///< 1->long term reference 0->short term reference
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
......@@ -267,6 +321,7 @@ typedef struct MpegEncContext {
Picture *current_picture_ptr; ///< pointer to the current picture
int last_dc[3]; ///< last DC values for MPEG1
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
......@@ -295,6 +350,7 @@ typedef struct MpegEncContext {
/* 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)
DSPContext dsp; ///< pointers for accelerated dsp fucntions
int f_code; ///< forward MV resolution
......@@ -470,9 +526,9 @@ typedef struct MpegEncContext {
int enhancement_type;
int new_pred;
int reduced_res_vop;
int aspect_ratio_info;
int aspected_width;
int aspected_height;
int aspect_ratio_info; //FIXME remove
int aspected_width; //FIXME remove
int aspected_height; //FIXME remove
int sprite_warping_accuracy;
int low_latency_sprite;
int data_partitioning; ///< data partitioning flag from header
......@@ -546,6 +602,7 @@ typedef struct MpegEncContext {
int fake_picture_number; ///< picture number at the bitstream frame rate
int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific
int last_mv_dir; ///< last mv_dir, used for b frame encoding
int broken_link; ///< no_output_of_prior_pics_flag
/* MPEG2 specific - I wish I had not to support this mess. */
int progressive_sequence;
......
......@@ -280,6 +280,31 @@ AVOutputFormat m4v_oformat = {
raw_write_trailer,
};
AVInputFormat h264_iformat = {
"h264",
"raw H264 video format",
0,
NULL /*mpegvideo_probe*/,
video_read_header,
raw_read_packet,
raw_read_close,
.extensions = "h26l,h264", //FIXME remove after writing mpeg4_probe
.value = CODEC_ID_H264,
};
AVOutputFormat h264_oformat = {
"h264",
"raw H264 video format",
NULL,
"h264",
0,
CODEC_ID_NONE,
CODEC_ID_H264,
raw_write_header,
raw_write_packet,
raw_write_trailer,
};
AVInputFormat mpegvideo_iformat = {
"mpegvideo",
"MPEG video",
......@@ -494,6 +519,9 @@ int raw_init(void)
av_register_input_format(&m4v_iformat);
av_register_output_format(&m4v_oformat);
av_register_input_format(&h264_iformat);
av_register_output_format(&h264_oformat);
av_register_input_format(&mpegvideo_iformat);
av_register_output_format(&mpeg1video_oformat);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册