文件分析并提取Packet中的PayloadData->NECHANDLEAVTransfer->NECHANDLEWMV->AUDIOOUTPUT按照驅(qū)動的API寫好代碼后卻怎么也沒有聲音,所有API返回值均OK。郁悶開始了。繼續(xù)絕望中尋找希望。為了對比調(diào)試,參考http://blog.csdn.net/ashlingr/article/details/7791321并做了一些f" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ffmpeg + sdl -03 簡單音頻播放器實現(xiàn)

系統(tǒng) 1748 0

沒辦法,工作中遇到了問題。


目前NEC EMMA的架構(gòu)如下:

從USB讀入文件 -> 文件分析并提取Packet中的Payload Data ? -> NEC HANDLE AVTransfer ?-> NEC HANDLE WMV -> AUDIO OUTPUT


按照驅(qū)動的API寫好代碼后卻怎么也沒有聲音,所有API返回值均OK。

郁悶開始了。繼續(xù)絕望中尋找希望。


為了對比調(diào)試,參考

http://blog.csdn.net/ashlingr/article/details/7791321


并做了一些ffmpeg版本升級修改。

修改前:

?

  1. len?=?avcodec_decode_audio?(pAudioCodecCtx,?? ?
  2. ????????????????????????????(int16_t?*)decompressed_audio_buf,? ?
  3. ????????????????????????????&decompressed_audio_buf_size,???????? //?it?is?the?decompressed?frame?in?BYTES?解碼后的數(shù)據(jù)大小,字節(jié)為單位; ?
  4. ????????????????????????????packet.data,? ?
  5. ????????????????????????????packet.size?); ?

?

?

修改后:

decompressed_audio_buf_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2; // 不加這一行,執(zhí)行時會出錯。

len = avcodec_decode_audio3 (pCodecCtx,?

? ? ? ? ? ? ? ? ? ? ? ? ? ? (int16_t *)decompressed_audio_buf,?

? ? ? ? ? ? ? ? ? ? ? ? ? ? &decompressed_audio_buf_size, ? ? ? ?// it is the decompressed frame in BYTES?

? ? ? ? ? ? ? ? ? ? ? ? ? ? &packet);?


遇到的問題:

/dev/dsp 設(shè)備不存在

解決辦法:

modprobe snd_pcm_oss ?(需要su到root用戶)


