diff src/aac/aac_utils.c @ 1929:64bcd7c9c705

Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author Kiyoshi Aman <kiyoshi.aman@gmail.com>
date Mon, 01 Oct 2007 05:56:16 -0500
parents eed7c270e8dd
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aac/aac_utils.c	Mon Oct 01 05:56:16 2007 -0500
@@ -0,0 +1,99 @@
+/*
+ *
+ * utils for AAC informations
+*/
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define ADTS_HEADER_SIZE        8
+#define SEEK_TABLE_CHUNK        60
+#define MPEG4_TYPE              0
+#define MPEG2_TYPE              1
+
+// Read ADTS header, the file descriptor must be at
+// the begining of the aac frame not at the id3tag
+
+int	getAacInfo(FILE *fd)
+{
+  unsigned char	header[ADTS_HEADER_SIZE];
+  unsigned int	id;
+  unsigned long	originPosition;
+  
+  originPosition = ftell(fd);
+  if(fread(header, 1, ADTS_HEADER_SIZE, fd) != ADTS_HEADER_SIZE){
+    fseek(fd, originPosition, SEEK_SET);
+    return(-1);
+  }
+  if(!((header[0]==0xFF)&&((header[1]& 0xF6)==0xF0))){
+    printf("Bad header\n");
+    return(-1);
+  }
+  id = header[1]&0x08;
+  if(id==0){//MPEG-4 AAC
+    fseek(fd, originPosition, SEEK_SET);
+    return(MPEG4_TYPE);
+  }else{
+    fseek(fd, originPosition, SEEK_SET);
+    return(MPEG2_TYPE);
+  }
+  fseek(fd, originPosition, SEEK_SET);
+  return(-1);
+}
+
+// as AAC is VBR we need to check all ADTS header
+// to enable seeking...
+// there is no other solution
+void	checkADTSForSeeking(FILE *fd,
+			    unsigned long **seekTable,
+			    unsigned long *seekTableLength)
+{
+  unsigned long	originPosition;
+  unsigned long	position;
+  unsigned int	frameCount, frameLength, frameInsec;
+  unsigned int	id=0, seconds=0;
+  char header[ADTS_HEADER_SIZE];
+
+  originPosition = ftell(fd);
+
+  for(frameCount=0,frameInsec=0;; frameCount++,frameInsec++){
+    position = ftell(fd);
+    if(fread(header, 1, ADTS_HEADER_SIZE, fd)!=ADTS_HEADER_SIZE){
+      break;
+    }
+    if(!g_strncasecmp(header, "ID3", 3)){
+      break;
+    }
+    if(!frameCount){
+      id=header[1]&0x08;
+      if(((*seekTable) = malloc(SEEK_TABLE_CHUNK * sizeof(unsigned long)))==0){
+	printf("malloc error\n");
+	return;
+      }
+      (*seekTableLength) = SEEK_TABLE_CHUNK;
+    }
+
+    //if(id==0){//MPEG-4
+    //frameLength = ((unsigned int)header[4]<<5)|((unsigned int)header[5]>>3);
+    //}else{//MPEG-2
+      frameLength = (((unsigned int)header[3]&0x3)<<11)|((unsigned int)header[4]<<3)|(header[5]>>5);
+      //}
+    if(frameInsec==43){//???
+      frameInsec=0;
+    }
+    if(frameInsec==0){
+      if(seconds == (*seekTableLength)){
+	(*seekTable) = realloc((*seekTable), (seconds+SEEK_TABLE_CHUNK)*sizeof(unsigned long));
+	(*seekTableLength) = seconds+SEEK_TABLE_CHUNK;
+      }
+      (*seekTable)[seconds] = position;
+      seconds++;
+    }
+    if(fseek(fd, frameLength-ADTS_HEADER_SIZE, SEEK_CUR)==-1){
+      break;
+    } 
+  }
+  (*seekTableLength) = seconds;
+  fseek(fd, originPosition, SEEK_SET);
+}