Advertisement
zerodivisi0n

FFmpeg sample player 2 (audio + sync)

Feb 29th, 2012
7,763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.89 KB | None | 0 0
  1. /**
  2.  * FFmpeg sample player with audio support and syncing.
  3.  * Compile with:
  4.  * gcc player2.c -o player -lavutil -lavformat -lavcodec -lswscale -lz -lbz2 `/opt/SDL/bin/sdl-config --cflags --libs`
  5.  * Related to: http://habrahabr.ru/blogs/video/138426/
  6.  * Author: Alexey Zhuchkov (zerodivisi0n)
  7.  * License: GPL
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <assert.h>
  13.  
  14. #include <libavcodec/avcodec.h>
  15. #include <libavformat/avformat.h>
  16. #include <libswscale/swscale.h>
  17.  
  18. #include <SDL.h>
  19.  
  20. #define SDL_AUDIO_BUFFER_SIZE 1024
  21. #define AUDIO_BUF_SIZE ((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2)
  22. #define MAX_AUDIO_BUF_SIZE (AVCODEC_MAX_AUDIO_FRAME_SIZE * 4)
  23. /* no AV sync correction is done if below the AV sync threshold */
  24. #define AV_SYNC_THRESHOLD 0.01
  25. /* no AV correction is done if too big error */
  26. #define AV_NOSYNC_THRESHOLD 10.0
  27.  
  28. #define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
  29.  
  30. typedef struct PacketQueue {
  31.     AVPacketList *first_pkt, *last_pkt;
  32.     int nb_packets;
  33.     int size;
  34.     int eof;
  35.     SDL_mutex* mutex;
  36.     SDL_cond* cond;
  37. } PacketQueue;
  38.  
  39. typedef struct RingBuffer {
  40.     uint8_t* data;
  41.     int size;
  42.     int max_size;
  43.     int rindex;  // Read position
  44.     int windex;  // Write position
  45.     char eof;  // EOF flag
  46.     char lastop;  // last operation flag: 0 - read, 1 - write
  47.     SDL_mutex* mutex;
  48.     SDL_cond* rcond;
  49.     SDL_cond* wcond;
  50. } RingBuffer;
  51.  
  52. typedef struct VideoPicture {
  53.     SDL_Surface* screen;
  54.     SDL_Overlay* bmp;
  55.     double pts;
  56.     int ready;
  57.     SDL_mutex* mutex;
  58.     SDL_cond* cond;
  59. } VideoPicture;
  60.  
  61. typedef struct MainContext {
  62.     AVFormatContext *format_context;
  63.     int quit;
  64.    
  65.     // Streams
  66.     AVStream* video_stream;
  67.     AVStream* audio_stream;
  68.    
  69.     // Queues
  70.     PacketQueue videoq;
  71.     PacketQueue audioq;
  72.    
  73.     struct SwsContext* sws_context;
  74.    
  75.     VideoPicture pict;
  76.     RingBuffer audio_buf;
  77.    
  78.     double video_clock;
  79.     double audio_clock;
  80.    
  81.     double frame_timer;
  82.     double frame_last_pts;
  83.     double frame_last_delay;
  84.    
  85.     // Threads
  86.     SDL_Thread* demux_tid;
  87.     SDL_Thread* video_decode_tid;
  88.     SDL_Thread* audio_decode_tid;
  89. } MainContext;
  90.  
  91. static void usage(const char* progname) {
  92.     assert(progname != NULL);
  93.    
  94.     fprintf(stderr, "Usage %s movie\n", progname);
  95. }
  96.  
  97. static void packet_queue_init(PacketQueue* q) {
  98.     assert(q != NULL);
  99.    
  100.     memset(q, 0, sizeof(PacketQueue));
  101.     q->mutex = SDL_CreateMutex();
  102.     q->cond = SDL_CreateCond();
  103. }
  104.  
  105. static void packet_queue_deinit(PacketQueue* q) {
  106.     assert(q != NULL);
  107.     assert(q->mutex != NULL);
  108.     assert(q->cond != NULL);
  109.    
  110.     SDL_DestroyMutex(q->mutex);
  111.     SDL_DestroyCond(q->cond);
  112. }
  113.  
  114. static int packet_queue_put(PacketQueue* q, AVPacket* pkt) {
  115.     assert(q != NULL);
  116.     assert(pkt != NULL);
  117.    
  118.     // Duplicate current packet
  119.     if (av_dup_packet(pkt) < 0) {
  120.         return -1;
  121.     }
  122.    
  123.     AVPacketList* pkt_list = av_malloc(sizeof(AVPacketList));
  124.     if (pkt_list == NULL) {
  125.         return -1;
  126.     }
  127.    
  128.     pkt_list->pkt = *pkt;
  129.     pkt_list->next = NULL;
  130.    
  131.     SDL_LockMutex(q->mutex);
  132.    
  133.     if (!q->eof) {
  134.         if (q->last_pkt == NULL) {
  135.             // It's a first packet in queue
  136.             q->first_pkt = pkt_list;
  137.         } else {
  138.             // Append to the end of queue
  139.             q->last_pkt->next = pkt_list;
  140.         }
  141.         q->last_pkt = pkt_list;
  142.         q->nb_packets++;
  143.         q->size += pkt->size;
  144.     }
  145.     SDL_CondSignal(q->cond);
  146.    
  147.     SDL_UnlockMutex(q->mutex);
  148.     return 0;
  149. }
  150.  
  151. static int packet_queue_get(PacketQueue* q, AVPacket* pkt, int block) {
  152.     assert(q != NULL);
  153.     assert(pkt != NULL);
  154.    
  155.     SDL_LockMutex(q->mutex);
  156.    
  157.     AVPacketList* pkt_list = q->first_pkt;
  158.     if (!block && (pkt_list == NULL)) {
  159.         SDL_UnlockMutex(q->mutex);
  160.         return -1;
  161.     } else {
  162.         while ((pkt_list == NULL) && !q->eof) {
  163.             // Wait for packets
  164.             SDL_CondWait(q->cond, q->mutex);
  165.             pkt_list = q->first_pkt;
  166.         }
  167.     }
  168.    
  169.     if ((pkt_list == NULL) && q->eof) {
  170.         SDL_UnlockMutex(q->mutex);
  171.         return -1;
  172.     }
  173.    
  174.     q->first_pkt = pkt_list->next;
  175.     if (q->first_pkt == NULL) {
  176.         // No more packets
  177.         q->last_pkt = NULL;
  178.     }
  179.     *pkt = pkt_list->pkt;
  180.     q->nb_packets--;   
  181.     q->size -= pkt->size;
  182.     av_free(pkt_list);
  183.    
  184.     SDL_UnlockMutex(q->mutex);
  185.     return 0;
  186. }
  187.  
  188. static void packet_queue_eof(PacketQueue* q) {
  189.     assert(q != NULL);
  190.    
  191.     SDL_LockMutex(q->mutex);
  192.     q->eof = 1;
  193.     SDL_CondBroadcast(q->cond);
  194.     SDL_UnlockMutex(q->mutex);
  195. }
  196.  
  197. int ring_buffer_init(RingBuffer* rb, int initial_size, int max_size) {
  198.     assert(rb != NULL);
  199.     assert((max_size <= 0) || (max_size >= initial_size));
  200.    
  201.     memset(rb, 0, sizeof(RingBuffer));
  202.    
  203.     rb->data = av_malloc(initial_size);
  204.     if (rb->data == NULL) {
  205.         return -1;
  206.     }
  207.     rb->size = initial_size;
  208.     rb->max_size = max_size;
  209.     rb->mutex = SDL_CreateMutex();
  210.     rb->rcond = SDL_CreateCond();
  211.     rb->wcond = SDL_CreateCond();
  212.     return 0;
  213. }
  214.  
  215. void ring_buffer_deinit(RingBuffer* rb) {
  216.     assert(rb != NULL);
  217.     assert(rb->mutex != NULL);
  218.     assert(rb->rcond != NULL);
  219.     assert(rb->wcond != NULL);
  220.    
  221.     SDL_DestroyMutex(rb->mutex);
  222.     SDL_DestroyCond(rb->rcond);
  223.     SDL_DestroyCond(rb->wcond);
  224. }
  225.  
  226. // Returns number of bytes written
  227. int ring_buffer_write(RingBuffer* rb, void* buffer, int len, int block) {
  228.     assert(rb != NULL);
  229.     assert(rb != NULL);
  230.    
  231.     if (len == 0) {
  232.         return 0;
  233.     }
  234.    
  235.     SDL_LockMutex(rb->mutex);
  236.    
  237.     if (rb->eof) {
  238.         // Buffer ended
  239.         SDL_UnlockMutex(rb->mutex);
  240.         return -1;
  241.     }
  242.    
  243.     uint8_t* buffer_ptr = buffer;
  244.     while (len > 0) {
  245.         int step;
  246.         if ((rb->rindex < rb->windex) ||  // write forward
  247.             ((rb->rindex == rb->windex) && (rb->lastop == 0))) {  // buffer must be free
  248.             step = rb->size - rb->windex;
  249.         } else if (rb->rindex > rb->windex) {
  250.             step = rb->rindex - rb->windex;
  251.         } else if (block) {
  252.             SDL_CondWait(rb->rcond, rb->mutex);
  253.             if (rb->eof) {
  254.                 break;
  255.             }
  256.             continue;
  257.         } else {
  258.             break;
  259.         }
  260.        
  261.         if (len < step) {
  262.             step = len;
  263.         }
  264.         memcpy(rb->data + rb->windex, buffer_ptr, step);
  265.        
  266.         rb->windex += step;
  267.         assert(rb->windex <= rb->size);
  268.         if (rb->windex == rb->size) {
  269.             rb->windex = 0;
  270.         }
  271.         rb->lastop = 1;
  272.         SDL_CondSignal(rb->wcond);
  273.        
  274.         buffer_ptr += step;
  275.         len -= step;
  276.     }
  277.    
  278.     SDL_UnlockMutex(rb->mutex);
  279.     return buffer_ptr - (uint8_t*)buffer;
  280. }
  281.  
  282. // Returns number of bytes read
  283. int ring_buffer_read(RingBuffer* rb, void* buffer, int len, int block) {
  284.     assert(rb != NULL);
  285.     assert(buffer != NULL);
  286.    
  287.     if (len == 0) {
  288.         return 0;
  289.     }
  290.    
  291.     SDL_LockMutex(rb->mutex);
  292.    
  293.     uint8_t* buffer_ptr = buffer;
  294.     while (len > 0) {
  295.         int step;
  296.         if (rb->rindex < rb->windex) {  // write forward
  297.             step = rb->windex - rb->rindex;
  298.         } else if ((rb->rindex > rb->windex) ||  // read forward
  299.                    ((rb->rindex == rb->windex) && (rb->lastop == 1))) {  // buffer must be full
  300.             step = rb->size - rb->rindex;
  301.         } else if (block && !rb->eof) {
  302.             SDL_CondWait(rb->wcond, rb->mutex);
  303.             continue;
  304.         } else {
  305.             break;
  306.         }
  307.        
  308.         if (len < step) {
  309.             step = len;
  310.         }
  311.         memcpy(buffer_ptr, rb->data + rb->rindex, step);
  312.        
  313.         rb->rindex += step;
  314.         assert(rb->rindex <= rb->size);
  315.         if (rb->rindex == rb->size) {
  316.             rb->rindex = 0;
  317.         }
  318.         rb->lastop = 0;
  319.         SDL_CondSignal(rb->rcond);
  320.        
  321.         buffer_ptr += step;
  322.         len -= step;
  323.     }
  324.    
  325.     int count = buffer_ptr - (uint8_t*)buffer;
  326.     if ((count == 0) && rb->eof) {
  327.         count = -1;
  328.     }
  329.    
  330.     SDL_UnlockMutex(rb->mutex);
  331.     return count;
  332. }
  333.  
  334. int ring_buffer_size(RingBuffer* rb) {
  335.     assert(rb != NULL);
  336.    
  337.     int size;
  338.     SDL_LockMutex(rb->mutex);
  339.     if (rb->rindex < rb->windex) {
  340.         size = rb->windex - rb->rindex;
  341.     } else {
  342.         size = rb->size - rb->rindex + rb->windex;
  343.     }
  344.     SDL_UnlockMutex(rb->mutex);
  345.     return size;
  346. }
  347.  
  348. void ring_buffer_eof(RingBuffer* rb) {
  349.     assert(rb != NULL);
  350.    
  351.     SDL_LockMutex(rb->mutex);
  352.     rb->eof = 1;
  353.     SDL_CondBroadcast(rb->wcond);
  354.     SDL_UnlockMutex(rb->mutex);
  355. }
  356.  
  357. static AVStream* open_stream(AVFormatContext* format_context, int type) {
  358.     assert(format_context != NULL);
  359.    
  360.     int index;
  361.     AVStream* stream = NULL;
  362.     // Find stream index
  363.     for (index = 0; index < format_context->nb_streams; ++index) {
  364.         if (format_context->streams[index]->codec->codec_type == type) {
  365.             stream = format_context->streams[index];
  366.             break;
  367.         }
  368.     }
  369.     if (stream == NULL) {
  370.         // Stream index not found
  371.         return NULL;
  372.     }
  373.    
  374.     AVCodecContext* codec_context = stream->codec;
  375.    
  376.     // Find suitable codec
  377.     AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
  378.     if (codec == NULL) {
  379.         // Codec not found
  380.         return NULL;
  381.     }
  382.     if (avcodec_open2(codec_context, codec, NULL) < 0) {
  383.         // Failed to open codec
  384.         return NULL;
  385.     }
  386.    
  387.     return stream;
  388. }
  389.  
  390. static void close_stream(AVStream* stream) {
  391.     assert(stream != NULL);
  392.    
  393.     if (stream->codec != NULL) {
  394.         avcodec_close(stream->codec);
  395.     }
  396. }
  397.  
  398. static void audio_callback(void* userdata, uint8_t* stream, int len) {
  399.     assert(userdata != NULL);
  400.    
  401.     MainContext* main_context = (MainContext*)userdata;
  402.     ring_buffer_read(&main_context->audio_buf, stream, len, 1);
  403. }
  404.  
  405. static int configure_audio(MainContext* main_context) {
  406.     assert(main_context != NULL);
  407.    
  408.     AVCodecContext* codec_context = main_context->audio_stream->codec;
  409.    
  410.     SDL_AudioSpec wanted_spec, spec;
  411.     // Set audio settings from codec info
  412.     wanted_spec.freq = codec_context->sample_rate;
  413.     wanted_spec.format = AUDIO_S16SYS;
  414.     wanted_spec.channels = codec_context->channels;
  415.     wanted_spec.silence = 0;
  416.     wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
  417.     wanted_spec.callback = audio_callback;
  418.     wanted_spec.userdata = main_context;
  419.    
  420.     if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
  421.       fprintf(stderr, "SDL: %s\n", SDL_GetError());
  422.       return -1;
  423.     }
  424.  
  425.     SDL_PauseAudio(0);
  426.    
  427.     return 0;
  428. }
  429.  
  430. static int open_file(MainContext* main_context, const char* filename) {
  431.     assert(main_context != NULL);
  432.     assert(filename != NULL);
  433.    
  434.     int err;
  435.  
  436.     // Open video file
  437.     AVFormatContext* format_context = NULL;
  438.     err = avformat_open_input(&format_context, filename, NULL, NULL);
  439.     if (err < 0) {
  440.         fprintf(stderr, "ffmpeg: Unable to open input file\n");
  441.         return -1;
  442.     }
  443.     main_context->format_context = format_context;
  444.  
  445.     // Retrieve stream information
  446.     err = avformat_find_stream_info(format_context, NULL);
  447.     if (err < 0) {
  448.         fprintf(stderr, "ffmpeg: Unable to find stream info\n");
  449.         return -1;
  450.     }
  451.    
  452.     // Dump information about file onto standard error
  453.     av_dump_format(format_context, 0, filename, 0);
  454.    
  455.     // Open video and audio streams
  456.     main_context->video_stream = open_stream(format_context, AVMEDIA_TYPE_VIDEO);
  457.     if (main_context->video_stream == NULL) {
  458.         fprintf(stderr, "ffmpeg: Could not open video stream\n");
  459.         return -1;
  460.     }
  461.     main_context->audio_stream = open_stream(format_context, AVMEDIA_TYPE_AUDIO);
  462.     if (main_context->audio_stream == NULL) {
  463.         fprintf(stderr, "ffmpeg: Could not open audio stream\n");
  464.         return -1;
  465.     }
  466.    
  467.     // Create conversion context
  468.     AVCodecContext* video_codec_context = main_context->video_stream->codec;
  469.     main_context->sws_context = sws_getCachedContext(NULL,
  470.                                                      video_codec_context->width, video_codec_context->height,
  471.                                                      video_codec_context->pix_fmt,
  472.                                                      video_codec_context->width, video_codec_context->height,
  473.                                                      PIX_FMT_YUV420P, SWS_BICUBIC,
  474.                                                      NULL, NULL, NULL);
  475.    
  476.     // Prepare SDL video output
  477.     main_context->pict.screen = SDL_SetVideoMode(video_codec_context->width, video_codec_context->height, 0, 0);
  478.     if (main_context->pict.screen == NULL) {
  479.         fprintf(stderr, "Couldn't set video mode\n");
  480.         return -1;
  481.     }
  482.    
  483.     main_context->pict.bmp = SDL_CreateYUVOverlay(video_codec_context->width, video_codec_context->height,
  484.                                                   SDL_YV12_OVERLAY, main_context->pict.screen);
  485.     if (main_context->pict.bmp == NULL) {
  486.         fprintf(stderr, "Couldn't create YUV overlay\n");
  487.         return -1;
  488.     }
  489.    
  490.     // Set initial timer value
  491.     main_context->frame_timer = (double)av_gettime() / 1000000.0;
  492.    
  493.     return 0;
  494. }
  495.  
  496. // Main demux loop
  497. static int demux_thread(void* arg) {
  498.     assert(arg != NULL);
  499.    
  500.     MainContext* main_context = (MainContext*)arg;
  501.    
  502.     int video_stream_index = main_context->video_stream->index;
  503.     int audio_stream_index = main_context->audio_stream->index;
  504.     AVPacket packet;
  505.     while (av_read_frame(main_context->format_context, &packet) >= 0) {
  506.         if (main_context->quit) {
  507.             av_free_packet(&packet);
  508.             break;
  509.         }
  510.         if (packet.stream_index == video_stream_index) {
  511.             // Video packet
  512.             packet_queue_put(&main_context->videoq, &packet);
  513.         } else if (packet.stream_index == audio_stream_index) {
  514.             // Audio packet
  515.             packet_queue_put(&main_context->audioq, &packet);
  516.         } else {
  517.             av_free_packet(&packet);
  518.         }
  519.     }
  520.     packet_queue_eof(&main_context->videoq);
  521.     packet_queue_eof(&main_context->audioq);
  522.    
  523.     return 0;
  524. }
  525.  
  526. double synchronize_video(MainContext* main_context, AVFrame *src_frame, double pts) {
  527.     assert(main_context != NULL);
  528.     assert(src_frame != NULL);
  529.    
  530.     AVCodecContext* video_codec_context = main_context->video_stream->codec;
  531.     if(pts != 0) {
  532.         /* if we have pts, set video clock to it */
  533.         main_context->video_clock = pts;
  534.     } else {
  535.         /* if we aren't given a pts, set it to the clock */
  536.         pts = main_context->video_clock;
  537.     }
  538.     /* update the video clock */
  539.     double frame_delay = av_q2d(video_codec_context->time_base);
  540.     /* if we are repeating a frame, adjust clock accordingly */
  541.     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
  542.     main_context->video_clock += frame_delay;
  543.    
  544.     return pts;
  545. }
  546.  
  547. static int video_decode_thread(void* arg) {
  548.     assert(arg != NULL);
  549.    
  550.     MainContext* main_context = (MainContext*)arg;
  551.     AVCodecContext* video_codec_context = main_context->video_stream->codec;
  552.    
  553.     AVFrame frame;
  554.     while (!main_context->quit) {
  555.         avcodec_get_frame_defaults(&frame);
  556.        
  557.         // Get packet from queue
  558.         AVPacket pkt;
  559.         if (packet_queue_get(&main_context->videoq, &pkt, 1) < 0) {
  560.             // eof queue
  561.             break;
  562.         }
  563.        
  564.         int got_frame;
  565.         int len = avcodec_decode_video2(video_codec_context, &frame, &got_frame, &pkt);
  566.         if (len < 0) {
  567.             av_free_packet(&pkt);
  568.             fprintf(stderr, "Failed to decode video frame\n");
  569.             break;
  570.         }
  571.        
  572.         if (got_frame) {
  573.             // Consider sync
  574.             double pts = frame.pkt_dts;
  575.             if (pts == AV_NOPTS_VALUE) {
  576.                 pts = frame.pkt_pts;
  577.             }
  578.             if (pts == AV_NOPTS_VALUE) {
  579.                 pts = 0;
  580.             }
  581.             pts *= av_q2d(main_context->video_stream->time_base);
  582.             pts = synchronize_video(main_context, &frame, pts);
  583.            
  584.             // Wait until picture is released
  585.             SDL_LockMutex(main_context->pict.mutex);
  586.             while (main_context->pict.ready && !main_context->quit) {
  587.                 SDL_CondWait(main_context->pict.cond, main_context->pict.mutex);
  588.             }
  589.             SDL_UnlockMutex(main_context->pict.mutex);
  590.            
  591.             if (main_context->quit) {
  592.                 break;
  593.             }
  594.            
  595.             SDL_Overlay* bmp = main_context->pict.bmp;
  596.             main_context->pict.pts = pts;
  597.            
  598.             // Convert frame to YV12 pixel format for display in SDL overlay
  599.             SDL_LockYUVOverlay(bmp);
  600.            
  601.             AVPicture pict;
  602.             pict.data[0] = bmp->pixels[0];
  603.             pict.data[1] = bmp->pixels[2];  // it's because YV12
  604.             pict.data[2] = bmp->pixels[1];
  605.            
  606.             pict.linesize[0] = bmp->pitches[0];
  607.             pict.linesize[1] = bmp->pitches[2];
  608.             pict.linesize[2] = bmp->pitches[1];
  609.            
  610.             sws_scale(main_context->sws_context,
  611.                       frame.data, frame.linesize,
  612.                       0, video_codec_context->height,
  613.                       pict.data, pict.linesize);
  614.            
  615.             SDL_UnlockYUVOverlay(bmp);
  616.            
  617.             SDL_LockMutex(main_context->pict.mutex);
  618.             main_context->pict.ready = 1;
  619.             SDL_CondSignal(main_context->pict.cond);
  620.             SDL_UnlockMutex(main_context->pict.mutex);
  621.         }
  622.     }
  623.    
  624.     return 0;
  625. }
  626.  
  627. static int audio_decode_thread(void *arg) {
  628.     assert(arg != NULL);
  629.    
  630.     MainContext* main_context = (MainContext*)arg;
  631.     AVCodecContext* audio_codec_context = main_context->audio_stream->codec;
  632.    
  633.     AVFrame frame;
  634.     while (!main_context->quit) {
  635.         avcodec_get_frame_defaults(&frame);
  636.        
  637.         // Get packet from queue
  638.         AVPacket pkt;
  639.         if (packet_queue_get(&main_context->audioq, &pkt, 1) < 0) {
  640.             // eof queue
  641.             break;
  642.         }
  643.        
  644.         // The audio packet can contain several frames
  645.         int got_frame;
  646.         int len = avcodec_decode_audio4(audio_codec_context, &frame, &got_frame, &pkt);
  647.         if (len < 0) {
  648.             av_free_packet(&pkt);
  649.             fprintf(stderr, "Failed to decode audio frame\n");
  650.             break;
  651.         }
  652.        
  653.         if (got_frame) {
  654.             // Store frame
  655.             // Get decoded buffer size
  656.             int data_size = av_samples_get_buffer_size(NULL, audio_codec_context->channels,
  657.                                                         frame.nb_samples,
  658.                                                         audio_codec_context->sample_fmt, 1);
  659.            
  660.             // Obtain audio clock
  661.             if (pkt.pts != AV_NOPTS_VALUE) {
  662.                 main_context->audio_clock = av_q2d(main_context->audio_stream->time_base) * pkt.pts;
  663.             } else {
  664.                 /* if no pts, then compute it */
  665.                 main_context->audio_clock += (double)data_size /
  666.                                                         (audio_codec_context->channels *
  667.                                                         audio_codec_context->sample_rate *
  668.                                                         av_get_bytes_per_sample(audio_codec_context->sample_fmt));
  669.             }
  670.             ring_buffer_write(&main_context->audio_buf, frame.data[0], data_size, 1);
  671.         }
  672.         av_free_packet(&pkt);
  673.     }
  674.     ring_buffer_eof(&main_context->audio_buf);
  675.     return 0;
  676. }
  677.  
  678. static uint32_t sdl_refresh_timer(uint32_t interval, void *opaque) {
  679.   SDL_Event event;
  680.   event.type = FF_REFRESH_EVENT;
  681.   event.user.data1 = opaque;
  682.   SDL_PushEvent(&event);
  683.   return 0;
  684. }
  685.  
  686. static void schedule_refresh(MainContext* main_context, int delay) {
  687.     assert(main_context != 0);
  688.     assert(delay > 0.0);
  689.    
  690.     SDL_AddTimer(delay, sdl_refresh_timer, main_context);
  691. }
  692.  
  693. static double get_audio_clock(MainContext* main_context) {
  694.     assert(main_context != NULL);
  695.    
  696.     AVCodecContext* audio_codec_context = main_context->audio_stream->codec;
  697.     double pts = main_context->audio_clock;
  698.    
  699.     int bytes_per_sec = audio_codec_context->sample_rate *
  700.                             audio_codec_context->channels *
  701.                             av_get_bytes_per_sample(audio_codec_context->sample_fmt);
  702.     int buffer_size = ring_buffer_size(&main_context->audio_buf);
  703.    
  704.     if (bytes_per_sec != 0) {
  705.         pts -= (double)buffer_size / bytes_per_sec;
  706.     }
  707.    
  708.     return pts;
  709. }
  710.  
  711. static void video_display(MainContext* main_context) {
  712.     AVCodecContext* video_codec_context = main_context->video_stream->codec;
  713.     SDL_Rect rect;
  714.     rect.x = 0;
  715.     rect.y = 0;
  716.     rect.w = video_codec_context->width;
  717.     rect.h = video_codec_context->height;
  718.     SDL_DisplayYUVOverlay(main_context->pict.bmp, &rect);
  719. }
  720.  
  721. static double compute_delay(MainContext* main_context) {
  722.     double delay = main_context->pict.pts - main_context->frame_last_pts;
  723.     if (delay <= 0.0 || delay >= 1.0) {
  724.         // Delay incorrect - use previous one
  725.         delay = main_context->frame_last_delay;
  726.     }
  727.     // Save for next time
  728.     main_context->frame_last_pts = main_context->pict.pts;
  729.     main_context->frame_last_delay = delay;
  730.  
  731.     // Update delay to sync to audio
  732.     double ref_clock = get_audio_clock(main_context);
  733.     double diff = main_context->pict.pts - ref_clock;
  734.     double sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
  735.     if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
  736.         if (diff <= -sync_threshold) {
  737.             delay = 0;
  738.         } else if (diff >= sync_threshold) {
  739.             delay = 2 * delay;
  740.         }
  741.     }
  742.  
  743.     main_context->frame_timer += delay;
  744.    
  745.     double actual_delay = main_context->frame_timer - (av_gettime() / 1000000.0);
  746.     if(actual_delay < 0.010) {
  747.         /* Really it should skip the picture instead */
  748.         actual_delay = 0.010;
  749.     }
  750.     return actual_delay;
  751. }
  752.  
  753. static void video_refresh_timer(MainContext* main_context) {
  754.     SDL_LockMutex(main_context->pict.mutex);
  755.     while ((main_context->pict.ready == 0) && !main_context->quit) {
  756.         SDL_CondWait(main_context->pict.cond, main_context->pict.mutex);
  757.     }
  758.     SDL_UnlockMutex(main_context->pict.mutex);
  759.    
  760.     if (main_context->quit) {
  761.         return;
  762.     }
  763.    
  764.     // Sync video to audio
  765.     double delay = compute_delay(main_context);
  766.     schedule_refresh(main_context, (int)(delay * 1000 + 0.5));
  767.    
  768.     // Show the picture
  769.     video_display(main_context);
  770.    
  771.     SDL_LockMutex(main_context->pict.mutex);
  772.     main_context->pict.ready = 0;
  773.     SDL_CondSignal(main_context->pict.cond);
  774.     SDL_UnlockMutex(main_context->pict.mutex);
  775. }
  776.  
  777. static MainContext* allocate_context() {
  778.     MainContext* main_context = av_mallocz(sizeof(MainContext));
  779.     if (main_context == NULL) {
  780.         // memory allocation failed
  781.         return NULL;
  782.     }
  783.    
  784.     packet_queue_init(&main_context->videoq);
  785.     packet_queue_init(&main_context->audioq);
  786.     ring_buffer_init(&main_context->audio_buf, AUDIO_BUF_SIZE, MAX_AUDIO_BUF_SIZE);
  787.    
  788.     main_context->pict.mutex = SDL_CreateMutex();
  789.     main_context->pict.cond = SDL_CreateCond();
  790.    
  791.     return main_context;
  792. }
  793.  
  794. static void free_context(MainContext* main_context) {
  795.     assert(main_context != NULL);
  796.    
  797.     // Close streams
  798.     close_stream(main_context->video_stream);
  799.     close_stream(main_context->audio_stream);
  800.    
  801.     packet_queue_deinit(&main_context->videoq);
  802.     packet_queue_deinit(&main_context->audioq);
  803.     ring_buffer_deinit(&main_context->audio_buf);
  804.    
  805.     // Free SDL resources
  806.     SDL_FreeSurface(main_context->pict.screen);
  807.     SDL_FreeYUVOverlay(main_context->pict.bmp);
  808.    
  809.     // Close file
  810.     if (main_context->format_context != NULL)  {
  811.         avformat_close_input(&main_context->format_context);
  812.     }
  813. }
  814.  
  815. static void quit(MainContext* main_context) {
  816.     main_context->quit = 1;
  817.     SDL_CondBroadcast(main_context->pict.cond);
  818. }
  819.  
  820. static void event_loop(MainContext* main_context) {
  821.     assert(main_context != NULL);
  822.    
  823.     SDL_Event event;
  824.     while (!main_context->quit) {
  825.         SDL_WaitEvent(&event);
  826.         switch (event.type) {
  827.             case SDL_QUIT:
  828.                 quit(main_context);
  829.                 break;
  830.             case FF_REFRESH_EVENT:
  831.                 video_refresh_timer(main_context);
  832.                 break;
  833.         }
  834.     }
  835. }
  836.  
  837. typedef int (SDLCALL *ThreadProc)(void *);
  838.  
  839. static SDL_Thread* thread_start(ThreadProc fn, void* userdata, const char* name) {
  840.     assert(fn != NULL);
  841.    
  842.     SDL_Thread* thread = SDL_CreateThread(fn, userdata);
  843.     if (thread == NULL) {
  844.         fprintf(stderr, "SDL: Failed to run '%s' thread - %s\n", name, SDL_GetError());
  845.     }
  846.     return thread;
  847. }
  848.  
  849. static int thread_wait(SDL_Thread* tid, const char* name) {
  850.     int status;
  851.     SDL_WaitThread(tid, &status);
  852.     printf("Thread '%s' finished with status %d\n", name, status);
  853.     return status;
  854. }
  855.  
  856. int main(int argc, char* argv[]) {
  857.     int err;
  858.     // Check arguments
  859.     if (argc < 2) {
  860.         usage(argv[0]);
  861.         return -1;
  862.     }
  863.    
  864.     // Register all available file formats and codecs
  865.     av_register_all();
  866.    
  867.     // Init SDL
  868.     err = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
  869.     if (err < 0) {
  870.         fprintf(stderr, "SDL: %s\n", SDL_GetError());
  871.         return -1;
  872.     }
  873.    
  874.     MainContext* main_context = allocate_context();
  875.  
  876.     const char* filename = argv[1];
  877.     err = open_file(main_context, filename);
  878.     if (err < 0) {
  879.         return -1;
  880.     }
  881.    
  882.     configure_audio(main_context);
  883.    
  884.     // Run required threads
  885.     main_context->demux_tid = thread_start(demux_thread, main_context, "demux");
  886.     main_context->video_decode_tid = thread_start(video_decode_thread, main_context, "video_decode");
  887.     main_context->audio_decode_tid = thread_start(audio_decode_thread, main_context, "audio_decode");
  888.    
  889.     // Start video refresh
  890.     schedule_refresh(main_context, 40);
  891.  
  892.     // Start event loop
  893.     event_loop(main_context);
  894.    
  895.     // Wait until all the threads will be finished
  896.     thread_wait(main_context->demux_tid, "demux");
  897.     thread_wait(main_context->video_decode_tid, "video_decode");
  898.     thread_wait(main_context->audio_decode_tid, "audio_decode");
  899.    
  900.     // Free resources
  901.     free_context(main_context);
  902.     SDL_Quit();
  903.    
  904.     return 0;
  905. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement