音视频流::ffplay::tutorial04

来源:互联网 发布:淘宝开店协议怎么查 编辑:程序博客网 时间:2024/05/16 09:55

转自:

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

 

所用的版本为ffmpeg 0.6.3

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

 

转自:

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

 

所用的版本为ffmpeg 0.6.3

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

 

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


原创粉丝点击