FastLED 3.9.15
Loading...
Searching...
No Matches

◆ plm_video_decode_block()

void fl::third_party::plm_video_decode_block ( plm_video_t * self,
int block )

Definition at line 2726 of file pl_mpeg.hpp.

2726 {
2727
2728 int n = 0;
2729 uint8_t *quant_matrix;
2730
2731 // Decode DC coefficient of intra-coded blocks
2732 if (self->macroblock_intra) {
2733 int predictor;
2734 int dct_size;
2735
2736 // DC prediction
2737 int plane_index = block > 3 ? block - 3 : 0;
2738 predictor = self->dc_predictor[plane_index];
2739 dct_size = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_DCT_SIZE[plane_index]);
2740
2741 // Read DC coeff
2742 if (dct_size > 0) {
2743 int differential = plm_buffer_read(self->buffer, dct_size);
2744 if ((differential & (1 << (dct_size - 1))) != 0) {
2745 self->block_data[0] = predictor + differential;
2746 }
2747 else {
2748 self->block_data[0] = predictor + (-(1 << dct_size) | (differential + 1));
2749 }
2750 }
2751 else {
2752 self->block_data[0] = predictor;
2753 }
2754
2755 // Save predictor value
2756 self->dc_predictor[plane_index] = self->block_data[0];
2757
2758 // Dequantize + premultiply
2759 self->block_data[0] <<= (3 + 5);
2760
2761 quant_matrix = self->intra_quant_matrix;
2762 n = 1;
2763 }
2764 else {
2765 quant_matrix = self->non_intra_quant_matrix;
2766 }
2767
2768 // Decode AC coefficients (+DC for non-intra)
2769 int level = 0;
2770 while (TRUE) {
2771 int run = 0;
2773
2774 if ((coeff == 0x0001) && (n > 0) && (plm_buffer_read(self->buffer, 1) == 0)) {
2775 // end_of_block
2776 break;
2777 }
2778 if (coeff == 0xffff) {
2779 // escape
2780 run = plm_buffer_read(self->buffer, 6);
2781 level = plm_buffer_read(self->buffer, 8);
2782 if (level == 0) {
2783 level = plm_buffer_read(self->buffer, 8);
2784 }
2785 else if (level == 128) {
2786 level = plm_buffer_read(self->buffer, 8) - 256;
2787 }
2788 else if (level > 128) {
2789 level = level - 256;
2790 }
2791 }
2792 else {
2793 run = coeff >> 8;
2794 level = coeff & 0xff;
2795 if (plm_buffer_read(self->buffer, 1)) {
2796 level = -level;
2797 }
2798 }
2799
2800 n += run;
2801 if (n < 0 || n >= 64) {
2802 return; // invalid
2803 }
2804
2805 int de_zig_zagged = PLM_VIDEO_ZIG_ZAG[n];
2806 n++;
2807
2808 // Dequantize, oddify, clip
2809 level = (unsigned)level << 1;
2810 if (!self->macroblock_intra) {
2811 level += (level < 0 ? -1 : 1);
2812 }
2813 level = (level * self->quantizer_scale * quant_matrix[de_zig_zagged]) >> 4;
2814 if ((level & 1) == 0) {
2815 level -= level > 0 ? 1 : -1;
2816 }
2817 if (level > 2047) {
2818 level = 2047;
2819 }
2820 else if (level < -2048) {
2821 level = -2048;
2822 }
2823
2824 // Save premultiplied coefficient
2825 self->block_data[de_zig_zagged] = level * PLM_VIDEO_PREMULTIPLIER_MATRIX[de_zig_zagged];
2826 }
2827
2828 // Move block to its place
2829 uint8_t *d;
2830 int dw;
2831 int di;
2832
2833 if (block < 4) {
2834 d = self->frame_current.y.data;
2835 dw = self->luma_width;
2836 di = (self->mb_row * self->luma_width + self->mb_col) << 4;
2837 if ((block & 1) != 0) {
2838 di += 8;
2839 }
2840 if ((block & 2) != 0) {
2841 di += self->luma_width << 3;
2842 }
2843 }
2844 else {
2845 d = (block == 4) ? self->frame_current.cb.data : self->frame_current.cr.data;
2846 dw = self->chroma_width;
2847 di = ((self->mb_row * self->luma_width) << 2) + (self->mb_col << 3);
2848 }
2849
2850 int *s = self->block_data;
2851 int si = 0;
2852 if (self->macroblock_intra) {
2853 // Overwrite (no prediction)
2854 if (n == 1) {
2855 int clamped = plm_clamp((s[0] + 128) >> 8);
2856 PLM_BLOCK_SET(d, di, dw, si, 8, 8, clamped);
2857 s[0] = 0;
2858 }
2859 else {
2860 plm_video_idct(s);
2861 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(s[si]));
2862 fl::memset(self->block_data, 0, sizeof(self->block_data));
2863 }
2864 }
2865 else {
2866 // Add data to the predicted macroblock
2867 if (n == 1) {
2868 int value = (s[0] + 128) >> 8;
2869 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + value));
2870 s[0] = 0;
2871 }
2872 else {
2873 plm_video_idct(s);
2874 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + s[si]));
2875 fl::memset(self->block_data, 0, sizeof(self->block_data));
2876 }
2877 }
2878}
void run(fl::u32 microseconds, ExecFlags flags)
Run selected task subsystems.
static const uint8_t PLM_VIDEO_PREMULTIPLIER_MATRIX[]
Definition pl_mpeg.hpp:1690
int plm_buffer_read(plm_buffer_t *self, int count) FL_NOEXCEPT
Definition pl_mpeg.hpp:1017
static const plm_vlc_uint_t PLM_VIDEO_DCT_COEFF[]
Definition pl_mpeg.hpp:1920
fl::u16 uint16_t
Definition coder.h:214
static uint8_t plm_clamp(int n) FL_NOEXCEPT
Definition pl_mpeg.hpp:2097
static const plm_vlc_t * PLM_VIDEO_DCT_SIZE[]
Definition pl_mpeg.hpp:1907
uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self, const plm_vlc_uint_t *table) FL_NOEXCEPT
Definition pl_mpeg.hpp:1119
static const uint8_t PLM_VIDEO_ZIG_ZAG[]
Definition pl_mpeg.hpp:1657
unsigned char uint8_t
Definition coder.h:209
void plm_video_idct(int *block) FL_NOEXCEPT
Definition pl_mpeg.hpp:2880
int16_t plm_buffer_read_vlc(plm_buffer_t *self, const plm_vlc_t *table) FL_NOEXCEPT
Definition pl_mpeg.hpp:1111
constexpr int type_rank< T >::value
void * memset(void *s, int c, size_t n) FL_NOEXCEPT
#define TRUE
Definition pl_mpeg.hpp:174
#define PLM_BLOCK_SET(DEST, DEST_INDEX, DEST_WIDTH, SOURCE_INDEX, SOURCE_WIDTH, BLOCK_SIZE, OP)
Definition pl_mpeg.hpp:2675

References FL_NOEXCEPT, fl::memset(), PLM_BLOCK_SET, plm_buffer_read(), plm_buffer_read_vlc(), plm_buffer_read_vlc_uint(), plm_clamp(), PLM_VIDEO_DCT_COEFF, PLM_VIDEO_DCT_SIZE, plm_video_idct(), PLM_VIDEO_PREMULTIPLIER_MATRIX, PLM_VIDEO_ZIG_ZAG, TRUE, and fl::type_rank< T >::value.

Referenced by plm_video_decode_macroblock().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: