diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/h264dec/dec_api.c | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/h264dec/dec_api.c')
-rw-r--r-- | Src/h264dec/dec_api.c | 393 |
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 |