Subversion Repositories Kolibri OS

Rev

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