FFmpeg
Loading...
Searching...
No Matches
ogg_pages.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <inttypes.h>
20#include <stdio.h>
21#include <string.h>
22
23#include "libavutil/crc.h"
25
26#define OGG_PAGE_HEADER_SIZE 27
27#define OGG_PAGE_MAX_SIZE (OGG_PAGE_HEADER_SIZE + 255 + 255 * 255)
28
29static uint8_t page[OGG_PAGE_MAX_SIZE];
30
31int main(int argc, char **argv)
32{
33 const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE);
34 size_t nb_read;
35 long pos = 0;
36 int ret = 1;
37 FILE *file;
38
39 if (argc != 2) {
40 fprintf(stderr, "Usage: %s <file.ogg>\n"
41 "Print the header of every page and check its checksum.\n",
42 argv[0]);
43 return 1;
44 }
45
46 file = fopen(argv[1], "rb");
47 if (!file) {
48 perror(argv[1]);
49 return 1;
50 }
51
52 while ((nb_read = fread(page, 1, OGG_PAGE_HEADER_SIZE, file)) == OGG_PAGE_HEADER_SIZE) {
53 int nb_segments = page[26], body_size = 0, page_size;
54 uint32_t crc;
55
56 if (memcmp(page, "OggS", 4) ||
57 fread(page + OGG_PAGE_HEADER_SIZE, 1, nb_segments, file) != nb_segments) {
58 fprintf(stderr, "Invalid page at %ld\n", pos);
59 goto end;
60 }
61
62 for (int i = 0; i < nb_segments; i++)
63 body_size += page[OGG_PAGE_HEADER_SIZE + i];
64
65 page_size = OGG_PAGE_HEADER_SIZE + nb_segments + body_size;
66 if (fread(page + page_size - body_size, 1, body_size, file) != body_size) {
67 fprintf(stderr, "Truncated page at %ld\n", pos);
68 goto end;
69 }
70
71 crc = AV_RB32(page + 22);
72 AV_WB32(page + 22, 0);
73 if (av_crc(crc_table, 0, page, page_size) != crc) {
74 fprintf(stderr, "Checksum mismatch in page at %ld\n", pos);
75 goto end;
76 }
77
78 printf("pos=%ld serial=%"PRIu32" sequence=%"PRIu32" granule=%"PRId64
79 " flags=%c%c%c segments=%d size=%d\n",
80 pos, AV_RL32(page + 14), AV_RL32(page + 18),
81 (int64_t)AV_RL64(page + 6),
82 page[5] & 1 ? 'c' : '-', page[5] & 2 ? 'b' : '-',
83 page[5] & 4 ? 'e' : '-', nb_segments, body_size);
84
85 pos += page_size;
86 }
87
88 ret = nb_read || ferror(file);
89 if (ret)
90 fprintf(stderr, "Truncated page at %ld\n", pos);
91
92end:
93 fclose(file);
94 return ret;
95}
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
long long int64_t
Definition coverity.c:34
Public header for CRC hash function implementation.
__device__ int printf(const char *,...)
int main
Definition dovi_rpuenc.c:38
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition crc.c:389
uint32_t AVCRC
Definition crc.h:46
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition crc.c:421
@ AV_CRC_32_IEEE
Definition crc.h:52
#define AV_WB32(p, v)
#define AV_RL64(p)
#define AV_RL32(p)
#define AV_RB32(p)
#define OGG_PAGE_MAX_SIZE
Definition ogg_pages.c:27
#define OGG_PAGE_HEADER_SIZE
Definition ogg_pages.c:26
static uint8_t page[OGG_PAGE_MAX_SIZE]
Definition ogg_pages.c:29
unsigned int pos
Definition spdifenc.c:431