#include #include #include "fileutils.h" #include "generic.h" #include "cdutils.h" /* From the SONY documentation: 32 bytes header: StSTATUS : 2 bytes 0 StTYPE : 2 bytes 2 StSECTOR_OFFSET: 2 bytes 4 StSECTOR_SIZE : 2 bytes 6 StFRAME_NO : 4 bytes 10 StFRAME_SIZE : 4 bytes 14 StMOVIE_WIDTH : 2 bytes 16 StMOVIE_HEIGHT : 2 bytes 18 StMOVIE_HEADM : 4 bytes 22 StMOVIE_HEADV : 4 bytes 26 Channels : 2 bytes 30 */ int DCT[8][8] = { { 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, }, { 5681, 4816, 3218, 1130, -1130, -3218, -4816, -5681, }, { 5352, 2217, -2217, -5532, -5532, -2217, 2217, 5352, }, { 4816, -1130, -5681, -3218, 3218, 5681, 1130, -4816, }, { 4096, -4096, 4096, -4096, 4096, -4096, 4096, -4096, }, { 3218, -5681, 1130, 4816, -4816, -1130, 5681, -3218, }, { 2217, -5352, 5352, -2217, -2217, 5352, -5352, 2217, }, { 1130, -3218, 4816, -5681, 5681, -4816, 3218, -1130, }, }; int iDCT[8][8] = { { 4096, 5681, 5352, 4816, 4096, 3218, 2217, 1130, }, { 4096, 4816, 2217, -1130, -4096, -5681, -5352, -3218, }, { 4096, 3218, -2217, -5681, 4096, 1130, 5352, 4816, }, { 4096, 1130, -5532, -3218, -4096, 4816, -2217, -5681, }, { 4096, -1130, -5532, 3218, 4096, -4816, -2217, 5681, }, { 4096, -3218, -2217, 5681, -4096, -1130, 5352, -4816, }, { 4096, -4816, 2217, 1130, 4096, 5681, -5352, 3218, }, { 4096, -5681, 5352, -4816, -4096, -3218, 2217, -1130, }, }; int zscan[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, }; int izscan[] = { 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63, }; int iqtab[] = { 2, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83, }; float RGB2YUV[3][3] = { { 1.00000, 0.00000, 1.40200, }, { 1.00000, -0.34370, -0.71430, }, { 1.00000, 1.77200, 0.00000, }, }; float YUV2RGB[3][3] = { { 0.22900, 0.58700, 0.11400, }, { -0.16871, -0.33130, 0.50000, }, { 0.50000, -0.41870, -0.08130, }, }; struct STR_Header { Uint16 StSTATUS; Uint16 StTYPE; Uint16 StSECTOR_OFFSET; Uint16 StSECTOR_SIZE; Uint32 StFRAME_NO; Uint32 StFRAME_SIZE; Uint16 StMOVIE_WIDTH; Uint16 StMOVIE_HEIGHT; Uint32 StMOVIE_HEADM; Uint32 StMOVIE_HEADV; Uint16 Channels; } __attribute__((packed)); Byte * video = 0, * audio = 0; void print_bits(Uint16 w, int size = 16) { int i; for (i = size - 1; i >= 0; i--) { printm(M_BARE, "%c", w & (1 << i) ? '1' : '0'); } } Uint32 get_bits(Byte * datas, int size, Uint32 * pointer) { static int internal = 0; static Uint16 w = 0; Uint32 r = 0; int os = size; if (internal < size) { r = w; size -= internal; w = *((Uint16 *) (video + *pointer)); printm(M_BARE, "get_bits: needs food, got 0x%04x\n", w); *pointer += 2; // w = swap_word(w); internal = 16; } r <<= size; r |= ((w >> (16 - size)) & ((1 << size) - 1)); w <<= size; printm(M_BARE, "Read bits: "); print_bits(r, os); printm(M_BARE, "\n"); internal -= size; r &= ((1 << size) - 1); return r; } void process_one_sector(FILE * f) { Byte sector[2336]; STR_Header * h; fread(sector, 2336, 1, f); h = (STR_Header *) ((Byte *) sector + 8); printm(M_BARE, "SubHeader FN : %x\n", sector[0]); printm(M_BARE, "SubHeader CN : %x\n", sector[1]); printm(M_BARE, "SubHeader SM : %x\n", sector[2]); printm(M_BARE, "SubHeader CI : %x\n", sector[3]); if (sector[2] == 0x48) { printm(M_BARE, "Video sector\n"); printm(M_BARE, "Status : %04x\n", h->StSTATUS); printm(M_BARE, "Type : %04x\n", h->StTYPE); printm(M_BARE, "Sector Offset: %i\n", h->StSECTOR_OFFSET); printm(M_BARE, "Sector Size : %i\n", h->StSECTOR_SIZE); printm(M_BARE, "Frame Number : %i\n", h->StFRAME_NO); printm(M_BARE, "Frame Size : %i\n", h->StFRAME_SIZE); printm(M_BARE, "Movie Width : %i\n", h->StMOVIE_WIDTH); printm(M_BARE, "Movie Height : %i\n", h->StMOVIE_HEIGHT); printm(M_BARE, "Movie HeadM : %08x\n", h->StMOVIE_HEADM); printm(M_BARE, "Movie HeadV : %08x\n", h->StMOVIE_HEADV); printm(M_BARE, "Channels : %04x\n", h->Channels); if (h->StSECTOR_OFFSET == 0) { video = (Byte *) malloc(h->StSECTOR_SIZE * 2016); } memcpy(video + h->StSECTOR_OFFSET * 2016, sector + 40, 2016); if (h->StSECTOR_SIZE == (h->StSECTOR_OFFSET + 1)) { Uint32 pointer = 0; Uint32 macrobloc = 0; // Frame finished. printm(M_BARE, "End of Frame.\n"); // fwrite(video, 1, h->StSECTOR_SIZE * 2016, stdout); Uint16 rl_size = *((Uint16 *) (video + pointer)); pointer += 2; if (*((Uint16 *) (video + pointer)) != 0x3800) { printm(M_ERROR, "Broken frame\n"); // break; } pointer += 2; Uint16 quant = *((Uint16 *) (video + pointer)); pointer += 2; Uint16 ver = *((Uint16 *) (video + pointer)); pointer += 2; int rls = 0; while (rls <= rl_size) { printm(M_BARE, "Processing macrobloc %i, rlsize = %i, quant = %i, ver = %i, pointer = 0x%08x\n", macrobloc, rl_size, quant, ver, pointer); int16 Cb[64], Cr[64], Y0[64], Y1[64], Y2[64], Y3[64]; int16 * blocs[6] = {Cb, Cr, Y0, Y1, Y2, Y3}; int bloc; for (bloc = 0; bloc < 6; bloc++) { int i; for (i = 0; i < 64; i++) { blocs[bloc][i] = 0; } int16 DC = get_bits(video, 10, &pointer); if (DC & 0x20) DC |= 0xc0; printm(M_BARE, "Processing subbloc %i, DC = %i, Quant = %i, pointer = 0x%08x\n", bloc, DC, quant, pointer); int inbloc = 1; blocs[bloc][0] = DC; while (inbloc < 64) { Uint8 run = get_bits(video, 6, &pointer); int16 level; level = get_bits(video, 8, &pointer); if (level == 0) { level = get_bits(video, 8, &pointer); } else if (level & 0x80) { if (level == 0x80) level = get_bits(video, 8, &pointer); level |= 0xff00; } printm(M_BARE, "Read a runlevel: (%i, %i) = (%x %x), inbloc = %i, (pointer is %i)\n", run, level, run, level, inbloc, pointer); rls++; blocs[bloc][inbloc] = level; inbloc += run + 1; } printm(M_BARE, "Finished the bloc with inbloc = %i\n", inbloc); } macrobloc++; } exit(-1); free(video); } } else if (sector[2] == 0x64) { printm(M_BARE, "Audio sector\n"); } else { printm(M_BARE, "Unknow sector\n"); } printm(M_BARE, "---------------------------------\n\n"); } #ifdef STR_MAIN int main(void) { while (!feof(stdin)) { process_one_sector(stdin); } } #endif