void do_NAL (struct lib_cc_decode *ctx, unsigned char *NALstart, LLONG NAL_length, struct cc_subtitle *sub) { unsigned char *NALstop; enum ccx_avc_nal_types nal_unit_type = *NALstart & 0x1F; NALstop = NAL_length+NALstart; NALstop = remove_03emu(NALstart+1, NALstop); // Add +1 to NALstop for TS, without it for MP4. Still don't know why dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n", nal_unit_type, NALstop-NALstart-1, ctx->avc_ctx->nal_ref_idc, !ctx->avc_ctx->cc_buffer_saved); if (NALstop==NULL) // remove_03emu failed. { mprint ("\rNotice: NAL of type %u had to be skipped because remove_03emu failed.\n", nal_unit_type); return; } if ( nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9 ) { // Found Access Unit Delimiter } else if ( nal_unit_type == CCX_NAL_TYPE_SEQUENCE_PARAMETER_SET_7 ) { // Found sequence parameter set // We need this to parse NAL type 1 (CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1) ctx->avc_ctx->num_nal_unit_type_7++; seq_parameter_set_rbsp(ctx->avc_ctx, NALstart+1, NALstop); ctx->avc_ctx->got_seq_para = 1; } else if ( ctx->avc_ctx->got_seq_para && (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1 || nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE)) // Only if nal_unit_type=1 { // Found coded slice of a non-IDR picture // We only need the slice header data, no need to implement // slice_layer_without_partitioning_rbsp( ); slice_header(ctx, NALstart+1, NALstop, nal_unit_type, sub); } else if ( ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI ) { // Found SEI (used for subtitles) //set_fts(ctx->timing); // FIXME - check this!!! sei_rbsp(ctx->avc_ctx, NALstart+1, NALstop); } else if ( ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET ) { // Found Picture parameter set } if (temp_debug) { mprint ("NAL process failed.\n"); mprint ("\n After decoding, the actual thing was (length =%d)\n", NALstop-(NALstart+1)); dump (CCX_DMT_GENERIC_NOTICES,NALstart+1, NALstop-(NALstart+1),0, 0); } dvprint("END NAL unit type: %d length %d ref_idc: %d - Buffered captions after: %d\n", nal_unit_type, NALstop-NALstart-1, ctx->avc_ctx->nal_ref_idc, !ctx->avc_ctx->cc_buffer_saved); }
static void p_picture(APEG_LAYER *layer) { const int MBAmax = layer->mb_cols*layer->mb_rows; int macroblock_type; int coded_block_pattern; int MBA, MBAinc; int dc_dct_pred[3]; int PMV[2]; int bx, by; unsigned int code; slice_start: dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; PMV[0] = PMV[1] = 0; code = apeg_start_code(layer); if(code < SLICE_START_CODE_MIN || code > SLICE_START_CODE_MAX) return; apeg_flush_bits32(layer); slice_header(layer); bx = get_mba_inc(layer); by = (code&255) - 1; MBA = by*layer->mb_cols + bx; bx <<= 4; by <<= 4; block_start: code = show_bits(layer, 6); if(code >= 8) { code >>= 3; apeg_flush_bits8(layer, PMBtab0[code].len); macroblock_type = PMBtab0[code].val; dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; switch(macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN)) { case MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN: apeg_motion_vector(layer,PMV,forward_code,full_forward_vector); apeg_form_f_pred(layer, bx, by, PMV); break; case MACROBLOCK_PATTERN: PMV[0] = PMV[1] = 0; apeg_empty_pred(layer->forward_frame, layer->current_frame, bx, by, layer->coded_width); break; default: apeg_motion_vector(layer,PMV,forward_code,full_forward_vector); apeg_form_f_pred(layer, bx, by, PMV); goto next; } }
/* decode all macroblocks of the current picture */ static void i_picture(APEG_LAYER *layer) { const int MBAmax = layer->mb_cols*layer->mb_rows; int MBA, MBAinc; int dc_dct_pred[3]; int bx, by; unsigned int code; slice_start: dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; code = apeg_start_code(layer); if(code < SLICE_START_CODE_MIN || code > SLICE_START_CODE_MAX) return; apeg_flush_bits32(layer); slice_header(layer); bx = get_mba_inc(layer); by = (code&255) - 1; MBA = by*layer->mb_cols + bx; bx <<= 4; by <<= 4; block_start: switch(show_bits(layer, 2)) { case 0: goto slice_start; case 1: layer->quantizer_scale = apeg_get_bits(layer, 7) & MASK_BITS(5); break; default: apeg_flush_bits1(layer); } apeg_decode_intra_blocks(layer, dc_dct_pred); apeg_fast_idct(apeg_block[0]); apeg_fast_idct(apeg_block[1]); apeg_fast_idct(apeg_block[2]); apeg_fast_idct(apeg_block[3]); apeg_fast_idct(apeg_block[4]); apeg_fast_idct(apeg_block[5]); Move_Blocks(layer, bx, by); if(++MBA >= MBAmax) return; if(show_bits(layer, 24) == 1) goto slice_start; MBAinc = get_mba_inc(layer); if(MBAinc == 0) { if((bx += 16) == layer->coded_width) { bx = 0; by += 16; } goto block_start; } dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0; MBA += MBAinc; if(MBA >= MBAmax) return; bx = (MBA%layer->mb_cols) << 4; by = (MBA/layer->mb_cols) << 4; goto block_start; }