User Tools

Site Tools


tech:multimedia:rmvb

Differences

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

Link to this comparison view

Next revision
Previous revision
tech:multimedia:rmvb [2011/01/07 08:56]
admin created
tech:multimedia:rmvb [2014/11/10 08:22] (current)
Line 2: Line 2:
 #include <​stdio.h>​ #include <​stdio.h>​
 #include <​stdlib.h>​ #include <​stdlib.h>​
 + 
 #define MKTAG(a,​b,​c,​d) (d | (c << 8) | (b << 16) | (a << 24)) #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 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) int rmvb_unpack32(FILE *fp, unsigned int *pVal)
 { {
     unsigned char buf[4];     unsigned char buf[4];
 + 
     if (fread(buf, 1, 4, fp) != 4)     if (fread(buf, 1, 4, fp) != 4)
     {     {
         return -1;         return -1;
     }     }
 + 
     *pVal = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3];     *pVal = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3];
     return 0;     return 0;
 } }
 + 
 int rmvb_unpack16(FILE *fp, unsigned short *pVal) int rmvb_unpack16(FILE *fp, unsigned short *pVal)
 { {
     unsigned char buf[2];     unsigned char buf[2];
 + 
     if (fread(buf, 1, 2, fp) != 2)     if (fread(buf, 1, 2, fp) != 2)
     {     {
         return -1;         return -1;
     }     }
 + 
     *pVal = (buf[0] << 8)|buf[1];     *pVal = (buf[0] << 8)|buf[1];
     return 0;     return 0;
 + 
 } }
 + 
 int rmvb_unpack8(FILE *fp, unsigned char *pVal) int rmvb_unpack8(FILE *fp, unsigned char *pVal)
 { {
     *pVal = (unsigned char) fgetc(fp);     *pVal = (unsigned char) fgetc(fp);
 + 
     if (feof(fp)) ​     if (feof(fp)) ​
         return -1;         return -1;
Line 43: Line 49:
         return 0;         return 0;
 } }
 + 
 int rmvb_unpack14or30(FILE *fp, unsigned int *pval, unsigned int *len) int rmvb_unpack14or30(FILE *fp, unsigned int *pval, unsigned int *len)
 { {
     unsigned short tmp1;     unsigned short tmp1;
     unsigned int tmp2;     unsigned int tmp2;
 + 
     if (rmvb_unpack16(fp,​ &tmp1)) return -1;     if (rmvb_unpack16(fp,​ &tmp1)) return -1;
     if (tmp1&​0x4000)     if (tmp1&​0x4000)
Line 62: Line 68:
         *len = 4;         *len = 4;
     }        }   
 + 
     return 0;     return 0;
 } }
 + 
 int parse_basic(FILE *fp, unsigned int *pId, unsigned int *pSize, unsigned short *pVersion) int parse_basic(FILE *fp, unsigned int *pId, unsigned int *pSize, unsigned short *pVersion)
 { {
     unsigned int size;     unsigned int size;
     unsigned short version;     unsigned short version;
 + 
     if (rmvb_unpack32(fp,​ pId))     if (rmvb_unpack32(fp,​ pId))
         return -1;         return -1;
Line 77: Line 83:
     if (rmvb_unpack16(fp,​ pVersion))     if (rmvb_unpack16(fp,​ pVersion))
         return -1;         return -1;
 + 
     return 0;     return 0;
 } }
 + 
 int parse_indx(FILE *fp, unsigned int size, unsigned short version) int parse_indx(FILE *fp, unsigned int size, unsigned short version)
 {    ​ {    ​
     unsigned int pos = ftell(fp) - 10;     unsigned int pos = ftell(fp) - 10;
 + 
     printf("​\nINDX Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​     printf("​\nINDX Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
 + 
 int parse_frame(FILE *fp, int size) int parse_frame(FILE *fp, int size)
 { {
Line 97: Line 103:
     unsigned short tmp1;     unsigned short tmp1;
     unsigned char type, seq, tmp2;     unsigned char type, seq, tmp2;
-    unsigned int size2, time, len;+    unsigned int size2, time, len, off;
     unsigned char packets, packet;     unsigned char packets, packet;
  
Line 103: Line 109:
     type = tmp1 >> 14;     type = tmp1 >> 14;
     fseek(fp, -2, SEEK_CUR);     fseek(fp, -2, SEEK_CUR);
 + 
     switch(type)     switch(type)
     {     {
 +     /* partial frame */
         case 0:         case 0:
         case 2:         case 2:
             if (rmvb_unpack16(fp,​ &tmp1)) return -1;             if (rmvb_unpack16(fp,​ &tmp1)) return -1;
-            if (rmvb_unpack14or30(fp,​ &size2, &len)) return -1; +            if (rmvb_unpack14or30(fp,​ &len, &size2)) return -1; 
-            if (rmvb_unpack14or30(fp,​ &size2, &len)) return -1;+            if (rmvb_unpack14or30(fp,​ &off, &size2)) return -1;
             if (rmvb_unpack8(fp,​ &seq)) return -1;             if (rmvb_unpack8(fp,​ &seq)) return -1;
             packets = ((tmp1 & 0x3F80) >> 7);             packets = ((tmp1 & 0x3F80) >> 7);
             packet = (tmp1 & 0x007F);             packet = (tmp1 & 0x007F);
             printf("​\t\t"​);​             printf("​\t\t"​);​
-            if (packet == 0) putchar('​{'​);​+            if (packet == 1) putchar('​{'​);​
             else putchar('​+'​);​             else putchar('​+'​);​
-            printf("​No.%d (%d-%d)",​ seq, packets, packet);+            printf("​No.%d (%d-%d), %d@%d", seq, packets, packet, off, len);
             if (packet == packets) putchar('​}'​);​             if (packet == packets) putchar('​}'​);​
             else putchar('​+'​);​             else putchar('​+'​);​
Line 143: Line 150:
                 fseek(fp, size2, SEEK_CUR);                 fseek(fp, size2, SEEK_CUR);
                 size -= size2;                 size -= size2;
-            ​}+ }
             break;             break;
         default:         default:
             break;             break;
     }     }
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
     return 0;     return 0;
 } }
 + 
 int parse_packet(FILE *fp) int parse_packet(FILE *fp)
 { {
Line 162: Line 169:
     unsigned short asm_rule;     unsigned short asm_rule;
     unsigned int pos = ftell(fp);     unsigned int pos = ftell(fp);
 + 
     if (rmvb_unpack16(fp,​ &​version)) return -1;     if (rmvb_unpack16(fp,​ &​version)) return -1;
     if (rmvb_unpack16(fp,​ &size)) return -1;     if (rmvb_unpack16(fp,​ &size)) return -1;
Line 178: Line 185:
     }     }
     printf("​stream#​%d,​ size=%d, time:​%d\n",​ stream, size, time);     printf("​stream#​%d,​ size=%d, time:​%d\n",​ stream, size, time);
- +  
-    if (parse_frame(fp,​ size-8-version)) return -1; +    ​if (stream == video_stream) 
-    ​+
 +        ​if (parse_frame(fp,​ size-12-version)) return -1; 
 +    ​}
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
     return 0;     return 0;
 } }
 + 
 int parse_data(FILE *fp, unsigned int size, unsigned short version) int parse_data(FILE *fp, unsigned int size, unsigned short version)
 {    {   
Line 191: Line 200:
     unsigned int pos = ftell(fp) - 10;     unsigned int pos = ftell(fp) - 10;
     int i;     int i;
 + 
     printf("​\nDATA Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​     printf("​\nDATA Detected @0x%x, size=%u, version = %d\n", pos, size, version); ​   ​
 + 
     if (rmvb_unpack32(fp,​ &​packets)) return -1;     if (rmvb_unpack32(fp,​ &​packets)) return -1;
     if (rmvb_unpack32(fp,​ &next)) return -1;     if (rmvb_unpack32(fp,​ &next)) return -1;
 + 
     for (i = 0; i < packets; i++)     for (i = 0; i < packets; i++)
     {     {
Line 203: Line 212:
         if (parse_packet(fp)) return -1;         if (parse_packet(fp)) return -1;
     }     }
 + 
     if (next)     if (next)
         fseek(fp, next, SEEK_SET);         fseek(fp, next, SEEK_SET);
     else     else
         fseek(fp, pos+size, SEEK_SET);         fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
- +  
 + 
 int parse_prop(FILE *fp, unsigned int size, unsigned short version) int parse_prop(FILE *fp, unsigned int size, unsigned short version)
 { {
Line 218: Line 227:
     unsigned int v32;     unsigned int v32;
     unsigned short v16;     unsigned short v16;
 + 
     printf("​\nPROP Detected @0x%x, size=%u, version = %d\n", pos, size, version);     printf("​\nPROP Detected @0x%x, size=%u, version = %d\n", pos, size, version);
     putchar('​\t'​);​     putchar('​\t'​);​
Line 247: Line 256:
     }     }
     putchar('​\n'​);​     putchar('​\n'​);​
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
 + 
 int parse_mdpr(FILE *fp, unsigned int size, unsigned short version) int parse_mdpr(FILE *fp, unsigned int size, unsigned short version)
 { {
Line 260: Line 269:
     unsigned char v8;     unsigned char v8;
     char pStr[256];     char pStr[256];
 + int stream_nbr = -1; 
 + 
     printf("​\nMDPR Detected @0x%x, size=%u, version = %d\n", pos, size, version);     printf("​\nMDPR Detected @0x%x, size=%u, version = %d\n", pos, size, version);
     putchar('​\t'​);​     putchar('​\t'​);​
Line 269: Line 279:
         if (rmvb_unpack16(fp,​ &v16)) return -1;         if (rmvb_unpack16(fp,​ &v16)) return -1;
         printf("​stream#​%d;​ ", v16);         printf("​stream#​%d;​ ", v16);
 + stream_nbr = v16;
         if (rmvb_unpack32(fp,​ &v32)) return -1;         if (rmvb_unpack32(fp,​ &v32)) return -1;
         printf("​bitrate:​ %u/", v32);         printf("​bitrate:​ %u/", v32);
Line 288: Line 299:
         pStr[v8]=0;         pStr[v8]=0;
         printf("​%s;​ ", pStr);         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('​}'​);​
     }     }
     putchar('​\n'​);​     putchar('​\n'​);​
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
 + 
 int parse_cont(FILE *fp, unsigned int size, unsigned short version) int parse_cont(FILE *fp, unsigned int size, unsigned short version)
 {    ​ {    ​
Line 304: Line 317:
     char *pStr;     char *pStr;
     int i;     int i;
 + 
     printf("​\nCONT Detected @0x%x, size=%u, version = %d\n", pos, size, version);     printf("​\nCONT Detected @0x%x, size=%u, version = %d\n", pos, size, version);
     putchar('​\t'​);​     putchar('​\t'​);​
Line 326: Line 339:
     }     }
     putchar('​\n'​);​     putchar('​\n'​);​
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
 + 
 int parse_rmmd(FILE *fp, unsigned int size, unsigned short version) int parse_rmmd(FILE *fp, unsigned int size, unsigned short version)
 {    ​ {    ​
     unsigned int pos = ftell(fp) - 10;     unsigned int pos = ftell(fp) - 10;
 + 
     printf("​\nRMMD Detected @0x%x, size=%u, version = %d\n", pos, size, version);     printf("​\nRMMD Detected @0x%x, size=%u, version = %d\n", pos, size, version);
 + 
     fseek(fp, pos+size, SEEK_SET);     fseek(fp, pos+size, SEEK_SET);
 + 
     return 0;     return 0;
 } }
- +  
 + 
 void parse_rmvb(FILE *fp) void parse_rmvb(FILE *fp)
 { {
Line 350: Line 363:
     unsigned short version;     unsigned short version;
     int val;     int val;
-    ​+ 
     for (;;)     for (;;)
     {     {
Line 389: Line 402:
     }     }
 } }
 + 
 int main(int argc, char** argv) int main(int argc, char** argv)
 { {
     FILE *fp;     FILE *fp;
     long offset;     long offset;
 + 
     if (argc < 2)     if (argc < 2)
     {     {
Line 409: Line 422:
     parse_rmvb(fp);​     parse_rmvb(fp);​
     fclose(fp);​      fclose(fp);​
- + 
     return 0;     return 0;
 } }
- 
 </​code>​ </​code>​
tech/multimedia/rmvb.1294390565.txt.gz · Last modified: 2014/11/10 08:35 (external edit)