Claudio Bertozzi a écrit :
hallo,
could someone tell me if  is possible and how to read and decode an audio
and/or video AVPacket from a previous created list of AVPacket read from a
file instead that read directly with av_read_frame function called frame
after frame?
yes, you can store all packets in a list and read whatever packet you want in that list after (if your AvCodecCtx is correctly initialized) I join a test program I made from various examples I fouded, it's really basic and full of bugs but it was just to test to separate reading / decoding / and playing step and is only made for audio.
in a first step it read all packets and store into a buffer
in a second step it read all stored packets, decode them and save audio samples into another buffer
and at last it play the decoded audio buffer using OSS


My problem is that after stored all the frame in a list of packets, when I
grab one and pass it at the av_decode... functions, they returned me an
error and never decode the frames.
check if you AvCodecCtx is correctly initialized
I suppose that the av_read_... and/or av_decode_... functions write some
infos in the AVFormatContext or AVCodecContext functions after the read and
decode of a packet. If that is true, what can I do to tell at the structures
to decode the correct packet in my sequence?

I hope to have not made too much mess in the description of my problem.
Please write some feedback ;)
bye

claudio
I hope that help
Yvan
/// \Description : lecture d'un fichier audio decode grace a libavcodec/format et joue via OSS
///	 	
///		V1 : lecture en 3 etapes : 	1) extraction des paquets encodes vers un buffer indexe
///									2) decodage des paquets du buffer vers un autre buffer (qui contiendra donc les echantillons audio decodes)
///									3) lecture des echantillons depuis le buffer audio vers OSS
///
/// \Author : Yvan LABADIE
#include <stdio.h>
#include <iostream>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <vector.h>

extern "C" {
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}

void audio_decode_example(const char *outfilename, const char *filename);

using namespace std;

typedef struct frame_t {
	unsigned int size;
	unsigned char *data;
}frame_t;

////////////////////// VARIABLES ///////////////////////
short 				audio_buffer[8*1024*1024]; //buffer pour stocker les echantillons audio decodes
short 				samples[AVCODEC_MAX_AUDIO_FRAME_SIZE];    //samples audio decodes correspondant a un paquet audio encode
AVFormatContext 	*pFormatCtx;
AVCodecContext  	*pACodecCtx;
AVCodec         	*pACodec;
int             	numBytes;
int             	i;
int					audioStream;
double         	 	aFrameRate;
short 				*buf_ptr;
vector<frame_t> 	frames;
AVPacket 			pkt;
int 				len;
int 				data_size;
unsigned char 		*ptr;
unsigned char 		buffer[4*1024*1024]; //buffer pour stocker les paquets audio encodes
long int 			frame_ptr=0;
long int 			seek_pos=0;
int 				ret;
long int 			timeStamp;
long int 			pos;
int 				duration;  
int 				arg;   
int 				status;
int 				fd;    
short 				*se;    // samples pour encoder une frame MP3
unsigned long int 	write_ptr = 0;
unsigned long int 	read_ptr = 0;
	

/////////////////////////////////////////////////////////
inline void OSSinit() {
	//// Sortie Audio, on utilise OSS pour simplifier les choses
	puts("openning audio device");
	fd = open("/dev/dsp", O_RDWR, O_SYNC);
	if (fd < 0) {
		perror("open of /dev/dsp failed");
		exit(1);
	}
  
	arg = 16; //16 bits
	status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
	if (status == -1)
		perror("SOUND_PCM_WRITE_BITS ioctl failed");
	if (arg != 16)
		perror("unable to set sample size");
  
	arg = 2; //Stereo
	status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
	if (status == -1)
		perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
	if (arg != 2)
		perror("unable to set number of channels");
  
	arg = 44000; //44000Hz
	status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
	if (status == -1)
		perror("SOUND_PCM_WRITE_WRITE ioctl failed");
	////////////////////////////////////////////////////////
	puts("audio device open");
}

