SDL Audio Playback

Source: Internet
Author: User

Gcc-o tutorial03 tutorial03.c-lavutil-lavformat-lavcodec-lz-lm \
' Sdl-config--cflags--libs '

Audio noun Explanation:
Samples: Sampling, sampling by PCM, usually sample 16BIT,PCM from 14-bit to 16-bit, 18-bit, 20-bit to 24-bit
Samples Rate: Sample rate, 22.05KHz and 44.1KHz, number of samples per second extracted from continuous signal and composed of discrete signals
Bit rate: Sample rate * Sample bit* channel number, uncompressed audio bit rate on CD is 1411.2 kbit/s (16 bit/Sample point x44100 Sample Point/sec x2 Channel)

Pformatctx->streams[i]->codec->codec_type==codec_type_audio, find the index of Audiostream in the For loop i
Avcodeccontext *acodecctx=pformatctx->streams[audiostream]->codec; Get the audio encoded information

Sdl_audiospec Wanted_spec,spec;
Wanted_spec.freq = acodecctx->sample_rate; Sample Rate
Wanted_spec.format = Audio_s16sys;
Tell SDL what format to use, s refer to signed,16 for sample 16bit,sys size driven by system decision
Wanted_spec.channels = acodecctx->channels; How many channels are there?
wanted_spec.silence = 0; Silence value, because it is signed, it is 0
Wanted_spec.samples = 1024; Cache size
Wanted_spec.callback = Audio_callback; callback function for audio

Wanted_spec.userdata = Acodecctx; Data to be processed by the callback function
Sdl_openaudio (&wanted_spec, &spec)
Return-1 fails to open, spec is null to play in Wanted_spec specified mode, if spec is not NULL, it is played according to the spec specified by hardware change, and wanted_spec can be deleted

Vcodec *acodec = Avcodec_find_decoder (acodecctx->codec_id);
Avcodec_open (Acodecctx, Acodec);
Find the decoder and decode it

typedef struct PACKETQUEUE {
Avpacketlist *first_pkt, *LAST_PKT;
int nb_packets; Is the total number of packages
int size; For the size of all packages
Sdl_mutex *mutex; Mutual exclusion Lock
Sdl_cond *cond; Condition variable
} Packetqueue;
The data structures we created ourselves to build the packet queue

Avpacketlist
A simple linked list for packets.
Avpacket PKT
Avpacketlist * Next

void Packet_queue_init (Packetqueue *q)
{

memset (q,0,sizeof (packetqueue));
Q->mutex = Sdl_createmutex ();
Q->cond=sdl_createcond ();
}

Initialize the PACKETQUEUE data structure

Functions for filling packages into packetqueue data structures
int Packet_queue_put (packetqueue *q,avpacket *pkt)
{
Avpacketlist *PKT1;
if (Av_dup_packet (PKT) <0)
{
return-1; Checks whether null, or null, fills itself, otherwise returns-1
}
PKT1 = Av_malloc (sizeof (avpacketlist));//Allocate space for Avpacketlist

if (!PKT1)
return-1;
PKT1-&GT;PKT = *PKT;
Pkt1->next = NULL;
Sdl_lockmutex (Q->mutex); To operate on Packetqueue, first lock the mutex variable
if (!Q-&GT;LAST_PKT)
Q-&GT;FIRST_PKT = PKT1;
Else
Q->last_pkt->next = PKT1;
Q-&GT;LAST_PKT = PKT1;
q->nb_packets++;
Q->size + = pkt1->pkt.size;
Sdl_condsignal (Q->cond); Send conditional signals to wake up where data is waiting
Sdl_unlockmutex (Q->mutex); Unlock
return 0;
}

Receive data
static int Packet_queue_get (Packetqueue *q, Avpacket *pkt, int block)
{
Avpacketlist *PKT1;
int ret;
Sdl_lockmutex (Q->mutex);//Lock Mutex
for (;;)
{
if (quit)
{
RET =-1;
Break
}
pkt1=q->first_pkt;
if (PKT1) {
Q-&GT;FIRST_PKT = pkt1->next;
if (!Q-&GT;FIRST_PKT)
Q-&GT;LAST_PKT = NULL;
q->nb_packets--;
Q->size-= pkt1->pkt.size;
*PKT = pkt1->pkt;
Av_free (PKT1);
ret = 1;
Break
}
else if (!block) {
ret = 0;
Break
}
else {
Sdl_condwait (Q->cond, Q->mutex);
}
}
Sdl_unlockmutex (Q->mutex);
return ret;
}
Sdl_condwait detects whether the condition is met, if not satisfied, unlocks the mutex,wait until it is notified by the sdl_condsignal () function or the Sdl_condbroadcast () function, locks the mutex and returns

