#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, 17, 12, 27, 35, 29, 58, 53, 1, 24, 19, 20, 42, 22, 59, 60, 8, 32, 26, 13, 49, 15, 52, 61, 16, 25, 35, 6, 56, 23, 45, 54, 9, 18, 40, 7, 57, 30, 38, 47, 2, 11, 48, 14, 50, 37, 31, 55, 3, 4, 41, 21, 43, 44, 39, 62, 10, 5, 34, 28, 36, 51, 46, 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 i; for (i = 0; i < 16; i++) { printm(M_BARE, "%c", w & (1 << i) ? '1' : '0'); } } Uint32 get_bits(Uint16 * datas, int size, int * pointer) { static internal = 0; static Uint16 w = 0; Uint16 r = 0; if (internal <= size) { r = w; size -= internal; w = *((Uint16 *) (video + pointer)); pointer += 2; w = swap_word(w); internal = 16; } r <<= size; r |= ((w >> (16 - size)) & ((1 << size) - 1)); w <<= size; 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); while (pointer <= h->StFRAME_SIZE) { 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)); printm(M_BARE, "Processing macrobloc %i, rlsize = %i, quant = %i, ver = %i, pointer = 0x%08x\n", macrobloc, rl_size, quant, ver, pointer); for (int i = 0; i < 32; i++) { } printm(M_BARE, "\n"); // int16 Cb[64], Cr[64], Y0[64], Y1[64], Y2[64], Y3[64]; // int16 * blocs[6] = {Cb, Cr, Y0, Y1, Y2, Y3}; // int bloc; exit(-1); /* for (bloc = 0; bloc < 6; bloc++) { Uint16 QSP = *((Uint16 *) (video + pointer)); pointer += 2; int16 DC = QSP & 0x3f; Uint8 Quant = QSP >> 10; int i; for (i = 0; i < 64; i++) { blocs[bloc][i] = 0; } if (DC & 0x20) { DC |= 0xc0; } printm(M_BARE, "Processing subbloc %i, DC = %i, Quant = %i, pointer = 0x%08x\n", bloc, DC, Quant, pointer); int inblock = 1; blocs[bloc][0] = DC; while (1) { Uint16 RCF = *((Uint16 *) (video + pointer)); pointer += 2; if (RCF == 0xfe00) { break; } printm(M_BARE, "Read a RCF: 0x%04x\n", RCF); int16 Level = RCF & 0x3f; Uint8 Run = RCF >> 10; if (Level & 0x20) { Level |= 0xc0; } blocs[bloc][inblock] = Level; inblock += Run + 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