Subversion Repositories Kolibri OS

Rev

Rev 5592 | Rev 6106 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1.  
  2. #include <stdint.h>
  3.  
  4. #include <libavcodec/avcodec.h>
  5. #include <libavformat/avformat.h>
  6. #include <libavdevice/avdevice.h>
  7. #include <libswscale/swscale.h>
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <fcntl.h>
  12. #include <ctype.h>
  13. #include <kos32sys.h>
  14. #include "winlib/winlib.h"
  15.  
  16. #include "sound.h"
  17. #include "fplay.h"
  18.  
  19. volatile enum player_state player_state  = STOP;
  20. volatile enum player_state decoder_state = PREPARE;
  21. volatile enum player_state sound_state   = STOP;
  22.  
  23. uint32_t win_width, win_height;
  24.  
  25. void decoder();
  26. int fplay_init_context(AVCodecContext *avctx);
  27.  
  28. AVFormatContext *pFormatCtx;
  29. AVCodecContext  *pCodecCtx;
  30. AVCodecContext  *aCodecCtx;
  31. AVCodec         *pCodec;
  32. AVCodec         *aCodec;
  33. AVFrame         *pFrame;
  34. int             videoStream;
  35. int             audioStream;
  36.  
  37. int             have_sound = 0;
  38.  
  39. uint8_t     *decoder_buffer;
  40. extern int resampler_size;
  41.  
  42. extern int sample_rate;
  43. char *movie_file;
  44.  
  45. void flush_video();
  46.  
  47. queue_t  q_video;
  48. queue_t  q_audio;
  49. int64_t  rewind_pos;
  50.  
  51. int64_t stream_duration;
  52.  
  53. int threads_running = DECODER_THREAD;
  54. mutex_t driver_lock;
  55.  
  56. extern double audio_base;
  57.  
  58. double get_audio_base()
  59. {
  60.   return (double)av_q2d(pFormatCtx->streams[audioStream]->time_base)*1000;
  61. };
  62.  
  63.  
  64. int main( int argc, char *argv[])
  65. {
  66.     int i;
  67.     char *file_name, *dot;
  68.  
  69.     if(argc < 2)
  70.     {
  71.         movie_file = get_moviefile();
  72.         if(movie_file == NULL)
  73.         {
  74.             printf("Please provide a movie file\n");
  75.             return -1;
  76.         }
  77.     }
  78.     else movie_file = argv[1];
  79.  
  80.     /* register all codecs, demux and protocols */
  81.  
  82.     av_log_set_level(AV_LOG_FATAL);
  83.  
  84.     avcodec_register_all();
  85.     avdevice_register_all();
  86.     av_register_all();
  87.  
  88.     if( avformat_open_input(&pFormatCtx, movie_file, NULL, NULL) < 0)
  89.     {
  90.         printf("Cannot open file %s\n\r", movie_file);
  91.         return -1; // Couldn't open file
  92.     };
  93.  
  94.     pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
  95.  
  96.   // Retrieve stream information
  97.     if(avformat_find_stream_info(pFormatCtx, NULL)<0)
  98.     {
  99.         printf("Cannot find streams\n\r");
  100.         return -1;
  101.     };
  102.  
  103.     file_name = strrchr(movie_file,'/')+1;
  104.     dot = strrchr(file_name,'.');
  105.     if(dot)
  106.     {
  107.         movie_file = malloc(dot-file_name+1);
  108.         memcpy(movie_file, file_name, dot-file_name);
  109.         movie_file[dot-file_name] = 0;
  110.     }
  111.     else movie_file = file_name;
  112.  
  113. //    __asm__ __volatile__("int3");
  114.  
  115.     stream_duration = pFormatCtx->duration;
  116.  
  117.     printf("duration %f\n", (double)stream_duration);
  118.    // Find the first video stream
  119.     videoStream=-1;
  120.     audioStream=-1;
  121.     for(i=0; i < pFormatCtx->nb_streams; i++)
  122.     {
  123.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
  124.             && videoStream < 0)
  125.         {
  126.             videoStream=i;
  127.             video_time_base = pFormatCtx->streams[i]->time_base;
  128.             if(stream_duration == 0)
  129.                stream_duration = pFormatCtx->streams[i]->duration;
  130.  
  131.         }
  132.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
  133.             audioStream < 0)
  134.         {
  135.             audioStream=i;
  136.             if(stream_duration == 0)
  137.                stream_duration = pFormatCtx->streams[i]->duration;
  138.         }
  139.     }
  140.  
  141.     if(videoStream==-1)
  142.     {
  143.         printf("Video stream not detected\n\r");
  144.         return -1; // Didn't find a video stream
  145.     };
  146.  
  147.   //   __asm__ __volatile__("int3");
  148.  
  149.     // Get a pointer to the codec context for the video stream
  150.     pCodecCtx = pFormatCtx->streams[videoStream]->codec;
  151.     aCodecCtx = pFormatCtx->streams[audioStream]->codec;
  152.  
  153.   // Find the decoder for the video stream
  154.  
  155.  
  156.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  157.  
  158. //    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
  159.  
  160.     if(pCodec==NULL) {
  161.         printf("Unsupported codec with id %d for input stream %d\n",
  162.         pCodecCtx->codec_id, videoStream);
  163.         return -1; // Codec not found
  164.     }
  165.  
  166.     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
  167.     {
  168.         printf("Error while opening codec for input stream %d\n",
  169.                 videoStream);
  170.         return -1; // Could not open codec
  171.     };
  172.  
  173. //    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
  174.  
  175.     mutex_init(&driver_lock);
  176.     mutex_init(&q_video.lock);
  177.     mutex_init(&q_audio.lock);
  178.  
  179.     if (aCodecCtx->channels > 0)
  180.             aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels);
  181.     else
  182.             aCodecCtx->request_channels = 2;
  183.  
  184.     aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
  185.  
  186.     if(aCodec)
  187.     {
  188.         if(avcodec_open2(aCodecCtx, aCodec, NULL) >= 0 )
  189.         {
  190.             WAVEHEADER       whdr;
  191.             int fmt;
  192.             int channels;
  193.  
  194.             printf("audio stream rate %d channels %d format %d\n",
  195.             aCodecCtx->sample_rate, aCodecCtx->channels, aCodecCtx->sample_fmt );
  196.             whdr.riff_id = 0x46464952;
  197.             whdr.riff_format = 0x45564157;
  198.             whdr.wFormatTag = 0x01;
  199.             whdr.nSamplesPerSec = aCodecCtx->sample_rate;
  200.             whdr.nChannels = 2;
  201.             whdr.wBitsPerSample = 16;
  202.  
  203.             sample_rate = aCodecCtx->sample_rate;
  204.  
  205.             fmt = test_wav(&whdr);
  206.  
  207.             if( init_audio(fmt) )
  208.             {
  209.                 decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
  210.                 if( decoder_buffer != NULL )
  211.                 {
  212.                     mutex_init(&astream.lock);
  213.                     astream.count  = 0;
  214.                     astream.buffer = (char *)av_mallocz(192000*3);
  215.                     if( astream.buffer != NULL )
  216.                         have_sound = 1;
  217.                     else
  218.                         av_free(decoder_buffer);
  219.                 }
  220.                 if( have_sound == 0)
  221.                 {
  222.                         printf("Not enough memory for audio buffers\n");
  223.                 }
  224.             }
  225.         }
  226.         else printf("Cannot open audio codec\n\r");
  227.     }
  228.     else printf("Unsupported audio codec!\n");
  229.  
  230.     if( !init_video(pCodecCtx))
  231.         return 0;
  232.  
  233.     decoder();
  234.  
  235.   // Free the YUV frame
  236.     av_free(pFrame);
  237.  
  238.  
  239. //__asm__ __volatile__("int3");
  240.  
  241.     while( threads_running &
  242.            (AUDIO_THREAD | VIDEO_THREAD))
  243.            delay(1);
  244.  
  245.     if(astream.lock.handle)
  246.         mutex_destroy(&astream.lock);
  247.  
  248.     mutex_destroy(&driver_lock);
  249.     mutex_destroy(&q_video.lock);
  250.     mutex_destroy(&q_audio.lock);
  251.  
  252.     return 0;
  253. }
  254.  
  255.  
  256. static int load_frame()
  257. {
  258.     AVPacket  packet;
  259.     int err;
  260.  
  261.     err = av_read_frame(pFormatCtx, &packet);
  262.     if( err == 0)
  263.     {
  264.         if(packet.stream_index==videoStream)
  265.             put_packet(&q_video, &packet);
  266.         else if( (packet.stream_index == audioStream) &&
  267.                   (have_sound != 0) )
  268.         {
  269.             put_packet(&q_audio, &packet);
  270.             if(audio_base == -1.0)
  271.             {
  272.                 if (packet.pts != AV_NOPTS_VALUE)
  273.                     audio_base = get_audio_base() * packet.pts;
  274. //                    printf("audio base %f\n", audio_base);
  275.             };
  276.         }
  277.         else av_free_packet(&packet);
  278.     }
  279.     else if (err != AVERROR_EOF)
  280.         printf("av_read_frame: error %x\n", err);
  281.  
  282.     return err;
  283. }
  284.  
  285.  
  286.  
  287. static int fill_queue()
  288. {
  289.     int err = 0;
  290.     AVPacket  packet;
  291.  
  292.     while( (q_video.size < 4*1024*1024) &&
  293.             !err )
  294.         err = load_frame();
  295.  
  296.     return err;
  297.  
  298. };
  299.  
  300.  
  301. static void flush_all()
  302. {
  303.     AVPacket  packet;
  304.  
  305.     avcodec_flush_buffers(pCodecCtx);
  306.     avcodec_flush_buffers(aCodecCtx);
  307.     while( get_packet(&q_video, &packet) != 0)
  308.         av_free_packet(&packet);
  309.  
  310.     while( get_packet(&q_audio, &packet)!= 0)
  311.         av_free_packet(&packet);
  312.  
  313.     flush_video();
  314.  
  315.     astream.count = 0;
  316. };
  317.  
  318. void decoder()
  319. {
  320.     int       eof;
  321.     AVPacket  packet;
  322.     int       ret, vret, aret;
  323.  
  324.     int64_t   min_pos, max_pos;
  325.  
  326. //    av_log_set_level(AV_LOG_DEBUG);
  327.  
  328.     while( player_state != CLOSED )
  329.     {
  330.         int err;
  331.  
  332.         switch(decoder_state)
  333.         {
  334.             case PREPARE:
  335.                 eof = fill_queue();
  336.  
  337.                 do
  338.                 {
  339.                     if( (q_video.size < 4*1024*1024) &&
  340.                         (eof == 0) )
  341.                     {
  342.                         eof = load_frame();
  343.                     }
  344.                     decode_video(pCodecCtx, &q_video);
  345.                     ret = decode_audio(aCodecCtx, &q_audio);
  346.                 }while(astream.count < resampler_size*2 &&
  347.                        ret == 1);
  348.  
  349.                 sound_state   = PREPARE;
  350.                 decoder_state = PLAY;
  351.                 player_state  = PLAY;
  352.  
  353.             case PLAY:
  354.                 if( (q_video.size < 4*1024*1024) &&
  355.                     (eof == 0) )
  356.                 {
  357.                     eof = load_frame();
  358.                 }
  359.                 vret = decode_video(pCodecCtx, &q_video);
  360.                 aret = decode_audio(aCodecCtx, &q_audio);
  361.                 ret = vret | aret;
  362.  
  363.                 if( eof && !ret)
  364.                 {
  365.                     decoder_state = STOP;
  366.                     continue;
  367.                 };
  368.  
  369.                 if( (vret & aret) == -1)
  370.                 {
  371.                     if( (q_video.size < 4*1024*1024) &&
  372.                         (eof == 0) )
  373.                     {
  374.                         eof = load_frame();
  375.                         yield();
  376.                         continue;
  377.                     };
  378.                     delay(1);
  379.                     continue;
  380.                 }
  381.  
  382.                 yield();
  383.                 continue;
  384.  
  385.             case STOP:
  386.                 delay(1);
  387.                 continue;
  388.  
  389.  
  390.             case PLAY_2_STOP:
  391.                 while(sound_state != STOP)
  392.                     delay(1);
  393.  
  394.                 flush_all();
  395.  
  396.                 if (pFormatCtx->start_time != AV_NOPTS_VALUE)
  397.                     rewind_pos = pFormatCtx->start_time;
  398.                 else
  399.                     rewind_pos = 0;
  400.  
  401.                 ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
  402.                                          rewind_pos, INT64_MAX, 0);
  403.  
  404.                 decoder_state = STOP;
  405.                 break;
  406.  
  407.             case REWIND:
  408.                 while(sound_state != STOP)
  409.                     yield();
  410.  
  411.                 flush_all();
  412.                 int opts = 0;
  413.                 if(rewind_pos < 0)
  414.                 {
  415.                     rewind_pos = -rewind_pos;
  416.                     opts = AVSEEK_FLAG_BACKWARD;
  417.                 };
  418.  
  419.                 if (pFormatCtx->start_time != AV_NOPTS_VALUE)
  420.                     rewind_pos += pFormatCtx->start_time;
  421.  
  422. //                printf("rewind %8"PRId64"\n", rewind_pos);
  423.                 min_pos = rewind_pos - 1000000;
  424.                 max_pos = rewind_pos + 1000000;
  425.  
  426.                 ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
  427.                                          rewind_pos, INT64_MAX, 0);
  428.  
  429.                 if (ret < 0)
  430.                 {
  431.                     printf("could not seek to position %f\n",
  432.                             (double)rewind_pos / AV_TIME_BASE);
  433.                 }
  434.  
  435. //                printf("restart\n");
  436.                 decoder_state = PREPARE;
  437.                 break;
  438.         }
  439.     };
  440.  
  441. };
  442.  
  443.