/////////////////////////////////////////////////////////
inline void openFile(char * file) {
	avcodec_init(); //initialize codecs manager (ffmpeg)
    av_register_all(); // Register all formats and codecs
	puts("ffmpeg initialized");
    
	// Open media file
    status = av_open_input_file(&pFormatCtx, file, NULL, 0, NULL);
	
    if(status!=0){
		printf("[ERR (%i)]cannot open input file [%s]\n",status, file);
        exit(-1); // Couldn't open file
    }

    // Retrieve stream information
    if(av_find_stream_info(pFormatCtx)<0) {
		puts("cannot find stream info");
        exit(-1); // Couldn't find stream information
	}
	puts("dump format...");
    // Dump information about file onto standard error
    dump_format(pFormatCtx, 0, file, false);
	puts("find stream...");
    // Find the first audio stream
	audioStream=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++) {
        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
            aFrameRate = av_q2d(pFormatCtx->streams[i]->r_frame_rate);
            audioStream=i;
            break;
        }
	}
	
	printf("channels = %i | sample rate = %d | bitrate = %d | bit per sample = %i\n", pFormatCtx->streams[audioStream]->codec->channels, pFormatCtx->streams[audioStream]->codec->sample_rate, pFormatCtx->streams[audioStream]->codec->bit_rate, pFormatCtx->streams[audioStream]->codec->bits_per_coded_sample);
	printf("packet size= %i\n", pFormatCtx->packet_size);
    if(audioStream==-1) {
		puts("[ERR]Didn't find an audio stream");
        exit(-1);
	}

    // Get a pointer to the codec context for the video stream
    pACodecCtx=pFormatCtx->streams[audioStream]->codec;

    // Find the decoder for the audio stream
    pACodec=avcodec_find_decoder(pACodecCtx->codec_id);
    if(pACodec==NULL) {
		puts("[ERR]audio codec NOT FOUNDED");
        exit(-1); // Codec not found
	}

    // Ouvre le codec
    if(avcodec_open(pACodecCtx, pACodec)<0) {
		puts("[ERR] openning Codec");
        exit(-1);
	}
}

/////////////////////////////////////////////////////////
inline void readFrames() {
	//lecture fichier => enregistrement des paquets dans un buffer et indexation
	puts("we're gonna read some frames");
	frames.empty();
	frame_t newFrame;
	//ret = av_seek_frame(pFormatCtx, audioStream, 0, 0/*AVSEEK_FLAG_BYTE*/);
	while(1) {
		if(av_read_frame(pFormatCtx, &pkt)<0) {
			puts("Read ERROR");
			exit(-1);
		}
		
		ptr = pkt.data;
        len = pkt.size;
		timeStamp = pkt.pts;
		pos = pkt.pos;
		//printf("TS[%li] | pos=%li | readed len = %i\n", timeStamp, pos, len);
		
		if(pkt.stream_index==audioStream){
			newFrame.size = len;
			newFrame.data = &buffer[write_ptr];
			frames.push_back(newFrame);
			
			for (i=0 ; i<len ; i++) {
				buffer[write_ptr] = *ptr;
				write_ptr++;
				if(write_ptr >= 1*1024*1024) {
					puts ("buffer FULL!");
					break; //on s'embete pas avec le buffer circulaire juste pour le test...
				}
				ptr++;
			}
		}
		
		if(write_ptr >= 1*1024*1024 ) {
			break; //on s'embete pas avec le buffer circulaire juste pour le test...
		}
	}
	puts("fichier lu");
}

/////////////////////////////////////////////////////////
inline void decode() {
	puts("decode...");
	//decodage avec index des paquets
	buf_ptr = audio_buffer;
	for (i=0 ; i< 400; i++) {
		ptr = frames[i].data;
		len = frames[i].size;
		while(len>0) {    // Tant que tout n'a pas ete decode
			data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
			ret = avcodec_decode_audio2(pACodecCtx, samples, &data_size, (const uint8_t*)(ptr), len);
			printf("ret = %i | data_size = %i\n", ret, data_size);
			if(ret<0) {
				puts("decode error");
				break;
			}
			len-=ret;
			ptr+=ret;
			if (data_size > 0) {                 
				for (int j=0 ; j< data_size>>1 ; j++) {
					*buf_ptr = samples[j];
					buf_ptr++;
				}
			}
		}
	}
}

/////////////////////////////////////////////////////////
inline void playAudio() {
	//lecture des echantillons audio
	char * aud_ptr;
	aud_ptr = (char *)audio_buffer;
	i=0;
	int wrote;
	do {
		wrote = write(fd, aud_ptr, 512); // if a frame has been decoded, output it
		if (wrote > 0) {
			aud_ptr+=wrote;
		}
		i++;
	} while (aud_ptr<(char *)buf_ptr);
}

/////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
	OSSinit();
	openFile(argv[1]);
	readFrames();
	decode();
	playAudio();
	
	//////////////////////// exit stuff...
    close(fd);
    avcodec_close(pACodecCtx);
    av_close_input_file(pFormatCtx);
    return 0;
}
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to