Пример #1
0
static void test_mpeg(void *bytes, uint32_t len, struct h262_picparm *picparm, struct h262_seqparm *seqparm)
{
#if 1
	struct bitstream *str = vs_new_decode(VS_H262, bytes, len);
	int nslice = 0;

	while (str->bytepos < str->bytesnum) {
		unsigned start_code;

		if (vs_start(str, &start_code)) goto err;

		if (start_code >= H262_START_CODE_SLICE_BASE && start_code <= H262_START_CODE_SLICE_LAST) {
			struct h262_slice *slice;

			nslice++;

			slice = calloc (sizeof *slice, 1);
			slice->mbs = calloc (sizeof *slice->mbs, picparm->pic_size_in_mbs);
			slice->slice_vertical_position = start_code - H262_START_CODE_SLICE_BASE;
			if (seqparm->vertical_size > 2800) {
				uint32_t svp_ext;
				if (vs_u(str, &svp_ext, 3)) {
					h262_del_slice(slice);
					goto err;
				}
				if (slice->slice_vertical_position >= 0x80) {
					fprintf(stderr, "Invalid slice start code for large picture\n");
					goto err;
				}
				slice->slice_vertical_position += svp_ext * 0x80;
			}
			if (slice->slice_vertical_position >= picparm->pic_height_in_mbs) {
				fprintf(stderr, "slice_vertical_position too large\n");
				goto err;
			}
			if (h262_slice(str, seqparm, picparm, slice)) {
//				h262_print_slice(seqparm, picparm, slice);
				h262_del_slice(slice);
				goto err;
			}
//			h262_print_slice(seqparm, picparm, slice);
			if (vs_end(str)) {
				h262_del_slice(slice);
				goto err;
			}
			h262_del_slice(slice);
		} else {
			fprintf(stderr, "Unknown start code %08x\n", start_code);
			goto err;
		}
	}
	return;

err:
	assert(0);
	exit(1);
#endif
}
Пример #2
0
int vs_ue(struct bitstream *str, uint32_t *val) {
	int lzb = 0;
	uint32_t tmp;
	if (str->dir == VS_ENCODE) {
		tmp = 0;
		if (*val >= (uint32_t)0xffffffff) {
			fprintf (stderr, "Exp-Golomb number larger than 2^32-2\n");
			return 1;
		}
		while (*val >= (uint32_t)(1u << (lzb + 1)) - 1) {
			if (vs_u(str, &tmp, 1))
				return 1;
			lzb++;
		}
		tmp = 1;
		if (vs_u(str, &tmp, 1))
			return 1;
		tmp = *val - ((1 << lzb) - 1);
		if (vs_u(str, &tmp, lzb))
			return 1;
		return 0;
	} else {
		do {
			if (vs_u(str, &tmp, 1))
				return 1;
			lzb++;
		} while (!tmp);
		lzb--;
		if (lzb > 31) {
			fprintf (stderr, "Exp-Golomb number larger than 2^32-2\n");
			return 1;
		}
		if (vs_u(str, &tmp, lzb))
			return 1;
		*val = tmp + (1u << lzb) - 1;
		return 0;
	}
}
Пример #3
0
int main() {
	uint8_t *bytes = 0;
	int bytesnum = 0;
	int bytesmax = 0;
	int c;
	int res;
	while ((c = getchar()) != EOF) {
		ADDARRAY(bytes, c);
	}
	struct bitstream *str = vs_new_decode(VS_H262, bytes, bytesnum);
	struct h262_seqparm *seqparm = calloc(sizeof *seqparm, 1);
	struct h262_picparm *picparm = calloc(sizeof *picparm, 1);
	struct h262_gop *gop = calloc(sizeof *gop, 1);
	struct h262_slice *slice;
	while (1) {
		uint32_t start_code;
		uint32_t ext_start_code;
		if (vs_start(str, &start_code)) goto err;
		printf("Start code: %02x\n", start_code);
		switch (start_code) {
			case H262_START_CODE_SEQPARM:
				if (h262_seqparm(str, seqparm))
					goto err;
				if (vs_end(str))
					goto err;
				h262_print_seqparm(seqparm);
				break;
			case H262_START_CODE_PICPARM:
				if (h262_picparm(str, seqparm, picparm))
					goto err;
				if (vs_end(str))
					goto err;
				h262_print_picparm(picparm);
				break;
			case H262_START_CODE_GOP:
				if (h262_gop(str, gop))
					goto err;
				if (vs_end(str))
					goto err;
				h262_print_gop(gop);
				break;
			case H262_START_CODE_EXTENSION:
				if (vs_u(str, &ext_start_code, 4)) goto err;
				printf("Extension start code: %d\n", ext_start_code);
				switch (ext_start_code) {
					case H262_EXT_SEQUENCE:
						if (h262_seqparm_ext(str, seqparm))
							goto err;
						if (vs_end(str))
							goto err;
						h262_print_seqparm(seqparm);
						break;
					case H262_EXT_PIC_CODING:
						if (h262_picparm_ext(str, seqparm, picparm))
							goto err;
						if (vs_end(str))
							goto err;
						h262_print_picparm(picparm);
						break;
					default:
						fprintf(stderr, "Unknown extension start code\n");
						goto err;
				}
				break;
			case H262_START_CODE_END:
				printf ("End of sequence.\n");
				break;
			default:
				if (start_code >= H262_START_CODE_SLICE_BASE && start_code <= H262_START_CODE_SLICE_LAST) {
					slice = calloc (sizeof *slice, 1);
					slice->mbs = calloc (sizeof *slice->mbs, picparm->pic_size_in_mbs);
					slice->slice_vertical_position = start_code - H262_START_CODE_SLICE_BASE;
					if (seqparm->vertical_size > 2800) {
						uint32_t svp_ext;
						if (vs_u(str, &svp_ext, 3)) {
							h262_del_slice(slice);
							goto err;
						}
						if (slice->slice_vertical_position >= 0x80) {
							fprintf(stderr, "Invalid slice start code for large picture\n");
							goto err;
						}
						slice->slice_vertical_position += svp_ext * 0x80;
					}
					if (slice->slice_vertical_position >= picparm->pic_height_in_mbs) {
						fprintf(stderr, "slice_vertical_position too large\n");
						goto err;
					}
					if (h262_slice(str, seqparm, picparm, slice)) {
						h262_print_slice(seqparm, picparm, slice);
						h262_del_slice(slice);
						goto err;
					}
					h262_print_slice(seqparm, picparm, slice);
					if (vs_end(str)) {
						h262_del_slice(slice);
						goto err;
					}
					h262_del_slice(slice);
					break;
				} else {
					fprintf(stderr, "Unknown start code\n");
					goto err;
				}
		}
		printf("NAL decoded successfully\n\n");
		continue;
err:
		res = vs_search_start(str);
		if (res == -1)
			return 1;
		if (!res)
			break;
		printf("\n");
	}
	return 0;
}
Пример #4
0
int h262_seqparm(struct bitstream *str, struct h262_seqparm *seqparm) {
    uint32_t hs = seqparm->horizontal_size & 0xfff;
    uint32_t vs = seqparm->vertical_size & 0xfff;
    uint32_t br = seqparm->bit_rate & 0x3ffff;
    uint32_t vbv = seqparm->vbv_buffer_size & 0x3ff;
    int i;
    if (str->dir == VS_ENCODE && !seqparm->is_ext) {
        if (hs != seqparm->horizontal_size) {
            fprintf(stderr, "horizontal_size too big for MPEG1\n");
            return 1;
        }
        if (vs != seqparm->vertical_size) {
            fprintf(stderr, "vertical_size too big for MPEG1\n");
            return 1;
        }
        if (br != seqparm->bit_rate) {
            fprintf(stderr, "bit_rate too big for MPEG1\n");
            return 1;
        }
        if (vbv != seqparm->vbv_buffer_size) {
            fprintf(stderr, "vbv_buffer_size too big for MPEG1\n");
            return 1;
        }
    }
    if (vs_u(str, &hs, 12)) return 1;
    if (vs_u(str, &vs, 12)) return 1;
    if (vs_u(str, &seqparm->aspect_ratio_information, 4)) return 1;
    if (vs_u(str, &seqparm->frame_rate_code, 4)) return 1;
    if (vs_u(str, &br, 18)) return 1;
    if (vs_mark(str, 1, 1)) return 1;
    if (vs_u(str, &vbv, 10)) return 1;
    if (vs_u(str, &seqparm->constrained_parameters_flag, 1)) return 1;
    if (vs_u(str, &seqparm->load_intra_quantiser_matrix, 1)) return 1;
    if (seqparm->load_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            if (vs_u(str, &seqparm->intra_quantiser_matrix[i], 8)) return 1;
    }
    if (vs_u(str, &seqparm->load_non_intra_quantiser_matrix, 1)) return 1;
    if (seqparm->load_non_intra_quantiser_matrix) {
        for (i = 0; i < 64; i++)
            if (vs_u(str, &seqparm->non_intra_quantiser_matrix[i], 8)) return 1;
    }
    if (str->dir == VS_DECODE) {
        seqparm->horizontal_size = hs;
        seqparm->vertical_size = vs;
        seqparm->bit_rate = br;
        seqparm->vbv_buffer_size = vbv;
        seqparm->is_ext = 0;
        seqparm->has_disp_ext = 0;
    }
    if (!seqparm->is_ext) {
        if (vs_infer(str, &seqparm->progressive_sequence, 1)) return 1;
        if (vs_infer(str, &seqparm->chroma_format, 1)) return 1;
        if (vs_infer(str, &seqparm->low_delay, 0)) return 1;
        if (vs_infer(str, &seqparm->low_delay, 0)) return 1;
        if (vs_infer(str, &seqparm->frame_rate_extension_n, 0)) return 1;
        if (vs_infer(str, &seqparm->frame_rate_extension_d, 0)) return 1;
    }
    return 0;
}