summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2007-05-10 22:26:44 +0000
committerAurelien Jacobs <aurel@gnuage.org>2007-05-10 22:26:44 +0000
commit26b4fe821c0a6610e0d5598552e0a0e6114d4046 (patch)
tree6a3b04021db62ff8dbfe43917e822adabae5ad6e /libavcodec
parenteca3810e31a15c62b24408f5b4ae53f2c043911a (diff)
split h264.c to move parser in its own file
Originally committed as revision 8985 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/Makefile2
-rw-r--r--libavcodec/cabac.h6
-rw-r--r--libavcodec/h264.c476
-rw-r--r--libavcodec/h264.h386
-rw-r--r--libavcodec/h264_parser.c149
-rw-r--r--libavcodec/h264_parser.h40
6 files changed, 585 insertions, 474 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 5b56daef26..7a79e07bd3 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -290,7 +290,7 @@ OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o
OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o
-OBJS-$(CONFIG_H264_PARSER) += h264.o
+OBJS-$(CONFIG_H264_PARSER) += h264_parser.o
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg.o
OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o
OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index 3ef7f438a2..7da66d2ef1 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -25,6 +25,10 @@
* Context Adaptive Binary Arithmetic Coder.
*/
+#ifndef CABAC_H
+#define CABAC_H
+
+#include "bitstream.h"
//#undef NDEBUG
#include <assert.h>
@@ -857,3 +861,5 @@ static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signe
}else
return i;
}
+
+#endif /* CABAC_H */
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 92e7d2f9dc..b73b336335 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -30,7 +30,9 @@
#include "dsputil.h"
#include "avcodec.h"
#include "mpegvideo.h"
+#include "h264.h"
#include "h264data.h"
+#include "h264_parser.h"
#include "golomb.h"
#include "cabac.h"
@@ -38,356 +40,6 @@
//#undef NDEBUG
#include <assert.h>
-#define interlaced_dct interlaced_dct_is_a_bad_name
-#define mb_intra mb_intra_isnt_initalized_see_mb_type
-
-#define LUMA_DC_BLOCK_INDEX 25
-#define CHROMA_DC_BLOCK_INDEX 26
-
-#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
-#define COEFF_TOKEN_VLC_BITS 8
-#define TOTAL_ZEROS_VLC_BITS 9
-#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
-#define RUN_VLC_BITS 3
-#define RUN7_VLC_BITS 6
-
-#define MAX_SPS_COUNT 32
-#define MAX_PPS_COUNT 256
-
-#define MAX_MMCO_COUNT 66
-
-/* Compiling in interlaced support reduces the speed
- * of progressive decoding by about 2%. */
-#define ALLOW_INTERLACE
-
-#ifdef ALLOW_INTERLACE
-#define MB_MBAFF h->mb_mbaff
-#define MB_FIELD h->mb_field_decoding_flag
-#define FRAME_MBAFF h->mb_aff_frame
-#else
-#define MB_MBAFF 0
-#define MB_FIELD 0
-#define FRAME_MBAFF 0
-#undef IS_INTERLACED
-#define IS_INTERLACED(mb_type) 0
-#endif
-
-/**
- * Sequence parameter set
- */
-typedef struct SPS{
-
- int profile_idc;
- int level_idc;
- int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag
- int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4
- int poc_type; ///< pic_order_cnt_type
- int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4
- int delta_pic_order_always_zero_flag;
- int offset_for_non_ref_pic;
- int offset_for_top_to_bottom_field;
- int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle
- int ref_frame_count; ///< num_ref_frames
- int gaps_in_frame_num_allowed_flag;
- int mb_width; ///< frame_width_in_mbs_minus1 + 1
- int mb_height; ///< frame_height_in_mbs_minus1 + 1
- int frame_mbs_only_flag;
- int mb_aff; ///<mb_adaptive_frame_field_flag
- int direct_8x8_inference_flag;
- int crop; ///< frame_cropping_flag
- int crop_left; ///< frame_cropping_rect_left_offset
- int crop_right; ///< frame_cropping_rect_right_offset
- int crop_top; ///< frame_cropping_rect_top_offset
- int crop_bottom; ///< frame_cropping_rect_bottom_offset
- int vui_parameters_present_flag;
- AVRational sar;
- int timing_info_present_flag;
- uint32_t num_units_in_tick;
- uint32_t time_scale;
- int fixed_frame_rate_flag;
- short offset_for_ref_frame[256]; //FIXME dyn aloc?
- int bitstream_restriction_flag;
- int num_reorder_frames;
- int scaling_matrix_present;
- uint8_t scaling_matrix4[6][16];
- uint8_t scaling_matrix8[2][64];
-}SPS;
-
-/**
- * Picture parameter set
- */
-typedef struct PPS{
- unsigned int sps_id;
- int cabac; ///< entropy_coding_mode_flag
- int pic_order_present; ///< pic_order_present_flag
- int slice_group_count; ///< num_slice_groups_minus1 + 1
- int mb_slice_group_map_type;
- unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1
- int weighted_pred; ///< weighted_pred_flag
- int weighted_bipred_idc;
- int init_qp; ///< pic_init_qp_minus26 + 26
- int init_qs; ///< pic_init_qs_minus26 + 26
- int chroma_qp_index_offset;
- int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag
- int constrained_intra_pred; ///< constrained_intra_pred_flag
- int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
- int transform_8x8_mode; ///< transform_8x8_mode_flag
- uint8_t scaling_matrix4[6][16];
- uint8_t scaling_matrix8[2][64];
-}PPS;
-
-/**
- * Memory management control operation opcode.
- */
-typedef enum MMCOOpcode{
- MMCO_END=0,
- MMCO_SHORT2UNUSED,
- MMCO_LONG2UNUSED,
- MMCO_SHORT2LONG,
- MMCO_SET_MAX_LONG,
- MMCO_RESET,
- MMCO_LONG,
-} MMCOOpcode;
-
-/**
- * Memory management control operation.
- */
-typedef struct MMCO{
- MMCOOpcode opcode;
- int short_frame_num;
- int long_index;
-} MMCO;
-
-/**
- * H264Context
- */
-typedef struct H264Context{
- MpegEncContext s;
- int nal_ref_idc;
- int nal_unit_type;
- uint8_t *rbsp_buffer;
- unsigned int rbsp_buffer_size;
-
- /**
- * Used to parse AVC variant of h264
- */
- int is_avc; ///< this flag is != 0 if codec is avc1
- int got_avcC; ///< flag used to parse avcC data only once
- int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
-
- int chroma_qp; //QPc
-
- int prev_mb_skipped;
- int next_mb_skipped;
-
- //prediction stuff
- int chroma_pred_mode;
- int intra16x16_pred_mode;
-
- int top_mb_xy;
- int left_mb_xy[2];
-
- int8_t intra4x4_pred_mode_cache[5*8];
- int8_t (*intra4x4_pred_mode)[8];
- void (*pred4x4 [9+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp?
- void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
- void (*pred8x8 [4+3])(uint8_t *src, int stride);
- void (*pred16x16[4+3])(uint8_t *src, int stride);
- unsigned int topleft_samples_available;
- unsigned int top_samples_available;
- unsigned int topright_samples_available;
- unsigned int left_samples_available;
- uint8_t (*top_borders[2])[16+2*8];
- uint8_t left_border[2*(17+2*9)];
-
- /**
- * non zero coeff count cache.
- * is 64 if not available.
- */
- DECLARE_ALIGNED_8(uint8_t, non_zero_count_cache[6*8]);
- uint8_t (*non_zero_count)[16];
-
- /**
- * Motion vector cache.
- */
- DECLARE_ALIGNED_8(int16_t, mv_cache[2][5*8][2]);
- DECLARE_ALIGNED_8(int8_t, ref_cache[2][5*8]);
-#define LIST_NOT_USED -1 //FIXME rename?
-#define PART_NOT_AVAILABLE -2
-
- /**
- * is 1 if the specific list MV&references are set to 0,0,-2.
- */
- int mv_cache_clean[2];
-
- /**
- * number of neighbors (top and/or left) that used 8x8 dct
- */
- int neighbor_transform_size;
-
- /**
- * block_offset[ 0..23] for frame macroblocks
- * block_offset[24..47] for field macroblocks
- */
- int block_offset[2*(16+8)];
-
- uint32_t *mb2b_xy; //FIXME are these 4 a good idea?
- uint32_t *mb2b8_xy;
- int b_stride; //FIXME use s->b4_stride
- int b8_stride;
-
- int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff
- int mb_uvlinesize;
-
- int emu_edge_width;
- int emu_edge_height;
-
- int halfpel_flag;
- int thirdpel_flag;
-
- int unknown_svq3_flag;
- int next_slice_index;
-
- SPS sps_buffer[MAX_SPS_COUNT];
- SPS sps; ///< current sps
-
- PPS pps_buffer[MAX_PPS_COUNT];
- /**
- * current pps
- */
- PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?
-
- uint32_t dequant4_buffer[6][52][16];
- uint32_t dequant8_buffer[2][52][64];
- uint32_t (*dequant4_coeff[6])[16];
- uint32_t (*dequant8_coeff[2])[64];
- int dequant_coeff_pps; ///< reinit tables when pps changes
-
- int slice_num;
- uint8_t *slice_table_base;
- uint8_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
- int slice_type;
- int slice_type_fixed;
-
- //interlacing specific flags
- int mb_aff_frame;
- int mb_field_decoding_flag;
- int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag
-
- unsigned int sub_mb_type[4];
-
- //POC stuff
- int poc_lsb;
- int poc_msb;
- int delta_poc_bottom;
- int delta_poc[2];
- int frame_num;
- int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
- int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
- int frame_num_offset; ///< for POC type 2
- int prev_frame_num_offset; ///< for POC type 2
- int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
-
- /**
- * frame_num for frames or 2*frame_num for field pics.
- */
- int curr_pic_num;
-
- /**
- * max_frame_num or 2*max_frame_num for field pics.
- */
- int max_pic_num;
-
- //Weighted pred stuff
- int use_weight;
- int use_weight_chroma;
- int luma_log2_weight_denom;
- int chroma_log2_weight_denom;
- int luma_weight[2][48];
- int luma_offset[2][48];
- int chroma_weight[2][48][2];
- int chroma_offset[2][48][2];
- int implicit_weight[48][48];
-
- //deblock
- int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0
- int slice_alpha_c0_offset;
- int slice_beta_offset;
-
- int redundant_pic_count;
-
- int direct_spatial_mv_pred;
- int dist_scale_factor[16];
- int dist_scale_factor_field[32];
- int map_col_to_list0[2][16];
- int map_col_to_list0_field[2][32];
-
- /**
- * num_ref_idx_l0/1_active_minus1 + 1
- */
- unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode
- unsigned int list_count;
- Picture *short_ref[32];
- Picture *long_ref[32];
- Picture default_ref_list[2][32];
- Picture ref_list[2][48]; ///< 0..15: frame refs, 16..47: mbaff field refs
- Picture *delayed_pic[18]; //FIXME size?
- Picture *delayed_output_pic;
-
- /**
- * memory management control operations buffer.
- */
- MMCO mmco[MAX_MMCO_COUNT];
- int mmco_index;
-
- int long_ref_count; ///< number of actual long term references
- int short_ref_count; ///< number of actual short term references
-
- //data partitioning
- GetBitContext intra_gb;
- GetBitContext inter_gb;
- GetBitContext *intra_gb_ptr;
- GetBitContext *inter_gb_ptr;
-
- DECLARE_ALIGNED_8(DCTELEM, mb[16*24]);
- DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not to large or ensure that there is some unused stuff after mb
-
- /**
- * Cabac
- */
- CABACContext cabac;
- uint8_t cabac_state[460];
- int cabac_init_idc;
-
- /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */
- uint16_t *cbp_table;
- int cbp;
- int top_cbp;
- int left_cbp;
- /* chroma_pred_mode for i4x4 or i16x16, else 0 */
- uint8_t *chroma_pred_mode_table;
- int last_qscale_diff;
- int16_t (*mvd_table[2])[2];
- DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]);
- uint8_t *direct_table;
- uint8_t direct_cache[5*8];
-
- uint8_t zigzag_scan[16];
- uint8_t zigzag_scan8x8[64];
- uint8_t zigzag_scan8x8_cavlc[64];
- uint8_t field_scan[16];
- uint8_t field_scan8x8[64];
- uint8_t field_scan8x8_cavlc[64];
- const uint8_t *zigzag_scan_q0;
- const uint8_t *zigzag_scan8x8_q0;
- const uint8_t *zigzag_scan8x8_cavlc_q0;
- const uint8_t *field_scan_q0;
- const uint8_t *field_scan8x8_q0;
- const uint8_t *field_scan8x8_cavlc_q0;
-
- int x264_build;
-}H264Context;
-
static VLC coeff_token_vlc[4];
static VLC chroma_dc_coeff_token_vlc;
@@ -7982,117 +7634,6 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
return 0;
}
-/**
- * finds the end of the current frame in the bitstream.
- * @return the position of the first byte of the next frame, or -1
- */
-static int find_frame_end(H264Context *h, const uint8_t *buf, int buf_size){
- int i;
- uint32_t state;
- ParseContext *pc = &(h->s.parse_context);
-//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
-// mb_addr= pc->mb_addr - 1;
- state= pc->state;
- if(state>13)
- state= 7;
-
- for(i=0; i<buf_size; i++){
- if(state==7){
- for(; i<buf_size; i++){
- if(!buf[i]){
- state=2;
- break;
- }
- }
- }else if(state<=2){
- if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5
- else if(buf[i]) state = 7;
- else state>>=1; //2->1, 1->0, 0->0
- }else if(state<=5){
- int v= buf[i] & 0x1F;
- if(v==7 || v==8 || v==9){
- if(pc->frame_start_found){
- i++;
-found:
- pc->state=7;
- pc->frame_start_found= 0;
- return i-(state&5);
- }
- }else if(v==1 || v==2 || v==5){
- if(pc->frame_start_found){
- state+=8;
- continue;
- }else
- pc->frame_start_found = 1;
- }
- state= 7;
- }else{
- if(buf[i] & 0x80)
- goto found;
- state= 7;
- }
- }
- pc->state= state;
- return END_NOT_FOUND;
-}
-
-#ifdef CONFIG_H264_PARSER
-static int h264_parse(AVCodecParserContext *s,
- AVCodecContext *avctx,
- const uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size)
-{
- H264Context *h = s->priv_data;
- ParseContext *pc = &h->s.parse_context;
- int next;
-
- if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
- next= buf_size;
- }else{
- next= find_frame_end(h, buf, buf_size);
-
- if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
- *poutbuf = NULL;
- *poutbuf_size = 0;
- return buf_size;
- }
-
- if(next<0 && next != END_NOT_FOUND){
- assert(pc->last_index + next >= 0 );
- find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
- }
- }
-
- *poutbuf = buf;
- *poutbuf_size = buf_size;
- return next;
-}
-
-static int h264_split(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- int i;
- uint32_t state = -1;
- int has_sps= 0;
-
- for(i=0; i<=buf_size; i++){
- if((state&0xFFFFFF1F) == 0x107)
- has_sps=1;
-/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
- }*/
- if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
- if(has_sps){
- while(i>4 && buf[i-5]==0) i--;
- return i-4;
- }
- }
- if (i<buf_size)
- state= (state<<8) | buf[i];
- }
- return 0;
-}
-#endif /* CONFIG_H264_PARSER */
-
static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx;
@@ -8301,7 +7842,7 @@ static int decode_frame(AVCodecContext *avctx,
}
if(s->flags&CODEC_FLAG_TRUNCATED){
- int next= find_frame_end(h, buf, buf_size);
+ int next= ff_h264_find_frame_end(h, buf, buf_size);
if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
return buf_size;
@@ -8692,15 +8233,4 @@ AVCodec h264_decoder = {
.flush= flush_dpb,
};
-#ifdef CONFIG_H264_PARSER
-AVCodecParser h264_parser = {
- { CODEC_ID_H264 },
- sizeof(H264Context),
- NULL,
- h264_parse,
- ff_parse_close,
- h264_split,
-};
-#endif
-
#include "svq3.c"
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
new file mode 100644
index 0000000000..95c3ab42a9
--- /dev/null
+++ b/libavcodec/h264.h
@@ -0,0 +1,386 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003 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 h264.h
+ * H.264 / AVC / MPEG4 part10 codec.
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef H264_H
+#define H264_H
+
+#include "dsputil.h"
+#include "cabac.h"
+#include "mpegvideo.h"
+
+#define interlaced_dct interlaced_dct_is_a_bad_name
+#define mb_intra mb_intra_isnt_initalized_see_mb_type
+
+#define LUMA_DC_BLOCK_INDEX 25
+#define CHROMA_DC_BLOCK_INDEX 26
+
+#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
+#define COEFF_TOKEN_VLC_BITS 8
+#define TOTAL_ZEROS_VLC_BITS 9
+#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
+#define RUN_VLC_BITS 3
+#define RUN7_VLC_BITS 6
+
+#define MAX_SPS_COUNT 32
+#define MAX_PPS_COUNT 256
+
+#define MAX_MMCO_COUNT 66
+
+/* Compiling in interlaced support reduces the speed
+ * of progressive decoding by about 2%. */
+#define ALLOW_INTERLACE
+
+#ifdef ALLOW_INTERLACE
+#define MB_MBAFF h->mb_mbaff
+#define MB_FIELD h->mb_field_decoding_flag
+#define FRAME_MBAFF h->mb_aff_frame
+#else
+#define MB_MBAFF 0
+#define MB_FIELD 0
+#define FRAME_MBAFF 0
+#undef IS_INTERLACED
+#define IS_INTERLACED(mb_type) 0
+#endif
+
+/**
+ * Sequence parameter set
+ */
+typedef struct SPS{
+
+ int profile_idc;
+ int level_idc;
+ int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag
+ int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4
+ int poc_type; ///< pic_order_cnt_type
+ int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4
+ int delta_pic_order_always_zero_flag;
+ int offset_for_non_ref_pic;
+ int offset_for_top_to_bottom_field;
+ int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle
+ int ref_frame_count; ///< num_ref_frames
+ int gaps_in_frame_num_allowed_flag;
+ int mb_width; ///< frame_width_in_mbs_minus1 + 1
+ int mb_height; ///< frame_height_in_mbs_minus1 + 1
+ int frame_mbs_only_flag;
+ int mb_aff; ///<mb_adaptive_frame_field_flag
+ int direct_8x8_inference_flag;
+ int crop; ///< frame_cropping_flag
+ int crop_left; ///< frame_cropping_rect_left_offset
+ int crop_right; ///< frame_cropping_rect_right_offset
+ int crop_top; ///< frame_cropping_rect_top_offset
+ int crop_bottom; ///< frame_cropping_rect_bottom_offset
+ int vui_parameters_present_flag;
+ AVRational sar;
+ int timing_info_present_flag;
+ uint32_t num_units_in_tick;
+ uint32_t time_scale;
+ int fixed_frame_rate_flag;
+ short offset_for_ref_frame[256]; //FIXME dyn aloc?
+ int bitstream_restriction_flag;
+ int num_reorder_frames;
+ int scaling_matrix_present;
+ uint8_t scaling_matrix4[6][16];
+ uint8_t scaling_matrix8[2][64];
+}SPS;
+
+/**
+ * Picture parameter set
+ */
+typedef struct PPS{
+ unsigned int sps_id;
+ int cabac; ///< entropy_coding_mode_flag
+ int pic_order_present; ///< pic_order_present_flag
+ int slice_group_count; ///< num_slice_groups_minus1 + 1
+ int mb_slice_group_map_type;
+ unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1
+ int weighted_pred; ///< weighted_pred_flag
+ int weighted_bipred_idc;
+ int init_qp; ///< pic_init_qp_minus26 + 26
+ int init_qs; ///< pic_init_qs_minus26 + 26
+ int chroma_qp_index_offset;
+ int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag
+ int constrained_intra_pred; ///< constrained_intra_pred_flag
+ int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
+ int transform_8x8_mode; ///< transform_8x8_mode_flag
+ uint8_t scaling_matrix4[6][16];
+ uint8_t scaling_matrix8[2][64];
+}PPS;
+
+/**
+ * Memory management control operation opcode.
+ */
+typedef enum MMCOOpcode{
+ MMCO_END=0,
+ MMCO_SHORT2UNUSED,
+ MMCO_LONG2UNUSED,
+ MMCO_SHORT2LONG,
+ MMCO_SET_MAX_LONG,
+ MMCO_RESET,
+ MMCO_LONG,
+} MMCOOpcode;
+
+/**
+ * Memory management control operation.
+ */
+typedef struct MMCO{
+ MMCOOpcode opcode;
+ int short_frame_num;
+ int long_index;
+} MMCO;
+
+/**
+ * H264Context
+ */
+typedef struct H264Context{
+ MpegEncContext s;
+ int nal_ref_idc;
+ int nal_unit_type;
+ uint8_t *rbsp_buffer;
+ unsigned int rbsp_buffer_size;
+
+ /**
+ * Used to parse AVC variant of h264
+ */
+ int is_avc; ///< this flag is != 0 if codec is avc1
+ int got_avcC; ///< flag used to parse avcC data only once
+ int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
+
+ int chroma_qp; //QPc
+
+ int prev_mb_skipped;
+ int next_mb_skipped;
+
+ //prediction stuff
+ int chroma_pred_mode;
+ int intra16x16_pred_mode;
+
+ int top_mb_xy;
+ int left_mb_xy[2];
+
+ int8_t intra4x4_pred_mode_cache[5*8];
+ int8_t (*intra4x4_pred_mode)[8];
+ void (*pred4x4 [9+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp?
+ void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
+ void (*pred8x8 [4+3])(uint8_t *src, int stride);
+ void (*pred16x16[4+3])(uint8_t *src, int stride);
+ unsigned int topleft_samples_available;
+ unsigned int top_samples_available;
+ unsigned int topright_samples_available;
+ unsigned int left_samples_available;
+ uint8_t (*top_borders[2])[16+2*8];
+ uint8_t left_border[2*(17+2*9)];
+
+ /**
+ * non zero coeff count cache.
+ * is 64 if not available.
+ */
+ DECLARE_ALIGNED_8(uint8_t, non_zero_count_cache[6*8]);
+ uint8_t (*non_zero_count)[16];
+
+ /**
+ * Motion vector cache.
+ */
+ DECLARE_ALIGNED_8(int16_t, mv_cache[2][5*8][2]);
+ DECLARE_ALIGNED_8(int8_t, ref_cache[2][5*8]);
+#define LIST_NOT_USED -1 //FIXME rename?
+#define PART_NOT_AVAILABLE -2
+
+ /**
+ * is 1 if the specific list MV&references are set to 0,0,-2.
+ */
+ int mv_cache_clean[2];
+
+ /**
+ * number of neighbors (top and/or left) that used 8x8 dct
+ */
+ int neighbor_transform_size;
+
+ /**
+ * block_offset[ 0..23] for frame macroblocks
+ * block_offset[24..47] for field macroblocks
+ */
+ int block_offset[2*(16+8)];
+
+ uint32_t *mb2b_xy; //FIXME are these 4 a good idea?
+ uint32_t *mb2b8_xy;
+ int b_stride; //FIXME use s->b4_stride
+ int b8_stride;
+
+ int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff
+ int mb_uvlinesize;
+
+ int emu_edge_width;
+ int emu_edge_height;
+
+ int halfpel_flag;
+ int thirdpel_flag;
+
+ int unknown_svq3_flag;
+ int next_slice_index;
+
+ SPS sps_buffer[MAX_SPS_COUNT];
+ SPS sps; ///< current sps
+
+ PPS pps_buffer[MAX_PPS_COUNT];
+ /**
+ * current pps
+ */
+ PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?
+
+ uint32_t dequant4_buffer[6][52][16];
+ uint32_t dequant8_buffer[2][52][64];
+ uint32_t (*dequant4_coeff[6])[16];
+ uint32_t (*dequant8_coeff[2])[64];
+ int dequant_coeff_pps; ///< reinit tables when pps changes
+
+ int slice_num;
+ uint8_t *slice_table_base;
+ uint8_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
+ int slice_type;
+ int slice_type_fixed;
+
+ //interlacing specific flags
+ int mb_aff_frame;
+ int mb_field_decoding_flag;
+ int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag
+
+ unsigned int sub_mb_type[4];
+
+ //POC stuff
+ int poc_lsb;
+ int poc_msb;
+ int delta_poc_bottom;
+ int delta_poc[2];
+ int frame_num;
+ int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
+ int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
+ int frame_num_offset; ///< for POC type 2
+ int prev_frame_num_offset; ///< for POC type 2
+ int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
+
+ /**
+ * frame_num for frames or 2*frame_num for field pics.
+ */
+ int curr_pic_num;
+
+ /**
+ * max_frame_num or 2*max_frame_num for field pics.
+ */
+ int max_pic_num;
+
+ //Weighted pred stuff
+ int use_weight;
+ int use_weight_chroma;
+ int luma_log2_weight_denom;
+ int chroma_log2_weight_denom;
+ int luma_weight[2][48];
+ int luma_offset[2][48];
+ int chroma_weight[2][48][2];
+ int chroma_offset[2][48][2];
+ int implicit_weight[48][48];
+
+ //deblock
+ int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0
+ int slice_alpha_c0_offset;
+ int slice_beta_offset;
+
+ int redundant_pic_count;
+
+ int direct_spatial_mv_pred;
+ int dist_scale_factor[16];
+ int dist_scale_factor_field[32];
+ int map_col_to_list0[2][16];
+ int map_col_to_list0_field[2][32];
+
+ /**
+ * num_ref_idx_l0/1_active_minus1 + 1
+ */
+ unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode
+ unsigned int list_count;
+ Picture *short_ref[32];
+ Picture *long_ref[32];
+ Picture default_ref_list[2][32];
+ Picture ref_list[2][48]; ///< 0..15: frame refs, 16..47: mbaff field refs
+ Picture *delayed_pic[18]; //FIXME size?
+ Picture *delayed_output_pic;
+
+ /**
+ * memory management control operations buffer.
+ */
+ MMCO mmco[MAX_MMCO_COUNT];
+ int mmco_index;
+
+ int long_ref_count; ///< number of actual long term references
+ int short_ref_count; ///< number of actual short term references
+
+ //data partitioning
+ GetBitContext intra_gb;
+ GetBitContext inter_gb;
+ GetBitContext *intra_gb_ptr;
+ GetBitContext *inter_gb_ptr;
+
+ DECLARE_ALIGNED_8(DCTELEM, mb[16*24]);
+ DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not to large or ensure that there is some unused stuff after mb
+
+ /**
+ * Cabac
+ */
+ CABACContext cabac;
+ uint8_t cabac_state[460];
+ int cabac_init_idc;
+
+ /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */
+ uint16_t *cbp_table;
+ int cbp;
+ int top_cbp;
+ int left_cbp;
+ /* chroma_pred_mode for i4x4 or i16x16, else 0 */
+ uint8_t *chroma_pred_mode_table;
+ int last_qscale_diff;
+ int16_t (*mvd_table[2])[2];
+ DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]);
+ uint8_t *direct_table;
+ uint8_t direct_cache[5*8];
+
+ uint8_t zigzag_scan[16];
+ uint8_t zigzag_scan8x8[64];
+ uint8_t zigzag_scan8x8_cavlc[64];
+ uint8_t field_scan[16];
+ uint8_t field_scan8x8[64];
+ uint8_t field_scan8x8_cavlc[64];
+ const uint8_t *zigzag_scan_q0;
+ const uint8_t *zigzag_scan8x8_q0;
+ const uint8_t *zigzag_scan8x8_cavlc_q0;
+ const uint8_t *field_scan_q0;
+ const uint8_t *field_scan8x8_q0;
+ const uint8_t *field_scan8x8_cavlc_q0;
+
+ int x264_build;
+}H264Context;
+
+#endif /* H264_H */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
new file mode 100644
index 0000000000..4adb6cbe22
--- /dev/null
+++ b/libavcodec/h264_parser.c
@@ -0,0 +1,149 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... parser
+ * Copyright (c) 2003 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 h264_parser.c
+ * H.264 / AVC / MPEG4 part10 parser.
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "parser.h"
+#include "h264_parser.h"
+
+#include <assert.h>
+
+
+int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
+{
+ int i;
+ uint32_t state;
+ ParseContext *pc = &(h->s.parse_context);
+//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
+// mb_addr= pc->mb_addr - 1;
+ state= pc->state;
+ if(state>13)
+ state= 7;
+
+ for(i=0; i<buf_size; i++){
+ if(state==7){
+ for(; i<buf_size; i++){
+ if(!buf[i]){
+ state=2;
+ break;
+ }
+ }
+ }else if(state<=2){
+ if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5
+ else if(buf[i]) state = 7;
+ else state>>=1; //2->1, 1->0, 0->0
+ }else if(state<=5){
+ int v= buf[i] & 0x1F;
+ if(v==7 || v==8 || v==9){
+ if(pc->frame_start_found){
+ i++;
+found:
+ pc->state=7;
+ pc->frame_start_found= 0;
+ return i-(state&5);
+ }
+ }else if(v==1 || v==2 || v==5){
+ if(pc->frame_start_found){
+ state+=8;
+ continue;
+ }else
+ pc->frame_start_found = 1;
+ }
+ state= 7;
+ }else{
+ if(buf[i] & 0x80)
+ goto found;
+ state= 7;
+ }
+ }
+ pc->state= state;
+ return END_NOT_FOUND;
+}
+
+static int h264_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+ H264Context *h = s->priv_data;
+ ParseContext *pc = &h->s.parse_context;
+ int next;
+
+ if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
+ next= buf_size;
+ }else{
+ next= ff_h264_find_frame_end(h, buf, buf_size);
+
+ if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+ *poutbuf = NULL;
+ *poutbuf_size = 0;
+ return buf_size;
+ }
+
+ if(next<0 && next != END_NOT_FOUND){
+ assert(pc->last_index + next >= 0 );
+ ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
+ }
+ }
+
+ *poutbuf = buf;
+ *poutbuf_size = buf_size;
+ return next;
+}
+
+static int h264_split(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ int i;
+ uint32_t state = -1;
+ int has_sps= 0;
+
+ for(i=0; i<=buf_size; i++){
+ if((state&0xFFFFFF1F) == 0x107)
+ has_sps=1;
+/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
+ }*/
+ if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
+ if(has_sps){
+ while(i>4 && buf[i-5]==0) i--;
+ return i-4;
+ }
+ }
+ if (i<buf_size)
+ state= (state<<8) | buf[i];
+ }
+ return 0;
+}
+
+
+AVCodecParser h264_parser = {
+ { CODEC_ID_H264 },
+ sizeof(H264Context),
+ NULL,
+ h264_parse,
+ ff_parse_close,
+ h264_split,
+};
diff --git a/libavcodec/h264_parser.h b/libavcodec/h264_parser.h
new file mode 100644
index 0000000000..1d7407e4f5
--- /dev/null
+++ b/libavcodec/h264_parser.h
@@ -0,0 +1,40 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... parser
+ * Copyright (c) 2003 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 h264_parser.h
+ * H.264 / AVC / MPEG4 part10 parser.
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef H264_PARSER_H
+#define H264_PARSER_H
+
+#include "h264.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_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size);
+
+#endif /* H264_PARSER_H */