完整代碼如下:(基本來自 http://bbs.chinavideo.org/viewthread.php?tid=1247&extra=page%3D1

#include <avcodec.h>?
#include <avformat.h>?
#include <avutil.h>?
#include <assert.h>?
#include <stdio.h>?
#include <stdlib.h>?
#include <X11/Xlib.h>?
#include <sys/soundcard.h>?
#include <sys/stat.h>?
#include <fcntl.h>?
#include <sys/ioctl.h>?
#include <unistd.h>?
#include <errno.h>?
#include <string.h>?
#include <sched.h>?


#define ALL_DEBUG?


#ifdef ALL_DEBUG?
? ? #define AV_DEBUG?
? ? #define AUDIO_DEBUG?
#endif?


//------------------------------------------------------------------------------?
// manipulations for file?
int open_file (char *file_name, int mode)?
{?
? ? // open file file_name and return the file descriptor;?
? ? int fd;?


? ? if ((fd = open (file_name, mode)) < 0)?
? ? {?
? ? ? ? fprintf (stderr, " Can't open %s!/n", file_name);?
? ? ? ? exit (-1);?
? ? }?
? ? return fd;?
}?


int set_audio (int fd, AVCodecContext * pCodecCtx)?
{?
? ? // set the properties of audio device with pCodecCtx;?


? ? int i, err;?
? ? /* 設(shè)置適當?shù)膮?shù),使得聲音設(shè)備工作正常 */?
? ? /* 詳細情況請參考Linux關(guān)于聲卡編程的文檔 */?
? ?
? ? i = 0;?
? ? ioctl (fd, SNDCTL_DSP_RESET, &i);?
? ? i = 0;?
? ? ioctl (fd, SNDCTL_DSP_SYNC, &i);?
? ? i = 1;?
? ? ioctl (fd, SNDCTL_DSP_NONBLOCK, &i);?
? ?
? ? // set sample rate;?
? ? #ifdef AUDIO_DEBUG?
? ? printf ("pCodecCtx->sample_rate:%d/n", pCodecCtx->sample_rate);?
? ? #endif?
? ? i = pCodecCtx->sample_rate;?
? ? if (ioctl (fd, SNDCTL_DSP_SPEED, &i) == -1)?
? ? {?
? ? ? ? fprintf (stderr, "Set speed to %d failed:%s/n", i,?
? ? ? ? ? ? ?strerror (errno));?
? ? ? ? return (-1);?
? ? }?
? ? if (i != pCodecCtx->sample_rate)?
? ? {?
? ? ? ? fprintf (stderr, "do not support speed %d,supported is %d/n",?
? ? ? ? ? ? ?pCodecCtx->sample_rate, i);?
? ? ? ? return (-1);?
? ? }?
? ?
? ? // set channels;?
? ? i = pCodecCtx->channels;?
? ? #ifdef AUDIO_DEBUG?
? ? printf ("pCodecCtx->channels:%d/n", pCodecCtx->channels);?
? ? #endif?
? ? if ((ioctl (fd, SNDCTL_DSP_CHANNELS, &i)) == -1)?
? ? {?
? ? ? ? fprintf (stderr, "Set Audio Channels %d failed:%s/n", i,?
? ? ? ? ? ? ?strerror (errno));?
? ? ? ? return (-1);?
? ? }?
? ? if (i != pCodecCtx->channels)?
? ? {?
? ? ? ? fprintf (stderr, "do not support channel %d,supported %d/n",?
? ? ? ? ? ? pCodecCtx->channels, i);?
? ? ? ? return (-1);?
? ? }?
? ? // set bit format;?
? ? i = AFMT_S16_LE;?
? ? if (ioctl (fd, SNDCTL_DSP_SETFMT, &i) == -1)?
? ? {?
? ? ? ? fprintf (stderr, "Set fmt to bit %d failed:%s/n", i,?
? ? ? ? ? ? ?strerror (errno));?
? ? ? ? return (-1);?
? ? }?
? ? if (i != AFMT_S16_LE)?
? ? {?
? ? ? ? fprintf (stderr, "do not support bit %d, supported %d/n",?
? ? ? ? ? ? ?AFMT_S16_LE, i);?
? ? ? ? return (-1);?
? ? }?
? ?
? ? // set application buffer size;?
? ? // i = (0x00032 << 16) + 0x000c; ? ? ? ?// 32 4kb buffer;?
? ? // ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &i);?
? ? i = 1;?
? ? ioctl (fd, SNDCTL_DSP_PROFILE, &i);?
? ?
? ? return 0;?
}?


void close_file (int fd)?
{?
? ? // close the file pointed by file descriptor fd;?
? ? close (fd);?
}?


//------------------------------------------------------------------------------?
// handle audio;?


void display_AVCodecContext(AVCodecContext *pCodecCtx){?
? ? //?
? ? #define STDOUT stderr?
? ? fprintf(STDOUT, "pCodecCtx->bit_rate:%d/n", pCodecCtx->bit_rate);?
? ? fprintf(STDOUT, "pCodecCtx->sample_rate:%d/n", pCodecCtx->sample_rate);?
? ? fprintf(STDOUT, "pCodecCtx->channels:%d/n", pCodecCtx->channels);?
? ? fprintf(STDOUT, "pCodecCtx->frame_size:%d/n", pCodecCtx->frame_size);?
? ? fprintf(STDOUT, "pCodecCtx->frame_number:%d/n", pCodecCtx->frame_number);?
? ? fprintf(STDOUT, "pCodecCtx->delay:%d/n", pCodecCtx->delay);?
? ? fprintf(STDOUT, "pCodecCtx->frame_bits:%d/n", pCodecCtx->frame_bits);?
}?


// error if return -1;?
// success if return 0;?
// 這里要用到指向指針的指針,否則傳不到值;?
int av_init (char *file_name, AVFormatContext ** pFormatCtx,?
? ? ?AVCodecContext ** pCodecCtx, int *p_audioStream)?
{?
? ? // init the codec and format of input file file_name;?
? ? int audioStream, i;?
? ? AVCodec *pCodec;?
? ? // catch error?
? ? assert(file_name != NULL);?
? ? assert(*pFormatCtx != NULL);?
? ? assert(*pCodecCtx != NULL);?
? ?
? ? // Register all formats and codecs?
? ? av_register_all ();?
? ?
? ? // open file?
? ? if (av_open_input_file (pFormatCtx, file_name, NULL, 0, NULL) != 0){?
? ? ? ? // Couldn't open file?
? ? ? ? fprintf (stderr, " Can't open %s!/n", file_name);?
? ? ? ? return -1; ??
? ? }?


? ? // Retrieve stream information?
? ? if (av_find_stream_info (*pFormatCtx) < 0){?
? ? ? ? // Couldn't find stream information?
? ? ? ? return -1; ??
? ? }?
? ?
? ? #ifdef AV_DEBUG?
? ? // Dump information about file onto standard error?
? ? dump_format (*pFormatCtx, 0, file_name, 0);?
? ? #endif?
? ?
? ? // Find the first audio and video stream respectively?
? ? audioStream = -1;?
? ? for (i = 0; i < (*pFormatCtx)->nb_streams; i++){?
? ? ? ? if ((*pFormatCtx)->streams[i]->codec->codec_type ==?
? ? ? ? ? ? AVMEDIA_TYPE_AUDIO)?
? ? ? ? {?
? ? ? ? ? ? audioStream = i;?
? ? ? ? }?
? ? }?
? ?
? ? #ifdef AV_DEBUG?
? ? // dump_stream_info(pFormatCtx);?
? ? #endif?
? ?
? ? // exclude error?
? ? if (audioStream == -1){?
? ? ? ? // Didn't find a audio or video stream?
? ? ? ? return -1; ??
? ? }?


? ? // Get a pointer to the codec context for the audio stream?
? ? *pCodecCtx = (*pFormatCtx)->streams[audioStream]->codec;?


? ? // Find the decoder for the audio stream?
? ? pCodec = avcodec_find_decoder ((*pCodecCtx)->codec_id);?
? ? if (pCodec == NULL)?
? ? ? ? return -1; ? ?// Codec not found?


? ? // Open codec?
? ? if (avcodec_open ((*pCodecCtx), pCodec) < 0){?
? ? ? ? return -1; ? ?// Could not open codec?
? ? }?
? ?
? ? #ifdef AUDIO_DEBUG?
? ? // printf ("pCodecCtx->sample_rate:%d, audioStream:%d/n", (*pCodecCtx)->sample_rate, audioStream);?
? ? // display_AVCodecContext(*pCodecCtx);?
? ? #endif?
? ?
? ? *p_audioStream = audioStream;?
? ?
? ? return 0;?
}?


void av_play (AVFormatContext * pFormatCtx,?
? ? ?AVCodecContext * pCodecCtx, int audioStream)?
{?
? ? // which was read from one frame;?
? ? AVPacket packet;?
? ? uint32_t len;?
? ? uint8_t decompressed_audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];?
? ? int decompressed_audio_buf_size;?
? ? uint8_t * p_decompressed_audio_buf;?
? ? int fd = -1; ? ?// audio file or test file??
? ? char filename[64] = "/dev/dsp";?
? ? int mode = O_WRONLY;?
? ? //?
? ?
? ? // open audio file or written file?
? ? // printf("fd:%d", fd);?
? ? fd = open_file(filename, mode);?
? ? printf("fd:%d \n", fd);?
? ? //?
? ? set_audio(fd, pCodecCtx);?
? ?
? ? //?
? ? printf("(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2=%d\n", (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2);?
? ? printf("AVCODEC_MAX_AUDIO_FRAME_SIZE=%d\n", AVCODEC_MAX_AUDIO_FRAME_SIZE);?
? ?
? ? // for a test?
? ? // char test_file[256] = "my_pcm.pcm";?
? ? // fd = open_file(test_file, mode);?
? ?
? ? #ifdef AV_DEBUG?
? ? static int size = 0;?
? ? #endif?
? ? //?
? ?
? ? // set the sched priority?
? ? // 這是為了提高音頻優(yōu)先級;不曉得起作用沒;?
? ? int policy = SCHED_FIFO;?
? ? sched_setscheduler(0, policy, NULL);?
? ?
? ? int write_buf_size = 4196;?
? ? int written_size;?
? ? while (av_read_frame (pFormatCtx, &packet) >= 0)?
? ? {?
? ? ? ? // Is this a packet from the audio stream??
? ? ? ? // 判斷是否音頻幀;?
? ? ? ? if (packet.stream_index == audioStream)?
? ? ? ? {?
? ? ? ? ? ? // Decode audio frame?
? ? ? ? ? ? // 解碼音頻數(shù)據(jù)為pcm數(shù)據(jù);?
? ? ? ? ? ? decompressed_audio_buf_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
? ? ? ? ? ? len = avcodec_decode_audio3 (pCodecCtx,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? (int16_t *)decompressed_audio_buf,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? &decompressed_audio_buf_size, ? ? ? ?// it is the decompressed frame in BYTES?
? ? ? ? ? ? ? ? ? ? ? ? ? ? &packet);?
? ? ? ? ? ? // printf("len:%d, packet.size:%d/n", len, packet.size);?
? ? ? ? ? ? if ( len < 0 ){?
? ? ? ? ? ? ? ? // if error len = -1?
? ? ? ? ? ? ? ? printf("+----- error in decoding audio frame\n");?
? ? ? ? ? ? ? ? // exit(0);?
? ? ? ? ? ? }?
? ? ? ? ? ? // test lsosa?
? ? ? ? ? ?
? ? ? ? ? ?
? ? ? ? ? ? // printf("size = %d/n", size);?
? ? ? ? ? ? //******************************************************************?
? ? ? ? ? ? // 重點是這一部分,使用oss播放的代碼,之前的數(shù)據(jù)寫是否完整的問題就是出在這里,或者是前面的set_audio函數(shù)設(shè)置不正確;?
? ? ? ? ? ? // audio_buf_info info;?
? ? ? ? ? ? p_decompressed_audio_buf = decompressed_audio_buf;?
? ? ? ? ? ? while ( decompressed_audio_buf_size > 0 ){?
? ? ? ? ? ? ? ? // 解碼后數(shù)據(jù)不為零,則播放之,為零,則;?
? ? ? ? ? ? ? ? written_size = write(fd, p_decompressed_audio_buf, decompressed_audio_buf_size);?
? ? ? ? ? ? ? ? if ( written_size == -1 ){?
? ? ? ? ? ? ? ? ? ? // printf("error:decompressed_audio_buf_size:%d, decompressed_audio_buf_size:%d, %s/n", /?
? ? ? ? ? ? ? ? ? ? // ? ? ? ? ? ?decompressed_audio_buf_size, decompressed_audio_buf_size,strerror(errno));?
? ? ? ? ? ? ? ? ? ? // usleep(100);?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? // printf("decompressed_audio_buf_size:%d, written_size:%d/n", /?
? ? ? ? ? ? ? ? // ? ? ? ? ? decompressed_audio_buf_size, written_size);?
? ? ? ? ? ? ? ? decompressed_audio_buf_size -= written_size;?
? ? ? ? ? ? ? ? p_decompressed_audio_buf += written_size;?
? ? ? ? ? ? ? ?
? ? ? ? ? ? }// end while?
? ? ? ? ? ? //******************************************************************?
? ? ? ? }?
? ? ? ? else?
? ? ? ? {?
? ? ? ? ? ? printf("+----- this is not audio frame/n");?
? ? ? ? }// end if?
? ? ? ? // Free the packet that was allocated by av_read_frame?
? ? ? ? av_free_packet (&packet);?
? ? }// end while of reading one frame;?
? ? ? ?
? ? close_file(fd);?
}?


void av_close (AVFormatContext * pFormatCtx, AVCodecContext * pCodecCtx)?
{?
? ? // close the file and codec?


? ? // Close the codec?
? ? avcodec_close (pCodecCtx);?


? ? // Close the video file?
? ? av_close_input_file (pFormatCtx);?
}?


//------------------------------------------------------------------------------?


int main (int argc, char **argv){?
? ? //?
? ? AVFormatContext *pFormatCtx;?
? ? int audioStream = -1;?
? ? AVCodecContext *pCodecCtx;?
? ?
? ? // exclude the error about args;?
? ? if ( argc != 2 ){?
? ? ? ? printf("please give a file name\n");?
? ? ? ? exit(0);?
? ? }?
? ?
? ? // 注意:這里要用到指向指針的指針,是因為這個初始化函數(shù)需要對指針的地址進行改動,?
? ? // 所以,只有這么做,才能達到目的;?
? ? if ( av_init(argv[1], &pFormatCtx, &pCodecCtx, &audioStream) < 0 ){?
? ? ? ? //?
? ? ? ? fprintf(stderr, "error when av_init\n");?
? ? }?
? ?
? ? // play the audio file?
? ? av_play(pFormatCtx, pCodecCtx, audioStream);?
? ?
? ? // close all the opend files?
? ? av_close(pFormatCtx, pCodecCtx);?
? ?
}

?

ffmpeg + sdl -03 簡單音頻播放器實現(xiàn)


更多文章、技術(shù)交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美日韩毛片 | 婷婷综合在线观看丁香 | 欧美午夜精品久久久久免费视 | 奇米影视亚洲春色 | 中国日韩欧美中文日韩欧美色 | 在线观看一级毛片免费 | 亚洲国产精品a一区 | 日韩精品一区二区三区免费观看 | 精品久久久久久国产 | 欧美 亚洲 激情 | 成人午夜在线 | 69国产成人综合久久精品91 | 成人特黄午夜性a一级毛片 成人特级毛片69免费观看 | 99国产精品欧美久久久久久影院 | 久久久久久久国产精品视频 | 国产成人99 | 日韩中文字幕在线看 | 国产一国产一级毛片视频在线 | 欧洲性大片xxxxx久久久 | 天天插日日操 | 国产做人爱三级视频在线 | 激情 婷婷| 日韩在线看片中文字幕不卡 | 日韩欧美亚洲一区 | 色噜噜国产精品视频一区二区 | 黄色一级片免费网站 | 欧美日韩中文字幕久久伊人 | 国产精品久久久久久久久久久威 | 一区二区三 | 亚洲午夜天堂 | 国产欧美一区二区三区沐欲 | 国产偷国产偷亚洲高清在线 | 国产边打电话边被躁视频 | 精品国产三级 | 国产一区二区三区毛片 | xxx毛片| 久久精品美女 | 亚洲精品国产精品精 | 久久精品国产99久久香蕉 | 日本不卡高清免费v日本 | 99青草|