void Sdl_pauseaudio (int pause_on)
Control playback and Pause when pause_on is 0 o'clock, play the data if the data is not ready, then play mute

The callback function to play, the format must be void callback (void *userdata, Uint8 *stream, int len), where UserData is our pointer to SDL, stream is the buffer pointer we want to write the sound data to, Len is the size of the buffer.
void Audio_callback (void *userdata, Uint8 *stream, int len) {

struct MyData *data= (struct mydata*) UserData;
Avcodeccontext *acodecctx = (Avcodeccontext *) data->pformatctx;
Packetqueue *audioq=data->audioq;
int len1, audio_size;
static data in order to be able to call the callback function multiple times, and not necessarily processing the data
Static uint8_t audio_buf[(Avcodec_max_audio_frame_size * 3)/2];
Audio_buf size is 1.5 times times the size of the sound frame to make it easier to have a better buffer
static unsigned int audio_buf_size = 0;
static unsigned int audio_buf_index = 0;

while (Len > 0) {
if (Audio_buf_index >= audio_buf_size) {

Audio_size = Audio_decode_frame (Acodecctx, Audio_buf,
sizeof (AUDIO_BUF));
if (Audio_size < 0) {

Audio_buf_size = 1024;
memset (audio_buf, 0, audio_buf_size);
} else {
Audio_buf_size = audio_size;
}
Audio_buf_index = 0;
}
Len1 = Audio_buf_size-audio_buf_index;
if (Len1 > Len)
Len1 = Len;
memcpy (Stream, (uint8_t *) Audio_buf + audio_buf_index, len1);
Len-= len1;
Stream + = Len1;
Audio_buf_index + = Len1;
}
}

Decoding the audio data, the decoded data exists in Audio_buf, Buf_size tells the function Audio_buf buffer how large, the return value is the number of decoded data, the end returns 1, otherwise the number of decoded bytes is returned.
int Audio_decode_frame (Avcodeccontext *acodecctx, uint8_t *audio_buf,
int Buf_size,packetqueue *audioq) {

Static Avpacket pkt;
static uint8_t *audio_pkt_data = NULL;
static int audio_pkt_size = 0;
int len1, data_size;
for (;;) {
while (Audio_pkt_size > 0) {//The loop starts at the end
Data_size = buf_size; Avcodec_decode_audio2 must first specify the output buffer size
Len1 = Avcodec_decode_audio2 (Acodecctx, (int16_t *) audio_buf, &data_size, Audio_pkt_data, audio_pkt_size);

Decode the data
if (Len1 < 0) {

audio_pkt_size = 0;
Break
}
Audio_pkt_data + = Len1;
Audio_pkt_size-= len1; static data, there may be multiple frames inside the package, so the next call continues
if (data_size <= 0) {

Continue
}

return data_size;
}
if (Pkt.data)
Av_free_packet (&AMP;PKT);
if (quit) {
return-1;
}
if (Packet_queue_get (&audioq, &AMP;PKT, 1) < 0) {
return-1;
}
Audio_pkt_data = Pkt.data;
Audio_pkt_size = pkt.size;
}
}

int Avcodec_decode_audio2 (Avcodeccontext *avctx, int16_t *samples, int *frame_size_ptr, uint8_t *buf, int buf_size)
The output is samples, if there is no frame_size_ptr that can be decoded returns 0, otherwise it is the decoded size. You must allocate the cache size of frame_size_ptr to samples when you call the function.
Returns a negative number as an error, which returns the decoded bytes or 0 indicating not being decoded.
The input buffer must be ff_input_buffer_padding_size larger than the actual read bytes because some optimized bitstream R Eaders read or the bits at once and could read over the end. The end of the input buffer buf should is set to 0 to ensure, that is no overreading happens for damaged MPEG streams.
Note:you might has to align the input buffer buf and output buffer samples. The alignment requirements depend on the Cpu:on some CPUs it is ' t necessary at all, on others it won ' t work at all if no T aligned and on others it'll work but it'll have a impact on performance. In practice, the bitstream should has 4 byte alignment at minimum and all sample data should is + byte aligned unless th E CPU doesn ' t need it (ALTIVEC and SSE do). If The linesize is not a multiple of a, then there's no sense in aligning the start of the buffer to 16.

SDL Audio Playback

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.