User Tools

Site Tools


tech:multimedia:rmvb

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tech:multimedia:rmvb [2011/01/12 07:38]
admin
tech:multimedia:rmvb [2014/11/10 08:22]
Line 1: Line 1:
-#include <​stdio.h>​ 
-#include <​stdlib.h>​ 
-  
-#define MKTAG(a,​b,​c,​d) (d | (c << 8) | (b << 16) | (a << 24)) 
-#define ERROR    do {printf("​Error Detected\n"​);​ exit(0);} while(0) 
  
-#define REALAUDIO_MIME_TYPE "​audio/​x-pn-realaudio"​ 
-#define REALVIDEO_MIME_TYPE "​video/​x-pn-realvideo"​ 
- 
-static int audio_stream = -1; 
-static int video_stream = -1; 
-  
-  
-int rmvb_unpack32(FILE *fp, unsigned int *pVal) 
-{ 
-    unsigned char buf[4]; 
-  
-    if (fread(buf, 1, 4, fp) != 4) 
-    { 
-        return -1; 
-    } 
-  
-    *pVal = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3]; 
-    return 0; 
-} 
-  
-int rmvb_unpack16(FILE *fp, unsigned short *pVal) 
-{ 
-    unsigned char buf[2]; 
-  
-    if (fread(buf, 1, 2, fp) != 2) 
-    { 
-        return -1; 
-    } 
-  
-    *pVal = (buf[0] << 8)|buf[1]; 
-    return 0; 
-  
-} 
-  
-int rmvb_unpack8(FILE *fp, unsigned char *pVal) 
-{ 
-    *pVal = (unsigned char) fgetc(fp); 
-  
-    if (feof(fp)) ​ 
-        return -1; 
-    else  
-        return 0; 
-} 
-  
-int rmvb_unpack14or30(FILE *fp, unsigned int *pval, unsigned int *len) 
-{ 
-    unsigned short tmp1; 
-    unsigned int tmp2; 
-  
-    if (rmvb_unpack16(fp,​ &tmp1)) return -1; 
-    if (tmp1&​0x4000) 
-    { 
-        *pval = tmp1&​0x3fff;​ 
-        *len = 2; 
-    } 
-    else 
-    { 
-        fseek(fp, -2, SEEK_CUR); 
-        if (rmvb_unpack32(fp,​ &tmp2)) return -1; 
-        *pval = tmp2&​0x3ffffff;​ 
-        *len = 4; 
-    }    
-  
-    return 0; 
-} 
-  
-int parse_basic(FILE *fp, unsigned int *pId, unsigned int *pSize, unsigned short *pVersion) 
-{ 
-    unsigned int size; 
-    unsigned short version; 
-  
-    if (rmvb_unpack32(fp,​ pId)) 
-        return -1; 
-    if (rmvb_unpack32(fp,​ pSize)) 
-        return -1; 
-    if (rmvb_unpack16(fp,​ pVersion)) 
-        return -1; 
-  
-    return 0; 
-} 
-  
-int parse_indx(FILE *fp, unsigned int size, unsigned short version) 
-{    ​ 
-    unsigned int pos = ftell(fp) - 10; 
-  
-    printf("​\nINDX Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​ 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-int parse_frame(FILE *fp, int size) 
-{ 
-    unsigned int pos = ftell(fp); 
-    unsigned short tmp1; 
-    unsigned char type, seq, tmp2; 
-    unsigned int size2, time, len, off; 
-    unsigned char packets, packet; 
- 
-    if (rmvb_unpack16(fp,​ &tmp1)) return -1; 
-    type = tmp1 >> 14; 
-    fseek(fp, -2, SEEK_CUR); 
-  
-    switch(type) 
-    { 
-     /* partial frame */ 
-        case 0: 
-        case 2: 
-            if (rmvb_unpack16(fp,​ &tmp1)) return -1; 
-            if (rmvb_unpack14or30(fp,​ &len, &​size2)) return -1; 
-            if (rmvb_unpack14or30(fp,​ &off, &​size2)) return -1; 
-            if (rmvb_unpack8(fp,​ &seq)) return -1; 
-            packets = ((tmp1 & 0x3F80) >> 7); 
-            packet = (tmp1 & 0x007F); 
-            printf("​\t\t"​);​ 
-            if (packet == 1) putchar('​{'​);​ 
-            else putchar('​+'​);​ 
-            printf("​No.%d (%d-%d), %d@%d",​ seq, packets, packet, off, len); 
-            if (packet == packets) putchar('​}'​);​ 
-            else putchar('​+'​);​ 
-            putchar('​\n'​);​ 
-            break; 
-        case 1: 
-            if (rmvb_unpack8(fp,​ &tmp2)) return -1; 
-            if (rmvb_unpack8(fp,​ &seq)) return -1; 
-            printf("​\t\t{No.%d}\n",​ seq); 
-            break; 
-        case 3: 
-            while (size > 0) 
-            { 
-                putchar('​\t'​);​ 
-                putchar('​\t'​);​ 
-                len = 0; 
-                if (rmvb_unpack8(fp,​ &tmp2)) return -1; 
-                if (rmvb_unpack14or30(fp,​ &size2, &len)) return -1; 
-                size -= len; 
-                if (rmvb_unpack14or30(fp,​ &time, &len)) return -1; 
-                size -= len; 
-                if (rmvb_unpack8(fp,​ &seq)) return -1; 
-                size -=2; 
-                printf("​{No.%d,​ size: %d, time: %d},​\n",​ seq, size2, time); 
-                fseek(fp, size2, SEEK_CUR); 
-                size -= size2; 
- } 
-            break; 
-        default: 
-            break; 
-    } 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-    return 0; 
-} 
-  
-int parse_packet(FILE *fp) 
-{ 
-    unsigned short version; 
-    unsigned short size; 
-    unsigned short stream; 
-    unsigned int time; 
-    unsigned char pkt_grp, flags; 
-    unsigned short asm_rule; 
-    unsigned int pos = ftell(fp); 
-  
-    if (rmvb_unpack16(fp,​ &​version)) return -1; 
-    if (rmvb_unpack16(fp,​ &size)) return -1; 
-    if (rmvb_unpack16(fp,​ &​stream)) return -1; 
-    if (rmvb_unpack32(fp,​ &time)) return -1; 
-    if (version == 0) 
-    { 
-        if (rmvb_unpack8(fp,​ &​pkt_grp)) return -1; 
-        if (rmvb_unpack8(fp,​ &​flags)) return -1; 
-    } 
-    else 
-    { 
-        if (rmvb_unpack16(fp,​ &​asm_rule)) return -1; 
-        if (rmvb_unpack8(fp,​ &​flags)) return -1;    
-    } 
-    printf("​stream#​%d,​ size=%d, time:​%d\n",​ stream, size, time); 
-  
-    if (stream == video_stream) 
- { 
-        if (parse_frame(fp,​ size-12-version)) return -1; 
-    } 
-    fseek(fp, pos+size, SEEK_SET); 
-    return 0; 
-} 
-  
-int parse_data(FILE *fp, unsigned int size, unsigned short version) 
-{    
-    unsigned int packets; 
-    unsigned int next; 
-    unsigned int pos = ftell(fp) - 10; 
-    int i; 
-  
-    printf("​\nDATA Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​ 
-  
-    if (rmvb_unpack32(fp,​ &​packets)) return -1; 
-    if (rmvb_unpack32(fp,​ &next)) return -1; 
-  
-    for (i = 0; i < packets; i++) 
-    { 
-        putchar('​\t'​);​ 
-        printf("​Packet %d: ", i); 
-        if (parse_packet(fp)) return -1; 
-    } 
-  
-    if (next) 
-        fseek(fp, next, SEEK_SET); 
-    else 
-        fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-  
-int parse_prop(FILE *fp, unsigned int size, unsigned short version) 
-{ 
-    unsigned int pos = ftell(fp)-10;​ 
-    unsigned int v32; 
-    unsigned short v16; 
-  
-    printf("​\nPROP Detected @0x%x, size=%u, version = %d\n", pos, size, version); 
-    putchar('​\t'​);​ 
-    if (version == 0) 
-    { 
-        putchar('​{'​);​ 
-        putchar(0x20);​ 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​bitrate:​ %u/", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u;​ ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​packet size: %u/", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u;​ ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u packets; ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​duartion=%u ms; ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​INDX@0x%x;​ ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​DATA@0x%x;​ ", v32); 
-        if (rmvb_unpack16(fp,​ &v16)) return -1; 
-        printf("​%u streams; ", v16); 
-        putchar('​}'​);​ 
-    } 
-    putchar('​\n'​);​ 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-int parse_mdpr(FILE *fp, unsigned int size, unsigned short version) 
-{ 
-    unsigned int pos = ftell(fp) - 10; 
-    unsigned int v32; 
-    unsigned short v16; 
-    unsigned char v8; 
-    char pStr[256]; 
- int stream_nbr = -1; 
-  
-    printf("​\nMDPR Detected @0x%x, size=%u, version = %d\n", pos, size, version); 
-    putchar('​\t'​);​ 
-    if (version == 0) 
-    { 
-        putchar('​{'​);​ 
-        putchar(0x20);​ 
-        if (rmvb_unpack16(fp,​ &v16)) return -1; 
-        printf("​stream#​%d;​ ", v16); 
- stream_nbr = v16; 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​bitrate:​ %u/", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u;​ ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​packet size: %u/", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u;​ ", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​time:​ %u+", v32); 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        if (rmvb_unpack32(fp,​ &v32)) return -1; 
-        printf("​%u ms; ", v32); 
-        if (rmvb_unpack8(fp,​ &v8) || fread(pStr, 1, v8, fp) != v8) return -1; 
-        pStr[v8]=0; 
-        printf("​%s;​ ", pStr); 
-        if (rmvb_unpack8(fp,​ &v8) || fread(pStr, 1, v8, fp) != v8) return -1; 
-        pStr[v8]=0; 
-        printf("​%s;​ ", pStr); 
- if (!strcmp(pStr,​ REALAUDIO_MIME_TYPE)) audio_stream = stream_nbr; 
- if (!strcmp(pStr,​ REALVIDEO_MIME_TYPE)) video_stream = stream_nbr; 
-  
-        putchar('​}'​);​ 
-    } 
-    putchar('​\n'​);​ 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-int parse_cont(FILE *fp, unsigned int size, unsigned short version) 
-{    ​ 
-    unsigned int pos = ftell(fp) - 10; 
-    unsigned short len; 
-    char *pStr; 
-    int i; 
-  
-    printf("​\nCONT Detected @0x%x, size=%u, version = %d\n", pos, size, version); 
-    putchar('​\t'​);​ 
-    if (version == 0) 
-    {    ​ 
-        putchar('​{'​);​ 
-        putchar(0x20);​ 
-        for (i = 0; i < 4; i++) 
-        { 
-            if (rmvb_unpack16(fp,​ &len)) return -1; 
-            if (len) 
-            { 
-                pStr = (char *)malloc(len+1);​ 
-                if (pStr == NULL || fread(pStr, 1, len, fp) != len) return -1; 
-                pStr[len] = 0; 
-                printf("​%s;​ ", pStr); ​ 
-                free(pStr); 
-            } 
-        } 
-        putchar('​}'​);​ 
-    } 
-    putchar('​\n'​);​ 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-int parse_rmmd(FILE *fp, unsigned int size, unsigned short version) 
-{    ​ 
-    unsigned int pos = ftell(fp) - 10; 
-  
-    printf("​\nRMMD Detected @0x%x, size=%u, version = %d\n", pos, size, version); 
-  
-    fseek(fp, pos+size, SEEK_SET); 
-  
-    return 0; 
-} 
-  
-  
-void parse_rmvb(FILE *fp) 
-{ 
-    unsigned int id; 
-    unsigned int size; 
-    unsigned short version; 
-    int val; 
-  
-    for (;;) 
-    { 
-        if (parse_basic(fp,​ &id, &size, &​version) != 0) 
-            break; 
-        switch (id) 
-        { 
-            case MKTAG('​.',​ '​R',​ '​M',​ '​F'​):​ 
-                printf("​Real Media File Detected: size=%u, version = %d\n", size, version); 
-                if (rmvb_unpack32(fp,​ &val)) ERROR; 
-                printf("​File Version: %d\n", val); 
-                if (rmvb_unpack32(fp,​ &val)) ERROR; 
-                printf("​number of headers: %d\n", val); 
-                break; 
-            case MKTAG('​P',​ '​R',​ '​O',​ '​P'​):​ 
-                if (parse_prop(fp,​ size, version)) ERROR; 
-                break; 
-            case MKTAG('​M',​ '​D',​ '​P',​ '​R'​):​ 
-                if (parse_mdpr(fp,​ size, version)) ERROR; 
-                break; 
-            case MKTAG('​C',​ '​O',​ '​N',​ '​T'​):​ 
-                if (parse_cont(fp,​ size, version)) ERROR; 
-                break; 
-            case MKTAG('​D',​ '​A',​ '​T',​ '​A'​):​ 
-                if (parse_data(fp,​ size, version)) ERROR; 
-                break; ​   
-            case MKTAG('​I',​ '​N',​ '​D',​ '​X'​):​ 
-                if (parse_indx(fp,​ size, version)) ERROR; 
-                break; ​   ​ 
-            case MKTAG('​R',​ '​M',​ '​M',​ '​D'​):​ 
-                if (parse_rmmd(fp,​ size, version)) ERROR; 
-                break; ​                   ​ 
-            default: 
-                printf("​undefined tag found\n"​);​ 
-                fseek(fp, size-2, SEEK_CUR); 
-                break; 
-        } 
-    } 
-} 
-  
-int main(int argc, char** argv) 
-{ 
-    FILE *fp; 
-    long offset; 
-  
-    if (argc < 2) 
-    { 
-        printf("​please input file name\n"​);​ 
-        return 0; 
-    } 
-  
-    fp = fopen(argv[1],​ "​rb"​);​ 
-    if (fp == NULL) 
-    { 
-        printf("​error in openning file"​);​ 
-        return 0; 
-    } 
-    parse_rmvb(fp);​ 
-    fclose(fp);​  
-  
-    return 0; 
-} 
tech/multimedia/rmvb.txt ยท Last modified: 2014/11/10 08:22 (external edit)