使用ffmpeg+SDL的简单播放器

http://blog.csdn.net/crazyman2010/article/details/8212470

 

使用ffmpeg+SDL的简单播放器,做了简单同步,还有许多问题,谨慎参考,直接上代码:

 

  1. #include "libavcodec/avcodec.h"  
  2. #include "libavformat/avformat.h"  
  3. #include "libswscale/swscale.h"  
  4. #include <stdio.h>  
  5. #include "SDL/SDL.h"  
  6. #include "SDL_thread.h"  
  7.   
  8. #define PICTURE_W 720  
  9. #define PICTURE_H 576  
  10. #define PICTURE_PW 720  
  11. #define PICTURE_PH 576  
  12.   
  13. #define MAX_QUEUE_SIZE 100  
  14. #define VIDEO_PICTURE_QUEUE_SIZE 2  
  15. typedef struct VideoPicture_t{  
  16.     SDL_Overlay *bmp;  
  17.     double pts;  
  18.     double duration;  
  19.     int width,height;  
  20. }VideoPicture;  
  21.   
  22.   
  23. struct play_info_t{  
  24.     double audio_clock;//解码时钟  
  25.     double audio_current_pts;//当前音频的pts  
  26.     double vedio_clock;//解码时钟  
  27.     double last_frame_pts;//上一帧的PTS值  
  28.     double last_frame_delay;//上一帧的延时  
  29.     double frame_timer;  
  30.       
  31.     AVCodecContext *pVideoCodecCtx;  
  32.     AVCodecContext *pAudioCodecCtx;  
  33.   
  34.     VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];  
  35.     int pictq_size, pictq_rindex, pictq_windex;  
  36.     SDL_mutex *pictq_mutex;  
  37.     SDL_cond *pictq_cond;  
  38.   
  39.     struct SwrContext *audio_conv;  
  40.     struct SwsContext *video_conv;  
  41. };  
  42.   
  43. struct play_info_t g_play_info;  
  44.   
  45.   
  46.   
  47.   
  48. typedef struct PacketQueue {  
  49.     AVPacketList *first_pkt, *last_pkt;  
  50.     int nb_packets;  
  51.     int size;  
  52.     SDL_mutex *mutex;  
  53.     SDL_cond *cond;  
  54. } PacketQueue;  
  55.   
  56. PacketQueue audio_queue;  
  57. PacketQueue video_queue;  
  58. int quit = 0;  
  59. SDL_Surface *screen;  
  60. SDL_Overlay *bmp;  
  61. SDL_Rect rect;  
  62.   
  63. int global_video_pkt_pts=0;  
  64. int our_get_buffer(struct AVCodecContext *c, AVFrame *pic) {  
  65.     int ret = avcodec_default_get_buffer(c, pic);  
  66.     uint64_t *pts = av_malloc(sizeof(uint64_t));  
  67.     *pts = global_video_pkt_pts;  
  68.     pic->opaque = pts;  
  69.     return ret;  
  70. }  
  71. void our_release_buffer(struct AVCodecContext *c, AVFrame *pic) {  
  72.     if(pic) av_freep(&pic->opaque);  
  73.     avcodec_default_release_buffer(c, pic);  
  74. }  
  75.   
  76. double get_audio_clock(void)  
  77. {  
  78.     return g_play_info.audio_current_pts;  
  79. }  
  80.   
  81. double get_video_clock(void)  
  82. {  
  83.     return g_play_info.vedio_clock;  
  84. }  
  85.   
  86. void picture_queque_init(struct play_info_t *play)  
  87. {  
  88.     int i;  
  89.     play->pictq_cond=SDL_CreateCond();  
  90.     play->pictq_mutex=SDL_CreateMutex();  
  91.     play->pictq_rindex=play->pictq_windex=0;  
  92.     play->pictq_size=0;  
  93.     memset(play->pictq,0,sizeof(play->pictq));  
  94.     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE;i++){  
  95.         play->pictq[i].bmp=SDL_CreateYUVOverlay(PICTURE_W,PICTURE_H,SDL_YUY2_OVERLAY,screen);  
  96.     }  
  97. }  
  98.   
  99. void picture_queque_destroy(struct play_info_t *play)  
  100. {  
  101.     int i;  
  102.     for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE;i++){  
  103.         SDL_FreeYUVOverlay(play->pictq[i].bmp);  
  104.     }  
  105. }  
  106.   
  107.   
  108.   
  109. void packet_queue_init(PacketQueue *q) {  
  110.     memset(q, 0, sizeof(PacketQueue));  
  111.     q->mutex = SDL_CreateMutex();  
  112.     q->cond = SDL_CreateCond();  
  113. }  
  114.   
  115. int packet_queue_put(PacketQueue *q, AVPacket *pkt) {  
  116.     AVPacketList *pkt1;  
  117.     if(av_dup_packet(pkt) < 0) {  
  118.         return -1;  
  119.     }  
  120.     pkt1 = av_malloc(sizeof(AVPacketList));  
  121.     if (!pkt1)  
  122.         return -1;  
  123.     pkt1->pkt = *pkt;  
  124.     pkt1->next = NULL;  
  125.     SDL_LockMutex(q->mutex);  
  126.     if (!q->last_pkt)  
  127.         q->first_pkt = pkt1;  
  128.     else  
  129.         q->last_pkt->next = pkt1;  
  130.     q->last_pkt = pkt1;  
  131.     q->nb_packets++;  
  132.     q->size += pkt1->pkt.size;  
  133.     SDL_CondSignal(q->cond);  
  134.     SDL_UnlockMutex(q->mutex);  
  135.     return 0;  
  136. }  
  137.   
  138.   
  139. static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) {  
  140.     AVPacketList *pkt1;  
  141.     int ret;  
  142.     SDL_LockMutex(q->mutex);  
  143.     for(;;) {  
  144.         if(quit) {  
  145.             ret = -1;  
  146.             break;  
  147.         }  
  148.         pkt1 = q->first_pkt;  
  149.         if (pkt1) {  
  150.             q->first_pkt = pkt1->next;  
  151.             if (!q->first_pkt)  
  152.                 q->last_pkt = NULL;  
  153.             q->nb_packets--;  
  154.             q->size -= pkt1->pkt.size;  
  155.             *pkt = pkt1->pkt;  
  156.             av_free(pkt1);  
  157.             ret = 1;  
  158.             break;  
  159.         } else if (!block) {  
  160.             ret = 0;  
  161.             break;  
  162.         } else {  
  163.             SDL_CondWait(q->cond, q->mutex);  
  164.         }  
  165.     }  
  166.     SDL_UnlockMutex(q->mutex);  
  167.     return ret;  
  168. }  
  169.   
  170. int decode_interrupt_cb(void) {  
  171.     return quit;  
  172. }  
  173.   
  174. //计算正确的pts值  
  175. double sync_video(struct play_info_t *play,AVFrame* frame,double pts)  
  176. {  
  177.     double frame_delay;  
  178.     if(pts!=0)  
  179.         play->vedio_clock=pts;  
  180.     else  
  181.         pts=play->vedio_clock;  
  182.     frame_delay=av_q2d(play->pVideoCodecCtx->time_base);//一帧占用的时间  
  183.     frame_delay+=frame->repeat_pict*(frame_delay*0.5);//计算重复帧  
  184.     play->vedio_clock+=frame_delay;  
  185.     return pts;  
  186. }  
  187.   
  188. int audio_decode_frame(struct play_info_t* play, uint8_t *audio_buf,int buf_size) {  
  189.     AVCodecContext *aCodecCtx=play->pAudioCodecCtx;  
  190.     AVFrame *pAudioFrame=avcodec_alloc_frame();  
  191.     AVPacket pkt,pkt1;  
  192.     int frame_finished=0;  
  193.     int pkt_pos,pkt_len;  
  194.     int src_len=0,dst_len=0,data_size=0;  
  195.     float pts=0;  
  196.     avcodec_get_frame_defaults(pAudioFrame);  
  197.   
  198.     uint8_t *out[]={audio_buf};  
  199.       
  200.     for(;!quit;){  
  201.         if(packet_queue_get(&audio_queue, &pkt, 1) < 0) {  
  202.             av_free(pAudioFrame);  
  203.             return -1;  
  204.         }  
  205.         pkt1=pkt;  
  206.         pkt_pos=0;  
  207.         pkt_len=pkt.size;  
  208.           
  209.         while(pkt_pos<pkt.size && !quit){  
  210.             if((src_len=avcodec_decode_audio4(aCodecCtx,pAudioFrame,&frame_finished,&pkt1))<0){  
  211.                 av_free_packet(&pkt);  
  212.                 av_free(pAudioFrame);  
  213.                 return -1;  
  214.             }  
  215.               
  216.             play->audio_clock+=(double)(pAudioFrame->linesize[0])/  
  217.                 (aCodecCtx->channels*aCodecCtx->sample_rate*av_get_bytes_per_sample(aCodecCtx->sample_fmt));  
  218.               
  219.             if(frame_finished){  
  220.                 int len=swr_convert(play->audio_conv,out,buf_size/aCodecCtx->channels/av_get_bytes_per_sample(AV_SAMPLE_FMT_S16),  
  221.                     pAudioFrame->data,pAudioFrame->linesize[0]/aCodecCtx->channels/av_get_bytes_per_sample(pAudioFrame->format));  
  222.                 len=len*aCodecCtx->channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);  
  223.                 av_free(pAudioFrame);  
  224.                 av_free_packet(&pkt);  
  225.                 return len;  
  226.             }else{  
  227.                 if (!pkt1.data && aCodecCtx->codec->capabilities & CODEC_CAP_DELAY){  
  228.                     break;  
  229.                 }  
  230.             }  
  231.             pkt_pos+=src_len;//已经解码的长度  
  232.             pkt1.data=pkt.data+pkt_pos;  
  233.             pkt1.size=pkt.size-pkt_pos;  
  234.         }  
  235.         av_free_packet(&pkt);  
  236.     }  
  237.     av_free(pAudioFrame);  
  238.     return dst_len;  
  239. }  
  240.   
  241. //decode the audio data ,and copy the result to stream  
  242. void SDLCALL audio_callback(void *userdata, Uint8 *stream, int len)  
  243. {  
  244.     struct play_info_t *play=(struct play_info_t*)userdata;  
  245.     AVCodecContext *aCodecCtx = play->pAudioCodecCtx;  
  246.     int len1, audio_size;  
  247.     static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];  
  248.     static unsigned int audio_buf_size = 0;  
  249.     static unsigned int audio_buf_index = 0;  
  250.     int bytes_per_sec=2*aCodecCtx->channels*aCodecCtx->sample_rate;  
  251.       
  252.     while(len > 0 && !quit) {  
  253.         if(audio_buf_index >= audio_buf_size) {  
  254.             audio_size = audio_decode_frame(play, audio_buf,sizeof(audio_buf));  
  255.             if(audio_size < 0) {  
  256.                 audio_buf_size = 1024;  
  257.                 memset(audio_buf, 0, audio_buf_size);  
  258.             } else {  
  259.                 audio_buf_size = audio_size;  
  260.             }  
  261.             audio_buf_index = 0;  
  262.         }  
  263.         len1 = audio_buf_size - audio_buf_index;  
  264.           
  265.         if(len1 > len)  
  266.             len1 = len;  
  267.         memcpy(stream, (uint8_t *)audio_buf + audio_buf_index, len1);  
  268.         len -= len1;  
  269.         stream += len1;  
  270.         audio_buf_index += len1;  
  271.     }  
  272.     if(audio_buf_size > audio_buf_index){  
  273.         play->audio_current_pts=play->audio_clock-((double)(audio_buf_size-audio_buf_index)/(double)bytes_per_sec);  
  274.         if(play->audio_current_pts<0)  
  275.             play->audio_current_pts=play->audio_clock;  
  276.         //printf("audio-pts:%f\n",play->audio_current_pts);  
  277.     }  
  278. }  
  279.   
  280. int SDLCALL video_decode_callback(void* arg)  
  281. {  
  282.     printf("---in video decode thread ---\n");  
  283.     struct play_info_t* play=(struct play_info_t*)arg;  
  284.     AVCodecContext *pVideoCodecCtx=play->pVideoCodecCtx;  
  285.     double pts;  
  286.     VideoPicture *vp;  
  287.     AVPacket pkt;  
  288.     int frame_finished;  
  289.     AVPicture pict = { { 0 } };  
  290.     AVFrame *pVideoFrame=avcodec_alloc_frame();  
  291.     if(pVideoFrame==NULL){  
  292.         printf("can't alloc video frame!\n");  
  293.         return -1;  
  294.     }  
  295.   
  296.     while(!quit){  
  297.         if(packet_queue_get(&video_queue, &pkt, 1) < 0) {  
  298.             return -1;  
  299.         }  
  300.         pts = 0;  
  301.         // Save global pts to be stored in pFrame in first call  
  302.         global_video_pkt_pts = pkt.pts;  
  303.         avcodec_decode_video2(pVideoCodecCtx,pVideoFrame,&frame_finished,&pkt);  
  304.         if(pkt.dts == AV_NOPTS_VALUE && pVideoFrame->opaque && *(uint64_t*)pVideoFrame->opaque != AV_NOPTS_VALUE){  
  305.             pts = *(uint64_t *)pVideoFrame->opaque;  
  306.         } else if(pkt.dts!=AV_NOPTS_VALUE){  
  307.             pts=pkt.dts;  
  308.         }else{  
  309.             pts=0;  
  310.         }  
  311.         pts*=av_q2d(pVideoCodecCtx->time_base);  
  312.       
  313.         av_free_packet(&pkt);  
  314.         if(frame_finished){  
  315.             SDL_LockMutex(play->pictq_mutex);  
  316.             while(play->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !quit){  
  317.                 SDL_CondWait(play->pictq_cond,play->pictq_mutex);  
  318.             }  
  319.             SDL_UnlockMutex(play->pictq_mutex);  
  320.             if(quit)  
  321.                 goto out;  
  322.               
  323.             vp=&play->pictq[play->pictq_windex];  
  324.             SDL_Overlay *bmp=vp->bmp;  
  325.             //序列化帧  
  326.             pts=sync_video(&g_play_info,pVideoFrame,pts);  
  327.             vp->pts=pts;  
  328.             //printf("video-pts:%f\n",pts);  
  329.               
  330.             SDL_LockYUVOverlay(bmp);  
  331.             pict.data[0]=bmp->pixels[0];  
  332.             pict.data[1]=bmp->pixels[2];  
  333.             pict.data[2]=bmp->pixels[1];  
  334.             pict.linesize[0]=bmp->pitches[0];  
  335.             pict.linesize[1]=bmp->pitches[2];  
  336.             pict.linesize[2]=bmp->pitches[1];  
  337.             sws_scale(play->video_conv,pVideoFrame->data,pVideoFrame->linesize,0,  
  338.                 pVideoFrame->height,pict.data,pict.linesize);  
  339.             SDL_UnlockYUVOverlay(bmp);  
  340.   
  341.   
  342.             play->pictq_windex=(play->pictq_windex+1)%VIDEO_PICTURE_QUEUE_SIZE;  
  343.             SDL_LockMutex(play->pictq_mutex);  
  344.             play->pictq_size++;  
  345.             SDL_UnlockMutex(play->pictq_mutex);  
  346.               
  347.         }  
  348.     }  
  349. out:  
  350.     av_free(pVideoFrame);  
  351.     printf("---- exit video_decode_callback ----\n");  
  352.     return 0;  
  353. }  
  354.   
  355. void video_image_display(struct play_info_t *play)  
  356. {  
  357.     double delay,time;  
  358.     VideoPicture *vp;  
  359.     double diff,sync_threshold;  
  360.     if(play->pictq_size>0){  
  361.         vp=&play->pictq[play->pictq_rindex];  
  362.         delay=vp->pts - play->last_frame_pts;  
  363.         if(delay>0 && delay<10){  
  364.             play->last_frame_delay=delay;  
  365.         }  
  366.         delay=play->last_frame_delay;  
  367.           
  368.         diff=vp->pts-get_audio_clock();  
  369.         sync_threshold = FFMAX(0.01, delay);  
  370.         if (fabs(diff) < 10) {  
  371.             if (diff <= -sync_threshold)  
  372.                 delay = 0;  
  373.             else if (diff >= sync_threshold)  
  374.                 delay = 2 * delay;  
  375.         }  
  376.   
  377.         time=av_gettime()/1000000.0;  
  378.         if(time < play->frame_timer+delay)  
  379.             return ;  
  380.           
  381.         if(delay>0)  
  382.             play->frame_timer+=delay;  
  383.         play->last_frame_pts=vp->pts;  
  384.   
  385.         SDL_DisplayYUVOverlay(vp->bmp,&rect);  
  386.   
  387.         play->pictq_rindex=(play->pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE;  
  388.   
  389.         SDL_LockMutex(play->pictq_mutex);  
  390.         play->pictq_size--;  
  391.         SDL_CondSignal(play->pictq_cond);  
  392.         SDL_UnlockMutex(play->pictq_mutex);  
  393.           
  394.     }  
  395. }  
  396.   
  397. int SDLCALL video_show_callback(void* arg)  
  398. {  
  399.     double delay=5000;  
  400.     struct play_info_t *play=(struct play_info_t*)arg;  
  401.     while(!quit){  
  402.         video_image_display(play);  
  403.         usleep(delay);  
  404.     }  
  405.     printf("----exit video_show_callback ----\n");  
  406.     return 0;  
  407. }  
  408.   
  409. void player_log_callback(void* ptr, int level, const char* fmt, va_list vl)  
  410. {  
  411.     static int print_prefix = 0;  
  412.     static int count;  
  413.     char line[1024];  
  414.     av_log_format_line(ptr, level, fmt, vl, line, sizeof(line), &print_prefix);  
  415.     printf("%s",line);  
  416. }  
  417.   
  418.   
  419.   
  420.   
  421. int main(int argc,char *argv[])  
  422. {  
  423.     if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)<0){  
  424.         printf("Init SDL err!\n");  
  425.         return -1;  
  426.     }  
  427.   
  428.     av_log_set_callback(player_log_callback);  
  429.     av_register_all();  
  430.   
  431.     AVFormatContext *pFormatCtx;  
  432.     pFormatCtx=avformat_alloc_context();  
  433.     if(avformat_open_input(&pFormatCtx,argv[1],NULL,NULL)<0){  
  434.         printf("avformat_open_input err!\n");  
  435.         return -1;  
  436.     }  
  437.   
  438.     if(avformat_find_stream_info(pFormatCtx,NULL)<0){  
  439.         printf("avformat_find_stream_info err!\n");  
  440.         return -1;  
  441.     }  
  442.   
  443.     //av_dump_format(pFormatCtx,0,argv[1],0);  
  444.       
  445.     int video_stream=-1,audio_stream=-1,i;  
  446.     for(i=0;i<pFormatCtx->nb_streams;i++){  
  447.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){  
  448.             video_stream=i;  
  449.         }  
  450.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){  
  451.             audio_stream=i;  
  452.         }  
  453.     }  
  454.     if(video_stream==-1 || audio_stream==-1){  
  455.         printf("not find video or audio stream!\n");  
  456.         avformat_close_input(&pFormatCtx);  
  457.         return -1;  
  458.     }  
  459.     g_play_info.pVideoCodecCtx=pFormatCtx->streams[video_stream]->codec;  
  460.     g_play_info.pAudioCodecCtx=pFormatCtx->streams[audio_stream]->codec;  
  461.   
  462.     //find the decoder  
  463.     AVCodec *pVideoCodec=avcodec_find_decoder(g_play_info.pVideoCodecCtx->codec_id);  
  464.     if(pVideoCodec==NULL){  
  465.         printf("not find video decoder!\n");  
  466.         avformat_close_input(&pFormatCtx);  
  467.         return -1;  
  468.     }  
  469.     AVCodec *pAudioCodec=avcodec_find_decoder(g_play_info.pAudioCodecCtx->codec_id);  
  470.     if(pVideoCodec==NULL){  
  471.         printf("not find audio decoder!\n");  
  472.         avformat_close_input(&pFormatCtx);  
  473.         return -1;  
  474.     }  
  475.     //open the codec  
  476.     if(avcodec_open(g_play_info.pVideoCodecCtx,pVideoCodec)<0){  
  477.         printf("can't open the video decoder!\n");  
  478.         avformat_close_input(&pFormatCtx);  
  479.         return -1;  
  480.     }  
  481.     if(avcodec_open(g_play_info.pAudioCodecCtx,pAudioCodec)<0){  
  482.         printf("can't open the audio decoder!\n");  
  483.         avcodec_close(g_play_info.pVideoCodecCtx);  
  484.         avformat_close_input(&pFormatCtx);  
  485.         return -1;  
  486.     }  
  487.   
  488.     //setup SDL  
  489.     screen=SDL_SetVideoMode(PICTURE_W,PICTURE_H,0,0);  
  490.     picture_queque_init(&g_play_info);  
  491.     packet_queue_init(&video_queue);  
  492.     packet_queue_init(&audio_queue);  
  493.       
  494.     rect.x=0;  
  495.     rect.y=0;  
  496.     rect.w=PICTURE_W;  
  497.     rect.h=PICTURE_H;  
  498.   
  499.   
  500.     //setup the sdl audio  
  501.     SDL_AudioSpec sdl_audio;  
  502.     int64_t wanted_channel_layout = 0;  
  503.     int wanted_nb_channels;  
  504.     wanted_channel_layout =   
  505.         (g_play_info.pAudioCodecCtx->channel_layout &&   
  506.         g_play_info.pAudioCodecCtx->channels == av_get_channel_layout_nb_channels(g_play_info.pAudioCodecCtx->channel_layout)) ? g_play_info.pAudioCodecCtx->channel_layout : av_get_default_channel_layout(g_play_info.pAudioCodecCtx->channels);  
  507.     wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;  
  508.     wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);  
  509.     /* SDL only supports 1, 2, 4 or 6 channels at the moment, so we have to make sure not to request anything else. */  
  510.     while (wanted_nb_channels > 0 && (wanted_nb_channels == 3 || wanted_nb_channels == 5 || wanted_nb_channels > 6)) {  
  511.         wanted_nb_channels--;  
  512.         wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);  
  513.     }  
  514.     sdl_audio.channels=av_get_channel_layout_nb_channels(wanted_channel_layout);  
  515.     g_play_info.pAudioCodecCtx->channels=sdl_audio.channels;  
  516.     g_play_info.pAudioCodecCtx->channel_layout=wanted_channel_layout;  
  517.       
  518.     g_play_info.audio_conv=swr_alloc_set_opts(NULL,wanted_channel_layout,AV_SAMPLE_FMT_S16,g_play_info.pAudioCodecCtx->sample_rate,  
  519.         wanted_channel_layout,g_play_info.pAudioCodecCtx->sample_fmt,  
  520.         g_play_info.pAudioCodecCtx->sample_rate,0,NULL);  
  521.     swr_init(g_play_info.audio_conv);  
  522.       
  523.     sdl_audio.freq=g_play_info.pAudioCodecCtx->sample_rate;  
  524.     sdl_audio.format=AUDIO_S16SYS;  
  525.     sdl_audio.channels=g_play_info.pAudioCodecCtx->channels;  
  526.     sdl_audio.silence=0;  
  527.     sdl_audio.samples=1024;  
  528.     sdl_audio.callback=audio_callback;//calls when the audio device need more data  
  529.     sdl_audio.userdata=&g_play_info;  
  530.     if(SDL_OpenAudio(&sdl_audio,NULL)<0){  
  531.         printf("can't open audio device!\n");  
  532.         goto err_alloc_frame1;  
  533.     }  
  534.   
  535.     g_play_info.vedio_clock=0;  
  536.     g_play_info.audio_clock=0;  
  537.     g_play_info.audio_current_pts=0;  
  538.     g_play_info.last_frame_pts=0;  
  539.     g_play_info.last_frame_delay=0;  
  540.     g_play_info.frame_timer=av_gettime()/1000000.0;  
  541.     g_play_info.pVideoCodecCtx->get_buffer=our_get_buffer;  
  542.     g_play_info.pVideoCodecCtx->release_buffer=our_release_buffer;  
  543.       
  544.     SDL_PauseAudio(0);  
  545.   
  546.     //create video decode thread  
  547.         //setup the converter  
  548.       
  549.     g_play_info.video_conv=sws_getContext(g_play_info.pVideoCodecCtx->width,g_play_info.pVideoCodecCtx->height,  
  550.         g_play_info.pVideoCodecCtx->pix_fmt,  
  551.         PICTURE_PW,PICTURE_PH,PIX_FMT_YUYV422,SWS_POINT,NULL,NULL,NULL);  
  552.     SDL_Thread * video_decode_thread=SDL_CreateThread(video_decode_callback,(void*)&g_play_info);  
  553.     SDL_Thread * video_show_thread=SDL_CreateThread(video_show_callback,(void*)&g_play_info);  
  554.     //start to decode  
  555.     SDL_Event sdl_event;  
  556.     AVPacket packet;  
  557.   
  558.   
  559.       
  560.     while(!quit){  
  561.         SDL_PollEvent(&sdl_event);  
  562.         if(sdl_event.type==SDL_QUIT){  
  563.             SDL_CondSignal(video_queue.cond);  
  564.             SDL_CondSignal(audio_queue.cond);  
  565.             quit=1;  
  566.             break;  
  567.         }  
  568.         if(video_queue.nb_packets>=MAX_QUEUE_SIZE || audio_queue.nb_packets>=MAX_QUEUE_SIZE){  
  569.             //printf("%d---%d\n",video_queue.nb_packets,audio_queue.nb_packets);  
  570.             usleep(10000);  
  571.             continue;  
  572.         }  
  573.         if(av_read_frame(pFormatCtx,&packet)<0){  
  574.             quit=1;  
  575.             continue;  
  576.         }  
  577.         if(packet.stream_index==video_stream){  
  578.             packet_queue_put(&video_queue,&packet);  
  579.         }else if(packet.stream_index==audio_stream){  
  580.             packet_queue_put(&audio_queue,&packet);  
  581.         }else{  
  582.             av_free_packet(&packet);  
  583.         }  
  584.           
  585.         //usleep(5000);  
  586.     }  
  587.     SDL_CloseAudio();  
  588.     SDL_CondSignal(g_play_info.pictq_cond);  
  589.     SDL_WaitThread(video_decode_thread,NULL);  
  590.     SDL_WaitThread(video_show_thread,NULL);  
  591.     picture_queque_destroy(&g_play_info);  
  592.   
  593.     swr_free(&g_play_info.audio_conv);  
  594.     sws_freeContext(g_play_info.video_conv);  
  595.   
  596.     SDL_FreeSurface(screen);  
  597.     avcodec_close(g_play_info.pVideoCodecCtx);  
  598.     avcodec_close(g_play_info.pAudioCodecCtx);  
  599.     avformat_close_input(&pFormatCtx);  
  600.     return 0;  
  601.   
  602. err_alloc_frame1:  
  603.     avcodec_close(g_play_info.pAudioCodecCtx);  
  604.     avcodec_close(g_play_info.pVideoCodecCtx);  
  605.     avformat_close_input(&pFormatCtx);  
  606.     return -1;  
  607. }  

 

posted @ 2013-09-29 00:05  myblogszz  Views(331)  Comments(0)    收藏  举报