if (!PKT1) return-1; PKT1->PKT = *PKT; Pkt1->next = NULL; Sdl_lockmutex (Q->mutex); To operate on Packetqueue, first lock the mutex variable if (!Q->LAST_PKT) Q->FIRST_PKT = PKT1; Else Q->last_pkt->next = PKT1; Q->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->FIRST_PKT = pkt1->next; if (!Q->FIRST_PKT) Q->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 (&PKT); if (quit) { return-1; } if (Packet_queue_get (&audioq, &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. |