音视频流::ffplay::tutorial05 .

来源:互联网 发布:format在vb是什么意思 编辑:程序博客网 时间:2024/05/29 19:09

转自:

http://blog.chinaunix.net/uid-24203478-id-3179828.html

 

所用的版本为ffmpeg 0.6.3

编译命令:
gcc -o tutorial05 tutorial05.c -lavformat -lavcodec -lz -lm -lswscale `sdl-config --cflags --libs`

 

  1. #include <libavcodec/avcodec.h>   
  2.   
  3. #include <libavformat/avformat.h>   
  4.   
  5. #include <libswscale/swscale.h>   
  6.   
  7.     
  8.   
  9. #include <SDL.h>    
  10.   
  11. #include <SDL_thread.h>    
  12.   
  13.     
  14.   
  15. #include <stdio.h>    
  16.   
  17. #include <math.h>    
  18.   
  19.     
  20.   
  21. #define SDL_AUDIO_BUFFER_SIZE 1024   
  22.   
  23. #define MAX_AUDIOQ_SIZE (5 * 6 * 1024)   
  24.   
  25. #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)   
  26.   
  27.     
  28.   
  29. #define AV_SYNC_THRESHOLD 0.01   
  30.   
  31. #define AV_NOSYNC_THRESHOLD 10.0   
  32.   
  33.     
  34.   
  35. #define FF_ALLOC_EVENT (SDL_USEREVENT)   
  36.   
  37. #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)   
  38.   
  39. #define FF_QUIT_EVENT (SDL_USEREVENT + 2)   
  40.   
  41.     
  42.   
  43. #define VIDEO_PICTURE_QUEUE_SIZE 1   
  44.   
  45.     
  46.   
  47.     
  48.   
  49. typedef struct PacketQueue {   
  50.   
  51.   AVPacketList *first_pkt, *last_pkt;   
  52.   
  53.   int nb_packets;   
  54.   
  55.   int size;   
  56.   
  57.   SDL_mutex *mutex;   
  58.   
  59.   SDL_cond *cond;   
  60.   
  61. } PacketQueue;   
  62.   
  63.     
  64.   
  65. typedef struct VideoPicture {   
  66.   
  67.   SDL_Overlay *bmp;   
  68.   
  69.   int width, height;   
  70.   
  71.   int allocated;   
  72.   
  73.   double pts;   
  74.   
  75. } VideoPicture;   
  76.   
  77.     
  78.   
  79. typedef struct VideoState {   
  80.   
  81.   AVFormatContext *pFormatCtx;   
  82.   
  83.   int videoStream, audioStream;   
  84.   
  85.   double audio_clock;   
  86.   
  87.   AVStream *audio_st;   
  88.   
  89.   PacketQueue audioq;   
  90.   
  91.   uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];   
  92.   
  93.   unsigned int audio_buf_size;   
  94.   
  95.   unsigned int audio_buf_index;   
  96.   
  97.   AVPacket audio_pkt;   
  98.   
  99.   uint8_t *audio_pkt_data;   
  100.   
  101.   int audio_pkt_size;   
  102.   
  103.   int audio_hw_buf_size;   
  104.   
  105.   double frame_timer;   
  106.   
  107.   double frame_last_pts;   
  108.   
  109.   double frame_last_delay;   
  110.   
  111.   double video_clock;   
  112.   
  113.   AVStream *video_st;   
  114.   
  115.   PacketQueue videoq;   
  116.   
  117.   VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];   
  118.   
  119.   int pictq_size, pictq_rindex, pictq_windex;   
  120.   
  121.   SDL_mutex *pictq_mutex;   
  122.   
  123.   SDL_cond *pictq_cond;   
  124.   
  125.   SDL_Thread *parse_tid;   
  126.   
  127.   SDL_Thread *video_tid;   
  128.   
  129.   char filename[1024];   
  130.   
  131.   int quit;   
  132.   
  133.   struct SwsContext *img_convert_ctx;   
  134.   
  135. } VideoState;   
  136.   
  137.     
  138.   
  139. SDL_Surface *screen;   
  140.   
  141.     
  142.   
  143. VideoState *global_video_state;   
  144.   
  145.     
  146.   
  147. void packet_queue_init(PacketQueue *q) {   
  148.   
  149.   memset(q, 0, sizeof(PacketQueue));   
  150.   
  151.   q->mutex = SDL_CreateMutex();   
  152.   
  153.   q->cond = SDL_CreateCond();   
  154.   
  155. }   
  156.   
  157.     
  158.   
  159. int packet_queue_put(PacketQueue *q, AVPacket *pkt) {   
  160.   
  161.   AVPacketList *pkt1;   
  162.   
  163.   if(av_dup_packet(pkt) < 0) {   
  164.   
  165.     return -1;   
  166.   
  167.   }   
  168.   
  169.   pkt1 = av_malloc(sizeof(AVPacketList));   
  170.   
  171.   if (!pkt1) {   
  172.   
  173.     return -1;   
  174.   
  175.   }   
  176.   
  177.   pkt1->pkt = *pkt;   
  178.   
  179.   pkt1->next = NULL;   
  180.   
  181.     
  182.   
  183.   SDL_LockMutex(q->mutex);   
  184.   
  185.     
  186.   
  187.   if (!q->last_pkt) {   
  188.   
  189.     q->first_pkt = pkt1;   
  190.   
  191.   } else {   
  192.   
  193.     q->last_pkt->next = pkt1;   
  194.   
  195.   }   
  196.   
  197.   q->last_pkt = pkt1;   
  198.   
  199.   q->nb_packets++;   
  200.   
  201.   q->size += pkt1->pkt.size;   
  202.   
  203.   SDL_CondSignal(q->cond);   
  204.   
  205.     
  206.   
  207.   SDL_UnlockMutex(q->mutex);   
  208.   
  209.   return 0;   
  210.   
  211. }   
  212.   
  213.     
  214.   
  215. static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) {   
  216.   
  217.   AVPacketList *pkt1;   
  218.   
  219.   int ret;   
  220.   
  221.   SDL_LockMutex(q->mutex);   
  222.   
  223.   for(;;) {   
  224.   
  225.     if (global_video_state->quit) {   
  226.   
  227.       ret = -1;   
  228.   
  229.       break;   
  230.   
  231.     }   
  232.   
  233.     pkt1 = q->first_pkt;   
  234.   
  235.     if (pkt1) {   
  236.   
  237.       q->first_pkt = pkt1->next;   
  238.   
  239.       if (!q->first_pkt) {   
  240.   
  241.     q->last_pkt = NULL;   
  242.   
  243.       }   
  244.   
  245.       q->nb_packets--;   
  246.   
  247.       q->size -= pkt1->pkt.size;   
  248.   
  249.       *pkt = pkt1->pkt;   
  250.   
  251.       av_free(pkt1);   
  252.   
  253.       ret = 1;   
  254.   
  255.       break;   
  256.   
  257.     } else if (!block) {   
  258.   
  259.       ret = 0;   
  260.   
  261.       break;   
  262.   
  263.     } else {   
  264.   
  265.       SDL_CondWait(q->cond, q->mutex);   
  266.   
  267.     }   
  268.   
  269.   }   
  270.   
  271.   SDL_UnlockMutex(q->mutex);   
  272.   
  273.   return ret;   
  274.   
  275. }   
  276.   
  277.     
  278.   
  279. double get_audio_clock(VideoState *is) {   
  280.   
  281.     double pts;   
  282.   
  283.     int hw_buf_size, bytes_per_sec, n;   
  284.   
  285.     
  286.   
  287.     pts = is->audio_clock;   
  288.   
  289.     hw_buf_size = is->audio_buf_size - is->audio_buf_index;   
  290.   
  291.     bytes_per_sec = 0;   
  292.   
  293.     n = is->audio_st->codec->channels * 2;   
  294.   
  295.     if (is->audio_st) {   
  296.   
  297.         bytes_per_sec = is->audio_st->codec->sample_rate * n;   
  298.   
  299.     }   
  300.   
  301.     if (bytes_per_sec) {   
  302.   
  303.         pts -= (double)hw_buf_size / bytes_per_sec;   
  304.   
  305.     }   
  306.   
  307.     return pts;   
  308.   
  309. }   
  310.   
  311.     
  312.   
  313. int audio_decode_frame(VideoState*is, uint8_t *audio_buf, int buf_size, double *pts_ptr) {   
  314.   
  315.   int len1, data_size, n;   
  316.   
  317.   AVPacket *pkt = &is->audio_pkt;   
  318.   
  319.   double pts;   
  320.   
  321.       
  322.   
  323.   for (;;) {   
  324.   
  325.     while (is->audio_pkt_size > 0) {   
  326.   
  327.       data_size = buf_size;   
  328.   
  329.       len1 = avcodec_decode_audio2(is->audio_st->codec,   
  330.   
  331.                                    (int16_t *)audio_buf,   
  332.   
  333.                                    &data_size,   
  334.   
  335.                                    is->audio_pkt_data,   
  336.   
  337.                                    is->audio_pkt_size);   
  338.   
  339.       if (len1 < 0) {   
  340.   
  341.             is->audio_pkt_size = 0;   
  342.   
  343.             break;   
  344.   
  345.       }   
  346.   
  347.       is->audio_pkt_data += len1;   
  348.   
  349.       is->audio_pkt_size -= len1;   
  350.   
  351.       if (data_size <= 0) {   
  352.   
  353.             continue;   
  354.   
  355.       }   
  356.   
  357.       pts = is->audio_clock;   
  358.   
  359.       *pts_ptr = pts;   
  360.   
  361.       n = 2 * is->audio_st->codec->channels;   
  362.   
  363.       is->audio_clock += (double)data_size / (double)(n*is->audio_st->codec->sample_rate);   
  364.   
  365.       return data_size;   
  366.   
  367.     }   
  368.   
  369.     if (pkt->data) {   
  370.   
  371.       av_free_packet(pkt);   
  372.   
  373.     }   
  374.   
  375.     if (is->quit) {   
  376.   
  377.       return -1;   
  378.   
  379.     }   
  380.   
  381.     if (packet_queue_get(&is->audioq, pkt, 1) < 0) {   
  382.   
  383.       return -1;   
  384.   
  385.     }   
  386.   
  387.     is->audio_pkt_data = pkt->data;   
  388.   
  389.     is->audio_pkt_size = pkt->size;   
  390.   
  391.     if (pkt->pts != AV_NOPTS_VALUE) {   
  392.   
  393.       is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;   
  394.   
  395.     }   
  396.   
  397.   }   
  398.   
  399. }   
  400.   
  401.     
  402.   
  403. void audio_callback(void *userdata, Uint8 *stream, int len) {   
  404.   
  405.   VideoState *is = (VideoState *)userdata;   
  406.   
  407.   int len1, audio_size;   
  408.   
  409.   double pts;   
  410.   
  411.       
  412.   
  413.   while(len > 0) {   
  414.   
  415.     if(is->audio_buf_index >= is->audio_buf_size) {   
  416.   
  417.       audio_size = audio_decode_frame(is, is->audio_buf, sizeof(is->audio_buf), &pts);   
  418.   
  419.       if (audio_size < 0) {   
  420.   
  421.             is->audio_buf_size = 1024;   
  422.   
  423.             memset(is->audio_buf, 0, is->audio_buf_size);   
  424.   
  425.       } else {   
  426.   
  427.             is->audio_buf_size = audio_size;   
  428.   
  429.       }   
  430.   
  431.       is->audio_buf_index = 0;   
  432.   
  433.     }   
  434.   
  435.     len1 = is->audio_buf_size - is->audio_buf_index;   
  436.   
  437.     if(len1 > len) {   
  438.   
  439.       len1 = len;   
  440.   
  441.     }   
  442.   
  443.     memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);   
  444.   
  445.     len -= len1;   
  446.   
  447.     stream += len1;   
  448.   
  449.     is->audio_buf_index += len1;   
  450.   
  451.   }   
  452.   
  453. }   
  454.   
  455.     
  456.   
  457. static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque) {   
  458.   
  459.   SDL_Event event;   
  460.   
  461.   event.type = FF_REFRESH_EVENT;   
  462.   
  463.   event.user.data1 = opaque;   
  464.   
  465.   SDL_PushEvent(&event);   
  466.   
  467.   return 0;   
  468.   
  469. }   
  470.   
  471.     
  472.   
  473. static void schedule_refresh(VideoState *is, int delay) {   
  474.   
  475.   SDL_AddTimer(delay, sdl_refresh_timer_cb, is);   
  476.   
  477. }   
  478.   
  479.     
  480.   
  481. void video_display(VideoState *is) {   
  482.   
  483.   SDL_Rect rect;   
  484.   
  485.   VideoPicture *vp;   
  486.   
  487.   AVPicture pict;   
  488.   
  489.   float aspect_ratio;   
  490.   
  491.   int w, h, x, y;   
  492.   
  493.   int i;   
  494.   
  495.       
  496.   
  497.   vp = &is->pictq[is->pictq_rindex];   
  498.   
  499.   if (vp->bmp) {   
  500.   
  501.     if (is->video_st->codec->sample_aspect_ratio.num == 0) {   
  502.   
  503.       aspect_ratio = 0;   
  504.   
  505.     } else {   
  506.   
  507.       aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)*is->video_st->codec->width / is->video_st->codec->height;   
  508.   
  509.     }   
  510.   
  511.     if(aspect_ratio <= 0.0) {   
  512.   
  513.       aspect_ratio = (float)is->video_st->codec->width / (float)is->video_st->codec->height;   
  514.   
  515.     }   
  516.   
  517.     h = screen->h;   
  518.   
  519.     w = ((int)rint(h*aspect_ratio)) & -3;   
  520.   
  521.     if (w > screen->w) {   
  522.   
  523.       w = screen->w;   
  524.   
  525.       h = ((int)rint(w / aspect_ratio)) & -3;   
  526.   
  527.     }   
  528.   
  529.     x = (screen->w - w) / 2;   
  530.   
  531.     y = (screen->h - h) / 2;   
  532.   
  533.     rect.x = x;   
  534.   
  535.     rect.y = y;   
  536.   
  537.     rect.w = w;   
  538.   
  539.     rect.h = h;   
  540.   
  541.     SDL_DisplayYUVOverlay(vp->bmp, &rect);   
  542.   
  543.   }   
  544.   
  545. }   
  546.   
  547.     
  548.   
  549. void video_refresh_timer(void *userdata) {   
  550.   
  551.   VideoState *is = (VideoState *)userdata;   
  552.   
  553.   VideoPicture *vp;   
  554.   
  555.   double actual_delay, delay, sync_threshold, ref_clock, diff;   
  556.   
  557.     
  558.   
  559.   if(is->video_st) {   
  560.   
  561.     if(is->pictq_size == 0) {   
  562.   
  563.       schedule_refresh(is, 1);   
  564.   
  565.     } else {   
  566.   
  567.       vp = &is->pictq[is->pictq_rindex];   
  568.   
  569.       delay = vp->pts - is->frame_last_pts;   
  570.   
  571.       if (delay <= 0 || delay >= 1.0) {   
  572.   
  573.             delay = is->frame_last_delay;   
  574.   
  575.       }   
  576.   
  577.       is->frame_last_delay = delay;   
  578.   
  579.       is->frame_last_pts = vp->pts;   
  580.   
  581.           
  582.   
  583.       ref_clock = get_audio_clock(is);   
  584.   
  585.       diff = vp->pts - ref_clock;   
  586.   
  587.     
  588.   
  589.       sync_threshold = (delay > AV_SYNC_THRESHOLD) ? delay : AV_SYNC_THRESHOLD;   
  590.   
  591.       if (fabs(diff) < AV_NOSYNC_THRESHOLD) {   
  592.   
  593.             if (diff <= -sync_threshold) {   
  594.   
  595.               delay = 0;   
  596.   
  597.             } else if (diff >= sync_threshold) {   
  598.   
  599.                   delay = 2 * delay;   
  600.   
  601.             }   
  602.   
  603.       }   
  604.   
  605.       is->frame_timer += delay;   
  606.   
  607.       actual_delay = is->frame_timer - (av_gettime() / 1000000.0);   
  608.   
  609.       if (actual_delay < 0.010) {   
  610.   
  611.             actual_delay = 0.010;   
  612.   
  613.       }   
  614.   
  615.       schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));   
  616.   
  617.       video_display(is);   
  618.   
  619.       if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE) {   
  620.   
  621.             is->pictq_rindex = 0;   
  622.   
  623.       }   
  624.   
  625.       SDL_LockMutex(is->pictq_mutex);   
  626.   
  627.       is->pictq_size--;   
  628.   
  629.       SDL_CondSignal(is->pictq_cond);   
  630.   
  631.       SDL_UnlockMutex(is->pictq_mutex);   
  632.   
  633.     }   
  634.   
  635.   } else {   
  636.   
  637.     schedule_refresh(is, 100);   
  638.   
  639.   }   
  640.   
  641. }   
  642.   
  643.     
  644.   
  645. void alloc_picture(void *userdata) {   
  646.   
  647.   VideoState *is = (VideoState *)userdata;   
  648.   
  649.   VideoPicture *vp;   
  650.   
  651.       
  652.   
  653.   vp = &is->pictq[is->pictq_windex];   
  654.   
  655.   if (vp->bmp) {   
  656.   
  657.     SDL_FreeYUVOverlay(vp->bmp);   
  658.   
  659.   }   
  660.   
  661.   vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,   
  662.   
  663.                  is->video_st->codec->height,   
  664.   
  665.                  SDL_YV12_OVERLAY,   
  666.   
  667.                  screen);   
  668.   
  669.   vp->width = is->video_st->codec->width;   
  670.   
  671.   vp->height = is->video_st->codec->height;   
  672.   
  673.     
  674.   
  675.   SDL_LockMutex(is->pictq_mutex);   
  676.   
  677.   vp->allocated = 1;   
  678.   
  679.   SDL_CondSignal(is->pictq_cond);   
  680.   
  681.   SDL_UnlockMutex(is->pictq_mutex);   
  682.   
  683. }   
  684.   
  685.     
  686.   
  687. int queue_picture(VideoState *is, AVFrame *pFrame, double pts) {   
  688.   
  689.   VideoPicture *vp;   
  690.   
  691.   int dst_pix_fmt;   
  692.   
  693.   AVPicture pict;   
  694.   
  695.       
  696.   
  697.   SDL_LockMutex(is->pictq_mutex);   
  698.   
  699.   while(is->pictq_size>=VIDEO_PICTURE_QUEUE_SIZE &&   
  700.   
  701.     !is->quit) {   
  702.   
  703.     SDL_CondWait(is->pictq_cond, is->pictq_mutex);   
  704.   
  705.   }   
  706.   
  707.   SDL_UnlockMutex(is->pictq_mutex);   
  708.   
  709.       
  710.   
  711.   if(is->quit) {   
  712.   
  713.     return -1;   
  714.   
  715.   }   
  716.   
  717.       
  718.   
  719.   vp = &is->pictq[is->pictq_windex];   
  720.   
  721.       
  722.   
  723.   if (!vp->bmp ||   
  724.   
  725.       vp->width != is->video_st->codec->width ||   
  726.   
  727.       vp->height != is->video_st->codec->height) {   
  728.   
  729.     SDL_Event event;   
  730.   
  731.         
  732.   
  733.     vp->allocated = 0;   
  734.   
  735.     event.type = FF_ALLOC_EVENT;   
  736.   
  737.     event.user.data1 = is;   
  738.   
  739.     SDL_PushEvent(&event);   
  740.   
  741.         
  742.   
  743.     SDL_LockMutex(is->pictq_mutex);   
  744.   
  745.     while(!vp->allocated && !is->quit) {   
  746.   
  747.       SDL_CondWait(is->pictq_cond, is->pictq_mutex);   
  748.   
  749.     }   
  750.   
  751.     SDL_UnlockMutex(is->pictq_mutex);   
  752.   
  753.     if (is->quit) {   
  754.   
  755.       return -1;   
  756.   
  757.     }   
  758.   
  759.   }   
  760.   
  761.       
  762.   
  763.   if (vp->bmp) {   
  764.   
  765.     SDL_LockYUVOverlay(vp->bmp);   
  766.   
  767.     
  768.   
  769.     dst_pix_fmt = PIX_FMT_YUV420P;   
  770.   
  771.         
  772.   
  773.     pict.data[0] = vp->bmp->pixels[0];   
  774.   
  775.     pict.data[1] = vp->bmp->pixels[2];   
  776.   
  777.     pict.data[2] = vp->bmp->pixels[1];   
  778.   
  779.     
  780.   
  781.     pict.linesize[0] = vp->bmp->pitches[0];   
  782.   
  783.     pict.linesize[1] = vp->bmp->pitches[2];   
  784.   
  785.     pict.linesize[2] = vp->bmp->pitches[1];   
  786.   
  787.     
  788.   
  789.     //    
  790.   
  791.     sws_scale(is->img_convert_ctx,   
  792.   
  793.           pFrame->data,   
  794.   
  795.           pFrame->linesize, 0,   
  796.   
  797.           is->video_st->codec->height,   
  798.   
  799.           pict.data,   
  800.   
  801.           pict.linesize);   
  802.   
  803.     //    
  804.   
  805.         
  806.   
  807.     SDL_UnlockYUVOverlay(vp->bmp);   
  808.   
  809.     vp->pts = pts;   
  810.   
  811.     
  812.   
  813.     if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) {   
  814.   
  815.       is->pictq_windex = 0;   
  816.   
  817.     }   
  818.   
  819.     SDL_LockMutex(is->pictq_mutex);   
  820.   
  821.     is->pictq_size ++;   
  822.   
  823.     SDL_UnlockMutex(is->pictq_mutex);   
  824.   
  825.   }   
  826.   
  827.   return 0;   
  828.   
  829. }   
  830.   
  831.     
  832.   
  833. double synchronize_video(VideoState *is, AVFrame *src_frame, double pts) {   
  834.   
  835.   double frame_delay;   
  836.   
  837.   if (pts != 0) {   
  838.   
  839.     is->video_clock = pts;   
  840.   
  841.   } else {   
  842.   
  843.     pts = is->video_clock;   
  844.   
  845.   }   
  846.   
  847.   frame_delay = av_q2d(is->video_st->codec->time_base);   
  848.   
  849.   frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);   
  850.   
  851.   is->video_clock += frame_delay;   
  852.   
  853.   return pts;   
  854.   
  855. }   
  856.   
  857.     
  858.   
  859. uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;   
  860.   
  861.     
  862.   
  863. int our_get_buffer(struct AVCodecContext *c, AVFrame *pic) {   
  864.   
  865.   int ret = avcodec_default_get_buffer(c, pic);   
  866.   
  867.   uint64_t *pts = av_malloc(sizeof(uint64_t));   
  868.   
  869.   *pts = global_video_pkt_pts;   
  870.   
  871.   pic->opaque = pts;   
  872.   
  873.   return ret;   
  874.   
  875. }   
  876.   
  877.     
  878.   
  879. void our_release_buffer(struct AVCodecContext *c, AVFrame *pic) {   
  880.   
  881.   if (pic) {   
  882.   
  883.     av_freep(&pic->opaque);   
  884.   
  885.   }   
  886.   
  887.   avcodec_default_release_buffer(c, pic);   
  888.   
  889. }   
  890.   
  891.     
  892.   
  893. int video_thread(void *arg) {   
  894.   
  895.   VideoState *is = (VideoState*)arg;   
  896.   
  897.   AVPacket pkt1, *packet = &pkt1;   
  898.   
  899.   int len1, frameFinished;   
  900.   
  901.   AVFrame *pFrame;   
  902.   
  903.   double pts;   
  904.   
  905.       
  906.   
  907.   pFrame = avcodec_alloc_frame();   
  908.   
  909.   for(;;) {   
  910.   
  911.     if(packet_queue_get(&is->videoq, packet, 1) < 0) {   
  912.   
  913.       break;   
  914.   
  915.     }   
  916.   
  917.     pts = 0;   
  918.   
  919.     global_video_pkt_pts = packet->pts;   
  920.   
  921.     len1 = avcodec_decode_video(is->video_st->codec,   
  922.   
  923.                 pFrame,   
  924.   
  925.                 &frameFinished,   
  926.   
  927.                 packet->data,   
  928.   
  929.                 packet->size);   
  930.   
  931.     if(packet->dts == AV_NOPTS_VALUE   
  932.   
  933.        && pFrame->opaque   
  934.   
  935.        && *(uint64_t*)pFrame->opaque   
  936.   
  937.        != AV_NOPTS_VALUE) {   
  938.   
  939.       pts = *(uint64_t*) pFrame->opaque;   
  940.   
  941.     } else if (packet->dts != AV_NOPTS_VALUE) {   
  942.   
  943.       pts = packet->dts;   
  944.   
  945.     } else {   
  946.   
  947.       pts = 0;   
  948.   
  949.     }   
  950.   
  951.     pts *= av_q2d(is->video_st->time_base);   
  952.   
  953.         
  954.   
  955.     if (frameFinished) {   
  956.   
  957.       pts = synchronize_video(is, pFrame, pts);   
  958.   
  959.       if (queue_picture(is, pFrame, pts) < 0) {   
  960.   
  961.     break;   
  962.   
  963.       }   
  964.   
  965.     }   
  966.   
  967.     av_free_packet(packet);   
  968.   
  969.   }   
  970.   
  971.   av_free(pFrame);   
  972.   
  973.   return 0;   
  974.   
  975. }   
  976.   
  977.     
  978.   
  979. int stream_component_open(VideoState *is, int stream_index) {   
  980.   
  981.   AVFormatContext *pFormatCtx = is->pFormatCtx;   
  982.   
  983.   AVCodecContext *codecCtx;   
  984.   
  985.   AVCodec *codec;   
  986.   
  987.   SDL_AudioSpec wanted_spec, spec;   
  988.   
  989.       
  990.   
  991.   if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams) {   
  992.   
  993.     return -1;   
  994.   
  995.   }   
  996.   
  997.     
  998.   
  999.   codecCtx = pFormatCtx->streams[stream_index]->codec;   
  1000.   
  1001.     
  1002.   
  1003.   is->img_convert_ctx = sws_getContext(codecCtx->width,   
  1004.   
  1005.                    codecCtx->height,   
  1006.   
  1007.                    codecCtx->pix_fmt,   
  1008.   
  1009.                    codecCtx->width,   
  1010.   
  1011.                    codecCtx->height,   
  1012.   
  1013.                    PIX_FMT_YUV420P,   
  1014.   
  1015.                    SWS_BICUBIC,   
  1016.   
  1017.                    NULL, NULL, NULL);   
  1018.   
  1019.     
  1020.   
  1021.   if(codecCtx->codec_type == CODEC_TYPE_AUDIO) {   
  1022.   
  1023.     wanted_spec.freq = codecCtx->sample_rate;   
  1024.   
  1025.     wanted_spec.format = AUDIO_S16SYS;   
  1026.   
  1027.     wanted_spec.channels = codecCtx->channels;   
  1028.   
  1029.     wanted_spec.silence = 0;   
  1030.   
  1031.     wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;   
  1032.   
  1033.     wanted_spec.callback = audio_callback;   
  1034.   
  1035.     wanted_spec.userdata = is;   
  1036.   
  1037.         
  1038.   
  1039.     if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {   
  1040.   
  1041.       fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());   
  1042.   
  1043.       return -1;   
  1044.   
  1045.     }   
  1046.   
  1047.     is->audio_hw_buf_size = spec.size;   
  1048.   
  1049.   }   
  1050.   
  1051.   codec = avcodec_find_decoder(codecCtx->codec_id);   
  1052.   
  1053.     
  1054.   
  1055.   if(!codec || (avcodec_open(codecCtx, codec)) < 0) {   
  1056.   
  1057.     fprintf(stderr, "Unsupported codec!\n");   
  1058.   
  1059.     return -1;   
  1060.   
  1061.   }   
  1062.   
  1063.       
  1064.   
  1065.   switch(codecCtx->codec_type) {   
  1066.   
  1067.   case CODEC_TYPE_AUDIO:   
  1068.   
  1069.     is->audioStream = stream_index;   
  1070.   
  1071.     is->audio_st = pFormatCtx->streams[stream_index];   
  1072.   
  1073.     is->audio_buf_size = 0;   
  1074.   
  1075.     is->audio_buf_index = 0;   
  1076.   
  1077.     memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));   
  1078.   
  1079.     packet_queue_init(&is->audioq);   
  1080.   
  1081.     SDL_PauseAudio(0);   
  1082.   
  1083.     break;   
  1084.   
  1085.   case CODEC_TYPE_VIDEO:   
  1086.   
  1087.     is->videoStream = stream_index;   
  1088.   
  1089.     is->video_st = pFormatCtx->streams[stream_index];   
  1090.   
  1091.     is->frame_timer = (double)av_gettime() / 1000000.0;   
  1092.   
  1093.     is->frame_last_delay = 40e-3;   
  1094.   
  1095.     packet_queue_init(&is->videoq);   
  1096.   
  1097.     is->video_tid = SDL_CreateThread(video_thread, is);   
  1098.   
  1099.     codecCtx->get_buffer = our_get_buffer;   
  1100.   
  1101.     codecCtx->release_buffer = our_release_buffer;   
  1102.   
  1103.     break;   
  1104.   
  1105.   default:   
  1106.   
  1107.     break;   
  1108.   
  1109.   }   
  1110.   
  1111. }   
  1112.   
  1113.     
  1114.   
  1115. int decode_interrupt_cb(void) {   
  1116.   
  1117.   return (global_video_state && global_video_state->quit);   
  1118.   
  1119. }   
  1120.   
  1121.     
  1122.   
  1123. int decode_thread(void *arg) {   
  1124.   
  1125.   VideoState *is = (VideoState*)arg;   
  1126.   
  1127.   AVFormatContext *pFormatCtx;   
  1128.   
  1129.   AVPacket pkt1, *packet = &pkt1;   
  1130.   
  1131.     
  1132.   
  1133.   int video_index = -1;   
  1134.   
  1135.   int audio_index = -1;   
  1136.   
  1137.   int i;   
  1138.   
  1139.     
  1140.   
  1141.   is->videoStream = -1;   
  1142.   
  1143.   is->audioStream = -1;   
  1144.   
  1145.     
  1146.   
  1147.   global_video_state = is;   
  1148.   
  1149.   url_set_interrupt_cb(decode_interrupt_cb);   
  1150.   
  1151.   if(av_open_input_file(&pFormatCtx, is->filename, NULL, 0, NULL) != 0) {   
  1152.   
  1153.     return -1;   
  1154.   
  1155.   }   
  1156.   
  1157.   is->pFormatCtx = pFormatCtx;   
  1158.   
  1159.     
  1160.   
  1161.   if (av_find_stream_info(pFormatCtx) < 0) {   
  1162.   
  1163.     return -1;   
  1164.   
  1165.   }   
  1166.   
  1167.       
  1168.   
  1169.   dump_format(pFormatCtx, 0, is->filename, 0);   
  1170.   
  1171.     
  1172.   
  1173.   for (i=0 ; i<pFormatCtx->nb_streams; i++) {   
  1174.   
  1175.     if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO && video_index < 0) {   
  1176.   
  1177.       video_index = i;   
  1178.   
  1179.     }   
  1180.   
  1181.     if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO && audio_index < 0) {   
  1182.   
  1183.       audio_index = i;   
  1184.   
  1185.     }   
  1186.   
  1187.   }   
  1188.   
  1189.   if (audio_index >= 0) {   
  1190.   
  1191.     stream_component_open(is, audio_index);   
  1192.   
  1193.   }   
  1194.   
  1195.   if (video_index >= 0) {   
  1196.   
  1197.     stream_component_open(is, video_index);   
  1198.   
  1199.   }   
  1200.   
  1201.     
  1202.   
  1203.   if(is->videoStream < 0 || is->audioStream < 0) {   
  1204.   
  1205.     fprintf(stderr, "%s: could not open codecs\n", is->filename);   
  1206.   
  1207.     goto fail;   
  1208.   
  1209.   }   
  1210.   
  1211.     
  1212.   
  1213.   for(;;) {   
  1214.   
  1215.     if(is->quit) {   
  1216.   
  1217.       break;   
  1218.   
  1219.     }   
  1220.   
  1221.     if (is->audioq.size > MAX_AUDIOQ_SIZE || is->videoq.size > MAX_VIDEOQ_SIZE) {   
  1222.   
  1223.       SDL_Delay(10);   
  1224.   
  1225.       continue;   
  1226.   
  1227.     }   
  1228.   
  1229.     if(av_read_frame(is->pFormatCtx, packet) < 0) {   
  1230.   
  1231.       if(url_ferror(pFormatCtx->pb) == 0) {   
  1232.   
  1233.     SDL_Delay(100);   
  1234.   
  1235.     continue;   
  1236.   
  1237.       } else {   
  1238.   
  1239.     break;   
  1240.   
  1241.       }   
  1242.   
  1243.     }   
  1244.   
  1245.     if (packet->stream_index == is->videoStream) {   
  1246.   
  1247.       packet_queue_put(&is->videoq, packet);   
  1248.   
  1249.     } else if (packet->stream_index == is->audioStream) {   
  1250.   
  1251.       packet_queue_put(&is->audioq, packet);   
  1252.   
  1253.     } else {   
  1254.   
  1255.       av_free_packet(packet);   
  1256.   
  1257.     }   
  1258.   
  1259.   }   
  1260.   
  1261.   while (!is->quit) {   
  1262.   
  1263.     SDL_Delay(100);   
  1264.   
  1265.   }   
  1266.   
  1267.       
  1268.   
  1269.  fail:   
  1270.   
  1271.   {   
  1272.   
  1273.     SDL_Event event;   
  1274.   
  1275.     event.type = FF_QUIT_EVENT;   
  1276.   
  1277.     event.user.data1 = is;   
  1278.   
  1279.     SDL_PushEvent(&event);   
  1280.   
  1281.   }   
  1282.   
  1283.   return 0;   
  1284.   
  1285. }   
  1286.   
  1287.     
  1288.   
  1289. int main(int argc, char *argv[]) {   
  1290.   
  1291.   SDL_Event event;   
  1292.   
  1293.   VideoState *is;   
  1294.   
  1295.   is = av_mallocz(sizeof(VideoState));   
  1296.   
  1297.   if (argc < 2) {   
  1298.   
  1299.     fprintf(stderr, "Usage: test <file>\n");   
  1300.   
  1301.     exit(1);   
  1302.   
  1303.   }   
  1304.   
  1305.   av_register_all();   
  1306.   
  1307.     
  1308.   
  1309.   if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {   
  1310.   
  1311.     fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());   
  1312.   
  1313.     exit(1);   
  1314.   
  1315.   }   
  1316.   
  1317.       
  1318.   
  1319.   screen = SDL_SetVideoMode(640, 480, 24, 0);   
  1320.   
  1321.     
  1322.   
  1323.   if(!screen) {   
  1324.   
  1325.     fprintf(stderr, "SDL: could not set video mode - exiting\n");   
  1326.   
  1327.     exit(1);   
  1328.   
  1329.   }   
  1330.   
  1331.     
  1332.   
  1333.   av_strlcpy(is->filename, argv[1], sizeof(is->filename));   
  1334.   
  1335.     
  1336.   
  1337.   is->pictq_mutex = SDL_CreateMutex();   
  1338.   
  1339.   is->pictq_cond = SDL_CreateCond();   
  1340.   
  1341.     
  1342.   
  1343.   schedule_refresh(is, 40);   
  1344.   
  1345.       
  1346.   
  1347.   is->parse_tid = SDL_CreateThread(decode_thread, is);   
  1348.   
  1349.   if (!is->parse_tid) {   
  1350.   
  1351.     av_free(is);   
  1352.   
  1353.     return -1;   
  1354.   
  1355.   }   
  1356.   
  1357.   for (;;) {   
  1358.   
  1359.     SDL_WaitEvent(&event);   
  1360.   
  1361.     switch(event.type) {   
  1362.   
  1363.     case FF_QUIT_EVENT:   
  1364.   
  1365.     case SDL_QUIT:   
  1366.   
  1367.       is->quit = 1;   
  1368.   
  1369.       SDL_Quit();   
  1370.   
  1371.       exit(0);   
  1372.   
  1373.       break;   
  1374.   
  1375.     case FF_ALLOC_EVENT:   
  1376.   
  1377.       alloc_picture(event.user.data1);   
  1378.   
  1379.       break;   
  1380.   
  1381.     case FF_REFRESH_EVENT:   
  1382.   
  1383.       video_refresh_timer(event.user.data1);   
  1384.   
  1385.       break;   
  1386.   
  1387.     default:   
  1388.   
  1389.       break;   
  1390.   
  1391.     }   
  1392.   
  1393.   }   
  1394.   
  1395.   return 0;   
  1396.   
  1397. }  
原创粉丝点击