Subversion Repositories Kolibri OS

Rev

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