Subversion Repositories Kolibri OS

Rev

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