mais je l'ouvre dans le main en fait ...
Regarde ... (tout mon code, j'utilise visual C++, compilation nickel, faut juste mettre une video en chemin, et une video située dans la racine C:\mavideo.mpg sinon ça ne marche pas) :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h> // Bibliothèques utiles
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include <iostream.h>
#include <fstream.h>
#include <ctype.h>
#include <iomanip.h>
void find_TransportStream_synchro_bytes();
void press_key(char press_key_text[]); // Liste provisoire des prototypes de nos fonctions
void exit_prog(char error_msg[]); // --> à mettre dans un fichier header
unsigned int menu(void);
void menu_option1();
void menu_option2();
void TransportStream_header_decode();
void file_seek(int offset);
void display_transport_header(void);
void adaption_field(void);
struct TransportStream_header
{
unsigned char synchronisation_byte;
unsigned char transport_error_indicator;
unsigned char payload_start_indicator;
unsigned char transport_priority; // Structure de l'en-tête TS du flux MPEG
unsigned int PID;
unsigned char transport_scrambling_control;
unsigned char adaptation_field_control;
unsigned char continuity_counter;
} TransportStream_header;
char version[] = "1.00"; // Numéro de version
unsigned int current_header_add = 0; // Ajout d'une en-tête décodée/affichée
int index = 0; // index for found PID table
unsigned int search_PID = 0; // PID value to search for, from command line
long int payload_start = 0; // Ajout d'un payload_start si il est présent
char *ip_filepath; // Récupération de la ligne de commande
char synchro_bytes[10]; // Stockage des octets de synchronisation
int end_of_file = 0; // Vérification de la fin du fichier
unsigned char TS_raw_header[4]; // Espace de 4 octets pour lire les données du fichier
unsigned char adaption_field_length;
int ip_file_length;
int choix_menu;
FILE *ip_file;
char *Buffer;
//=======================Fonction-Principale=======================================================================================================================
int main(int argc, char *argv[])
{
puts ("\n\n================================");
puts ("Decodeur MPEG : TSdecode.exe");
printf("David Gombert Version : %s \n", version);
puts ("================================\n\n");
FILE *ip_file=NULL;
int i;
char ip_filepath[10000];
int ip_file_length=0; // Longueur du fichier
int size;
int end_of_file = 0;
if (argc == 1) //S'il n'y a pas d'argument, on demande à l'utilisateur d'entrer la chaine
{
printf("Entrer le chemin de la video:\n");
//scanf("%s",ip_filepath); //Attention n'accepte pas les espaces
gets(ip_filepath); //Accepte tout jusqu'à l'appuie sur entrée
}
else //entrée d'une chaine en argument du main (en passant par l'invite de commande)
{
strcpy(ip_filepath,&argv[1][0]); //ip_filepath pointe sur le premier argument, premier caractère
}
ip_file = fopen(ip_filepath, "rb"); // Ouverture du fichier MPEG en lecture seule ("rb"=read binary)
if(ip_file==NULL)
{
printf("Erreur : Impossible d'ouvrir le fichier spécifié \n"); //test d'ouverture du fichier
exit(0);
}
//system("pause");
fseek (ip_file , 0, SEEK_END); //On se place a la fin du fichier
ip_file_length=ftell (ip_file ); //Retourne le nombre d'octets depuis le début du fichier jusqu'à la position du curseur(ici la fin)
rewind (ip_file); //on se replace au début du fichier
printf("Ouverture du fichier MPEGx %s, contenant %ibytes...\n\n", ip_filepath, ip_file_length);
printf("Voici la liste des 100 premiers octets de ce flux MPEGx : \n\n\n");
char *Buffer=new char[ip_file_length];
size=(int)fread(Buffer,1,ip_file_length,ip_file); //TOUT le fichier est recopié dans le buffer
if(size != ip_file_length)
{
printf("Erreur lecture\n" );
exit(0);
}
//fclose(ip_file);
for(i=0;i<100;i++) //juste les 100 premiers
{
if((unsigned char)Buffer[i]<0x10)
{printf("0x0%x\n" , (unsigned char)Buffer[i]);}
else
{printf("0x%x\n" , (unsigned char)Buffer[i]);} //affichage des octets sous forme de caractère et NON en héxa -----> PROBLEME!!! --> résolu avec le cast
}
system("pause");
//printf("test1:\n");
//printf("0x%x \n",Buffer[101]);
//printf("0x%x \n",Buffer[289]);
//printf("0x%x \n",Buffer[477]);
//printf("0x%x \n",Buffer[665]);
//printf("0x%x \n",Buffer[853]);
//printf("0x%x \n",Buffer[1041]);
//printf("0x%x \n",Buffer[1229]);
//printf("0x%x \n",Buffer[1417]);
//printf("0x%x \n",Buffer[1605]);
//printf("0x%x \n",Buffer[1793]);
//printf("0x%x \n",Buffer[1981]);
//printf("0x%x \n",Buffer[2169]);
//printf("0x%x \n",Buffer[2357]);
//printf("0x%x \n",Buffer[2545]);
//system("pause");
//printf("\nVerification: affichage du premier octet de synchronisation: 0x%x \n" , (unsigned char)Buffer[101]);
//system("pause");
// Trouve les octets de synchronisation 0x47:
//find_TransportStream_synchro_bytes();
//================================================
// Trouve les octets de synchronisation 0x47:
char valeur=71;
int ordre=0;
for(i=0;i<1000;i++)
{
if((unsigned char)Buffer[i]==valeur)
{
ordre++;
synchro_bytes[ordre] = (unsigned char)Buffer[i];
printf("Octet de synchronisation numero %ld en position %ld dans le flux MPEG\n",ordre,i); // Fonction qui trouve les octets de synchronisation 0x47 à mettre au propre
//printf("%x\n",synchro_bytes[ordre]);
}
}
//================================================
system("pause");
printf("Test d'affichage des octets de synchro :\n");
printf("0x%x\n",synchro_bytes[1]);
printf("0x%x\n",synchro_bytes[2]);
printf("0x%x\n",synchro_bytes[3]);
system("pause");
// Retourne se placer au premier octet de synchronisation:
fseek(ip_file, synchro_bytes[1], 0);
// Menu utilisateur:
choix_menu = menu();
switch(choix_menu)
{
case'1':
menu_option1();
break;
case'2':
menu_option2();
break;
case'3':
exit_prog("");
break;
default:
puts("\nERREUR : Ceci n'est pas une entrée correcte");
}
//system("pause");
delete []Buffer;
exit_prog("");
return 0;
}
//========================================================================================================================================================================
void TransportStream_header_decode()
{
printf("\nSize of TS-header: %dbytes", sizeof(TS_raw_header));
current_header_add = ftell (ip_file);
fread(&TS_raw_header, sizeof(TS_raw_header), 1, ip_file); // Lecture de l'en-tête
//for (count=0; count <=sizeof(TS_raw_header); count++)
//printf("\nByte %d: \t \t x%x",count, TS_raw_header[count]);
// Utilisation de masques et décalages afin de récupérer les données que nous voulons dans l'en-tête:
TransportStream_header.synchronisation_byte = TS_raw_header[0];
TransportStream_header.transport_error_indicator = (TS_raw_header[1] & 0x80) >> 7;
TransportStream_header.payload_start_indicator = (TS_raw_header[1] & 0x40) >> 6;
TransportStream_header.transport_priority = (TS_raw_header[1] & 0x20) >> 5;
TransportStream_header.PID = ((TS_raw_header[1] & 31) << 8) | TS_raw_header[2];
TransportStream_header.transport_scrambling_control = (TS_raw_header[3] & 0xC0);
TransportStream_header.adaptation_field_control = (TS_raw_header[3] & 0x30) >> 4;
TransportStream_header.continuity_counter = (TS_raw_header[3] & 0xF);
}
//========================================================================================================================================================================
//void find_TransportStream_synchro_bytes()
//{
//int sync_data = 0; // Stockage des données lues provenant du fichier
//int nb_synchro_data = 0; // Savoir combien d'octets de synchro ont été trouvé
//long int current_file_pos = 0; // Position dans le fichier
//while ( !feof(ip_file) && nb_synchro_data < 2)
//{
//current_file_pos = ftell(ip_file); // Indique où nous sommes dans le fichier
//sync_data = 0;
//fread(&sync_data, 1, 1, ip_file); // Lecture du fichier à l'adresse
//switch (sync_data)
//{ // Si un octet de synchro est trouvé, il est stocker dans synchro_bytes[]
//case 0x47 :
//synchro_bytes[nb_synchro_data] = current_file_pos;
//nb_synchro_data++;
//file_seek(187); // Le prochain octet de synchro se trouve 187 octets plus loin d'après la norme MPEG (trame de 188 octets commençant par celui de synchro)
//break;
//default : // Si l'octet ne vaut pas 0x47...
//nb_synchro_data = 0;
//}
//}
//if ( nb_synchro_data < 2 )
//{ // Rapport d'erreur si eof avant d'avoir trouvé le nbre voulu d'octet de synchro
//exit_prog("Error: End of file reached before 5 sync_bytes found.");
//}
//}
//=====================================================================================================================================================================
void file_seek(int offset)
{
// Recherche les octets de fin de fichier, vérifie que ce n'est pas la fin
// On a en a besoin car la fction fseek peut chercher au-delà de la fin du fihcier sans reporter d'erreur
if ( ftell(ip_file) + (offset + 200) > ip_file_length )
{
end_of_file = 1;
// press_key("End of file");
}
else
fseek(ip_file, offset, 1);
}
//=====================================================================================================================================================================
void press_key(char press_key_text[])
{
printf("%s", press_key_text);
while ( !_kbhit() )
{;}
_getch();
}
//=====================================================================================================================================================================
void display_sync_byte_table()
{ // Affichage des octets de synchronisation
int count;
printf("\nTransport packet sync bytes found:");
printf("\nOccurance \t Address");
for (count=0; count < 6; count++)
printf("\n %d \t\t x%x", count, synchro_bytes[count]);
}
//====================================================================================================================================================================
void display_transport_header(void)
{ // Affichage de l'en-tête du TS et de quelques infos supp
printf("\nHeader address: \t x%x \t d%d",current_header_add, current_header_add);
printf("\nsynch_byte: \t \t x%x",TransportStream_header.synchronisation_byte);
printf("\t should be x47");
printf("\nError indicator: \t d%d",TransportStream_header.transport_error_indicator);
printf("\nPayload start: \t \t d%d",TransportStream_header.payload_start_indicator);
if (TransportStream_header.payload_start_indicator == 0x1)
printf("\t Payload is start of PID %d", TransportStream_header.PID);
printf("\nTans priority: \t \t d%d",TransportStream_header.transport_priority);
printf("\nPID: \t \t x%x \t d%d",TransportStream_header.PID, TransportStream_header.PID);
printf("\nScrambling: \t \t d%d",TransportStream_header.transport_scrambling_control);
if (TransportStream_header.transport_scrambling_control == 0x0)
printf("\t not scrambled");
printf("\nAdaption: \t \t d%d",TransportStream_header.adaptation_field_control);
if (TransportStream_header.adaptation_field_control == 0x01)
{ printf("\t no adaption field, payload only"); }
if (TransportStream_header.adaptation_field_control == 0x02)
{ printf("\t adaption field only, no payload");
adaption_field(); }
if (TransportStream_header.adaptation_field_control == 0x03)
{ printf("\t adaption field followed by payload");
adaption_field(); }
printf("\nContinuity: \t \t d%d",TransportStream_header.continuity_counter);
}
//====================================================================================================================================================================
void adaption_field(void)
{ // Trouve la longueur du adaptation_field
fread(&adaption_field_length, sizeof(adaption_field_length), 1, ip_file);
printf("\nAdaption length: \t d%d \t bytes", adaption_field_length);
// return file pointer
fseek (ip_file, -1, 1);
}
//====================================================================================================================================================================
void exit_prog(char error_msg[])
{
printf("\n%s\n", error_msg);
_fcloseall( );
press_key("Press a key to exit...");
exit(0);
}
//======================================================================================================================================================================
unsigned int menu(void)
{
char choix_menu;
puts("Menu:");
puts("1 - Decodage de l'en-tête");
puts("2 - Extraire le PES"); // Menu à développer avec de nouvelles options
puts("3 - Exit");
puts("\nEntrer_choix:");
scanf("%s", &choix_menu);
return choix_menu;
}
//=====================================================================================================================================================================
void menu_option1()
{
while ( end_of_file == 0 )
{
TransportStream_header_decode();
//if (TransportStream_header.PID == search_PID)
//{
display_transport_header();
//press_key("\nPress a key for next header or Control-C to exit.\n");
//}
file_seek(184);
}
puts("ERROR : End of file reached");
}
//========================================================================================================================================================================
void menu_option2(void)
{
printf("Looking for payload start of PID %d...", search_PID);
int payload_start_found = 0;
while ( end_of_file==0 )
{
TransportStream_header_decode();
//if (TransportStream_header.PID == search_PID)
//{
if ( payload_start_found == 0 && TransportStream_header.payload_start_indicator == 1)
{
payload_start = ftell(ip_file);
printf("\nPayload start found, header add: x%x", current_header_add);
payload_start_found = 1;
}
if ( payload_start_found == 1 )
{
//add_found_packet(); // nouvelle structure à définir
display_transport_header();
//display_pid_table(); // chercher un table contenant les principaux PID vidéo MPEG ????? à voir....
press_key("\nPress a key for next PID or Control-C to exit.\n");
}
//}
}
file_seek(184);
puts("\nERROR : End of file reached");
}