aboutsummaryrefslogtreecommitdiff
path: root/Src/h264dec/dec_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/h264dec/dec_api.c')
-rw-r--r--Src/h264dec/dec_api.c393
1 files changed, 393 insertions, 0 deletions
diff --git a/Src/h264dec/dec_api.c b/Src/h264dec/dec_api.c
new file mode 100644
index 00000000..aaaeb46a
--- /dev/null
+++ b/Src/h264dec/dec_api.c
@@ -0,0 +1,393 @@
+#include "dec_api.h"
+#include "global.h"
+#include "nalu.h"
+#include "image.h"
+#include "meminput.h"
+#include "output.h"
+#include "fmo.h"
+#include "erc_api.h"
+#include "parset.h"
+#include "memcache.h"
+#include "block.h"
+#include "optim.h"
+#include "mc_prediction.h"
+#include "vlc.h"
+#include <stddef.h> // for offsetof
+
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+OptimizedFunctions opt;
+
+DecoderParams *alloc_decoder();
+void Configure(VideoParameters *p_Vid, InputParameters *p_Inp);
+void malloc_slice(InputParameters *p_Inp, VideoParameters *p_Vid);
+void init (VideoParameters *p_Vid);
+void free_slice (Slice *currSlice);
+void free_img( VideoParameters *p_Vid);
+
+int sse2_flag = 0, mmx_flag=0, sse_flag=0, sse3_flag=0, sse4_1_flag=0;
+int H264_Init()
+{
+ int flags_edx, flags_ecx;
+ #ifdef H264_IPP
+ ippStaticInit();
+ #endif
+
+#ifdef _M_IX86
+ _asm {
+ mov eax, 1
+ cpuid
+ mov flags_edx, edx
+ mov flags_ecx, ecx
+ }
+ mmx_flag = flags_edx & 0x00800000;
+ sse_flag = flags_edx & 0x02000000;
+ sse2_flag = flags_edx & 0x04000000;
+ sse3_flag = flags_ecx & 0x00000001;
+ sse4_1_flag= flags_ecx & (1 << 19);
+
+#elif defined(_M_X64)
+ sse2_flag = 1;
+#endif
+
+#ifdef _M_IX86
+ /* if you get any compile errors here, you need to change biari.asm */
+ BUILD_BUG_ON(offsetof(TextureInfoContexts, map_contexts) != 436);
+ BUILD_BUG_ON(offsetof(TextureInfoContexts, last_contexts) != 3252);
+ BUILD_BUG_ON(offsetof(TextureInfoContexts, one_contexts) != 6068);
+ BUILD_BUG_ON(offsetof(TextureInfoContexts, abs_contexts) != 6508);
+
+ BUILD_BUG_ON(offsetof(Macroblock, p_Slice) != 0);
+ BUILD_BUG_ON(offsetof(Macroblock, p_Vid) != 4);
+ BUILD_BUG_ON(offsetof(Macroblock, qp) != 60);
+ BUILD_BUG_ON(offsetof(Macroblock, qpc) != 64);
+ BUILD_BUG_ON(offsetof(Macroblock, qp_scaled) != 72);
+ BUILD_BUG_ON(offsetof(Macroblock, cbp_blk) != 248);
+ BUILD_BUG_ON(offsetof(Macroblock, mb_field) != 344);
+ BUILD_BUG_ON(offsetof(Macroblock, read_and_store_CBP_block_bit) != 400);
+
+ BUILD_BUG_ON(offsetof(Slice, tex_ctx) != 100);
+ BUILD_BUG_ON(offsetof(Slice, mb_rec) != 1696);
+ BUILD_BUG_ON(offsetof(Slice, mb_pred) != 928);
+ BUILD_BUG_ON(offsetof(Slice, coeff) != 15632);
+ BUILD_BUG_ON(offsetof(Slice, coeff_ctr) != 15760);
+ BUILD_BUG_ON(offsetof(Slice, pos) != 15764);
+ BUILD_BUG_ON(offsetof(Slice, cof) != 2464);
+ BUILD_BUG_ON(offsetof(Slice, last_dquant) != 88);
+ BUILD_BUG_ON(offsetof(Slice, mot_ctx) != 96);
+ BUILD_BUG_ON(offsetof(Slice, slice_type) != 64);
+
+
+ BUILD_BUG_ON(offsetof(StorablePicture, structure) != 0);
+ BUILD_BUG_ON(offsetof(StorablePicture, chroma_qp_offset) != 158688);
+ BUILD_BUG_ON(offsetof(StorablePicture, motion) != 158524);
+ BUILD_BUG_ON(offsetof(StorablePicture, plane_images) != 158512);
+ BUILD_BUG_ON(offsetof(StorablePicture, imgY) != 158512);
+
+
+ BUILD_BUG_ON(offsetof(VideoParameters, structure) != 697200);
+ BUILD_BUG_ON(offsetof(VideoParameters, bitdepth_chroma_qp_scale) != 697456);
+ BUILD_BUG_ON(offsetof(VideoParameters, dec_picture) != 698192);
+
+ BUILD_BUG_ON(offsetof(DecodingEnvironment, Dcodestrm_len) != 16);
+ BUILD_BUG_ON(offsetof(DecodingEnvironment, Dcodestrm) != 12);
+ BUILD_BUG_ON(offsetof(DecodingEnvironment, DbitsLeft) != 8);
+ BUILD_BUG_ON(offsetof(DecodingEnvironment, Dvalue) != 4);
+ BUILD_BUG_ON(offsetof(DecodingEnvironment, Drange) != 0);
+
+ BUILD_BUG_ON(sizeof(BiContextType) != 4);
+ BUILD_BUG_ON(offsetof(BiContextType, state) != 0);
+ BUILD_BUG_ON(offsetof(BiContextType, MPS) != 2);
+
+ BUILD_BUG_ON(offsetof(OptimizedFunctions, copy_image_data_16x16_stride) != 32);
+#endif
+
+ if (sse2_flag)
+ {
+ //opt.itrans4x4 = itrans4x4_mmx;
+ opt.itrans8x8 = itrans8x8_sse2;
+ opt.weighted_mc_prediction16x16 = weighted_mc_prediction16x16_sse2;
+ opt.weighted_mc_prediction16x8 = weighted_mc_prediction16x8_sse2;
+ opt.weighted_mc_prediction8x8 = weighted_mc_prediction8x8_sse2;
+
+ opt.weighted_bi_prediction16x16 = weighted_bi_prediction16x16_sse2;
+ opt.weighted_bi_prediction16x8 = weighted_bi_prediction16x8_sse2;
+ opt.weighted_bi_prediction8x8 = weighted_bi_prediction8x8_sse2;
+
+ opt.bi_prediction8x8 = bi_prediction8x8_sse2;
+ opt.copy_image_data_16x16_stride = copy_image_data_16x16_stride_sse;
+ opt.code_from_bitstream_2d_5_4 = code_from_bitstream_2d_5_4_sse2;
+ opt.code_from_bitstream_2d_17_4 = code_from_bitstream_2d_17_4_sse2;
+ opt.code_from_bitstream_2d_16_1 = code_from_bitstream_2d_16_1_sse2;
+ }
+ else if (sse_flag && mmx_flag)
+ {
+ //opt.itrans4x4 = itrans4x4_mmx;
+ opt.itrans8x8 = itrans8x8_c;//itrans8x8_mmx;
+
+ opt.weighted_mc_prediction16x16 = weighted_mc_prediction16x16_ipp;
+ opt.weighted_mc_prediction16x8 = weighted_mc_prediction16x8_ipp;
+ opt.weighted_mc_prediction8x8 = weighted_mc_prediction8x8_ipp;
+
+ opt.weighted_bi_prediction16x16 = weighted_bi_prediction16x16_ipp;
+ opt.weighted_bi_prediction16x8 = weighted_bi_prediction16x8_ipp;
+ opt.weighted_bi_prediction8x8 = weighted_bi_prediction8x8_ipp;
+
+ opt.bi_prediction8x8 = bi_prediction8x8_ipp;
+ opt.copy_image_data_16x16_stride = copy_image_data_16x16_stride_sse;
+ opt.code_from_bitstream_2d_5_4 = code_from_bitstream_2d_5_4_c;
+ opt.code_from_bitstream_2d_17_4 = code_from_bitstream_2d_17_4_c;
+ opt.code_from_bitstream_2d_16_1 = code_from_bitstream_2d_16_1_c;
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
+h264_decoder_t H264_CreateDecoder()
+{
+ DecoderParams *decoder=alloc_decoder();
+
+ if (decoder)
+ {
+ InputParameters *p_Inp = decoder->p_Inp;
+ Configure(decoder->p_Vid, p_Inp);
+ p_Inp->intra_profile_deblocking = 1;
+
+ initBitsFile(decoder->p_Vid);
+
+ malloc_slice(decoder->p_Inp, decoder->p_Vid);
+ init_old_slice(decoder->p_Vid->old_slice);
+
+ init(decoder->p_Vid);
+
+ init_out_buffer(decoder->p_Vid);
+
+ decoder->p_Vid->current_mb_nr = -4711; // initialized to an impossible value for debugging -- correct value is taken from slice header
+
+ }
+ return decoder;
+}
+
+void H264_DestroyDecoder(h264_decoder_t d)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder)
+ {
+ free_slice(decoder->p_Vid->currentSlice);
+ FmoFinit(decoder->p_Vid);
+
+ free_global_buffers(decoder->p_Vid);
+ flush_dpb(decoder->p_Vid);
+
+#if (PAIR_FIELDS_IN_OUTPUT)
+ flush_pending_output(decoder->p_Vid);
+#endif
+
+ out_storable_pictures_destroy(decoder->p_Vid);
+
+ ercClose(decoder->p_Vid, decoder->p_Vid->erc_errorVar);
+
+ CleanUpPPS(decoder->p_Vid);
+ free_dpb(decoder->p_Vid);
+ uninit_out_buffer(decoder->p_Vid);
+ image_cache_flush(&decoder->p_Vid->image_cache[0]);
+ image_cache_flush(&decoder->p_Vid->image_cache[1]);
+ motion_cache_flush(&decoder->p_Vid->motion_cache);
+ FreeNALU(decoder->p_Vid->nalu);
+ free (decoder->p_Inp);
+ free_img (decoder->p_Vid);
+ free(decoder);
+ }
+}
+
+void H264_DecodeFrame(h264_decoder_t d, const void *buffer, size_t bufferlen, uint64_t time_code)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ int ret;
+ memory_input_t *mem_input = decoder->p_Vid->mem_input;
+ mem_input->user_buffer=buffer;
+ mem_input->user_buffer_size=bufferlen;
+ mem_input->user_buffer_read=0;
+ __try
+ {
+ ret = decode_one_frame(decoder->p_Vid, time_code);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ int x;
+ x=0;
+ }
+#ifdef _M_IX86
+ _mm_empty();
+#endif
+}
+
+void H264_GetPicture(h264_decoder_t d, StorablePicture **pic)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (pic)
+ {
+ out_storable_picture_get(decoder->p_Vid, pic);
+ }
+}
+
+static double GetAspectRatio(const vui_seq_parameters_t *vui)
+{
+ int aspect_ratio_width=1, aspect_ratio_height=1;
+
+ if (vui->aspect_ratio_info_present_flag)
+ {
+ switch(vui->aspect_ratio_idc)
+ {
+ case VUI_AR_UNDEFINED:
+ case VUI_AR_SQUARE:
+ aspect_ratio_width = 1;
+ aspect_ratio_height = 1;
+ break;
+ case VUI_AR_12_11:
+ aspect_ratio_width = 12;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_10_11:
+ aspect_ratio_width = 10;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_16_11:
+ aspect_ratio_width = 16;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_40_33:
+ aspect_ratio_width = 40;
+ aspect_ratio_height = 33;
+ break;
+ case VUI_AR_24_11:
+ aspect_ratio_width = 24;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_20_11:
+ aspect_ratio_width = 20;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_32_11:
+ aspect_ratio_width = 32;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_80_33:
+ aspect_ratio_width = 80;
+ aspect_ratio_height = 33;
+ break;
+ case VUI_AR_18_11:
+ aspect_ratio_width = 18;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_15_11:
+ aspect_ratio_width = 15;
+ aspect_ratio_height = 11;
+ break;
+ case VUI_AR_64_33:
+ aspect_ratio_width = 64;
+ aspect_ratio_height = 33;
+ break;
+ case VUI_AR_160_99:
+ aspect_ratio_width = 160;
+ aspect_ratio_height = 99;
+ break;
+ case VUI_AR_4_3:
+ aspect_ratio_width = 4;
+ aspect_ratio_height = 3;
+ break;
+ case VUI_AR_3_2:
+ aspect_ratio_width = 3;
+ aspect_ratio_height = 2;
+ break;;
+ case VUI_AR_2_1:
+ aspect_ratio_width = 2;
+ aspect_ratio_height = 1;
+ break;;
+ case VUI_EXTENDED_SAR:
+ default:
+ aspect_ratio_width = vui->sar_width;
+ aspect_ratio_height = vui->sar_height;
+ break;
+ }
+ }
+ return (double)aspect_ratio_width / (double)aspect_ratio_height;
+}
+
+const FrameFormat *H264_GetOutputFormat(h264_decoder_t d, double *aspect_ratio)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder && decoder->p_Inp)
+ {
+ if (decoder->p_Vid->active_sps)
+ *aspect_ratio = GetAspectRatio(&decoder->p_Vid->active_sps->vui_seq_parameters);
+
+ return &decoder->p_Inp->output;
+ }
+ else
+ return 0;
+}
+
+void H264_Flush(h264_decoder_t d)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder && decoder->p_Vid)
+ {
+ StorablePicture *pic=0;
+ exit_picture(decoder->p_Vid, &decoder->p_Vid->dec_picture);
+ if (pic)
+ free_storable_picture(decoder->p_Vid, pic);
+ pic=0;
+
+ decoder->p_Vid->frame_num = 0;
+ decoder->p_Vid->pre_frame_num = INT_MIN;
+ decoder->p_Vid->PreviousFrameNum=0;
+ decoder->p_Vid->PreviousFrameNumOffset = 0;
+ decoder->p_Vid->PrevPicOrderCntLsb = 0;
+ decoder->p_Vid->PrevPicOrderCntMsb = 0;
+ flush_dpb(decoder->p_Vid);
+
+ do
+ {
+ pic=0;
+ out_storable_picture_get(decoder->p_Vid, &pic);
+ if (pic)
+ free_storable_picture(decoder->p_Vid, pic);
+ } while (pic);
+ decoder->p_Vid->mem_input->resetting = 1;
+ }
+}
+
+void H264_FreePicture(h264_decoder_t d, StorablePicture *p)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder && decoder->p_Vid && p)
+ {
+ free_storable_picture(decoder->p_Vid, p);
+ }
+}
+
+void H264_EndOfStream(h264_decoder_t d)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder && decoder->p_Vid)
+ {
+ if (decoder->p_Vid->dec_picture)
+ exit_picture(decoder->p_Vid, &decoder->p_Vid->dec_picture);
+ else
+ flush_dpb(decoder->p_Vid);
+ }
+}
+
+void H264_HurryUp(h264_decoder_t d, int state)
+{
+ DecoderParams *decoder = (DecoderParams *)d;
+ if (decoder && decoder->p_Vid)
+ {
+ memory_input_t *mem_input = decoder->p_Vid->mem_input;
+ if (mem_input)
+ mem_input->skip_b_frames = state;
+ }
+} \ No newline at end of file