Subversion Repositories Kolibri OS

Rev

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