Subversion Repositories Kolibri OS

Rev

Rev 5592 | 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.  
  27. AVFormatContext *pFormatCtx;
  28. AVCodecContext  *pCodecCtx;
  29. AVCodecContext  *aCodecCtx;
  30. AVCodec         *pCodec;
  31. AVCodec         *aCodec;
  32. AVFrame         *pFrame;
  33. int             videoStream;
  34. int             audioStream;
  35.  
  36. int             have_sound = 0;
  37.  
  38. uint8_t     *decoder_buffer;
  39. extern int resampler_size;
  40.  
  41. extern int sample_rate;
  42. char *movie_file;
  43.  
  44. void flush_video();
  45.  
  46. queue_t  q_video;
  47. queue_t  q_audio;
  48. int64_t  rewind_pos;
  49.  
  50. int64_t stream_duration;
  51.  
  52. extern double audio_base;
  53.  
  54. double get_audio_base()
  55. {
  56.  
  57.   return (double)av_q2d(pFormatCtx->streams[audioStream]->time_base)*1000;
  58.  
  59. };
  60.  
  61.  
  62.  
  63. int main( int argc, char *argv[])
  64. {
  65.     int i;
  66.     char *file_name, *dot;
  67.  
  68.     if(argc < 2)
  69.     {
  70.         movie_file = get_moviefile();
  71.         if(movie_file == NULL)
  72.         {
  73.             printf("Please provide a movie file\n");
  74.             return -1;
  75.         }
  76.     }
  77.     else movie_file = argv[1];
  78.  
  79.     /* register all codecs, demux and protocols */
  80.  
  81. #if 0
  82.     {
  83.         int fd, i;
  84.         char *buff;
  85.         uint32_t start, stop;
  86.  
  87.         fd = open(movie_file,O_RDONLY);
  88.  
  89.         if(fd < 0)
  90.             return 0;
  91.  
  92.         buff = user_alloc(65536);
  93.         memset(buff, 0, 65536);
  94.  
  95.         start = get_tick_count();
  96.  
  97.         for(i = 0; i < 1024*1024*1024; i+=65536)
  98.         {
  99.             if(read(fd, buff, 65536) < 0)
  100.                 break;
  101.  
  102.         };
  103.         stop = get_tick_count();
  104.  
  105.         printf("average speed %d Kbytes/c\n", ((i/1024)*100)/(stop-start));
  106.     };
  107.     return 0;
  108. };
  109.  
  110. #else
  111.  
  112.     av_log_set_level(AV_LOG_FATAL);
  113.  
  114.     avcodec_register_all();
  115.     avdevice_register_all();
  116.     av_register_all();
  117.  
  118. //    init_pixlib(HW_BIT_BLIT|HW_TEX_BLIT);
  119.  
  120.     if( avformat_open_input(&pFormatCtx, movie_file, NULL, NULL) < 0)
  121.     {
  122.         printf("Cannot open file %s\n\r", movie_file);
  123.         return -1; // Couldn't open file
  124.     };
  125.  
  126.     pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
  127.  
  128.   // Retrieve stream information
  129.     if(avformat_find_stream_info(pFormatCtx, NULL)<0)
  130.     {
  131.         printf("Cannot find streams\n\r");
  132.         return -1;
  133.     };
  134.  
  135.     file_name = strrchr(movie_file,'/')+1;
  136.     dot = strrchr(file_name,'.');
  137.     if(dot)
  138.     {
  139.         movie_file = malloc(dot-file_name+1);
  140.         memcpy(movie_file, file_name, dot-file_name);
  141.         movie_file[dot-file_name] = 0;
  142.     }
  143.     else movie_file = file_name;
  144.  
  145.  
  146. //    __asm__ __volatile__("int3");
  147.  
  148. //  dump_format(pFormatCtx, 0, argv[1], 0);
  149.  
  150. //    stream_duration = 1000.0 * pFormatCtx->duration * av_q2d(AV_TIME_BASE_Q);
  151.     stream_duration = pFormatCtx->duration;
  152.  
  153.     printf("duration %f\n", (double)stream_duration);
  154.    // Find the first video stream
  155.     videoStream=-1;
  156.     audioStream=-1;
  157.     for(i=0; i < pFormatCtx->nb_streams; i++)
  158.     {
  159. //        pFormatCtx->streams[i]->discard = AVDISCARD_ALL;
  160.  
  161.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
  162.             && videoStream < 0)
  163.         {
  164.             videoStream=i;
  165.             video_time_base = pFormatCtx->streams[i]->time_base;
  166.             if(stream_duration == 0)
  167. //                stream_duration = 1000.0 *
  168. //                              pFormatCtx->streams[i]->duration *
  169. //                              av_q2d(pFormatCtx->streams[i]->time_base);
  170.                stream_duration = pFormatCtx->streams[i]->duration;
  171.  
  172.         }
  173.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
  174.             audioStream < 0)
  175.         {
  176.             audioStream=i;
  177.             if(stream_duration == 0)
  178. //                stream_duration = 1000.0 *
  179. //                              pFormatCtx->streams[i]->duration *
  180. //                              av_q2d(pFormatCtx->streams[i]->time_base);
  181.                stream_duration = pFormatCtx->streams[i]->duration;
  182.  
  183.         }
  184.     }
  185.  
  186.     if(videoStream==-1)
  187.     {
  188.         printf("Video stream not detected\n\r");
  189.         return -1; // Didn't find a video stream
  190.     };
  191.  
  192. #if 0
  193.     {
  194.         AVPacket  packet;
  195.         int psize = 0;
  196.         uint32_t start, stop;
  197.  
  198.         int err;
  199.         start = get_tick_count();
  200.  
  201.         while(psize < 1024*1024*1024)
  202.         {
  203.             err = av_read_frame(pFormatCtx, &packet);
  204.             if(err != 0)
  205.                 break;
  206.             psize+= packet.size;
  207.             av_free_packet(&packet);
  208.         };
  209.  
  210.         stop = get_tick_count();
  211.  
  212.         printf("average speed %d Kbytes/c\n", ((psize/1024)*100)/(stop-start));
  213.  
  214.         return 1;
  215.     };
  216. };
  217. #else
  218.  
  219.  
  220.   //   __asm__ __volatile__("int3");
  221.  
  222.     // Get a pointer to the codec context for the video stream
  223.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  224.     aCodecCtx=pFormatCtx->streams[audioStream]->codec;
  225.  
  226.   // Find the decoder for the video stream
  227.  
  228. //    init_hw_context(pCodecCtx);
  229.  
  230.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  231.  
  232. //    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
  233.  
  234.     if(pCodec==NULL) {
  235.         printf("Unsupported codec with id %d for input stream %d\n",
  236.         pCodecCtx->codec_id, videoStream);
  237.         return -1; // Codec not found
  238.     }
  239.  
  240.     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
  241.     {
  242.         printf("Error while opening codec for input stream %d\n",
  243.                 videoStream);
  244.         return -1; // Could not open codec
  245.     };
  246.  
  247. //    printf("ctx->pix_fmt %d\n", pCodecCtx->pix_fmt);
  248.  
  249.  
  250.     if (aCodecCtx->channels > 0)
  251.             aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels);
  252.     else
  253.             aCodecCtx->request_channels = 2;
  254.  
  255.     aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
  256.  
  257.     if(aCodec)
  258.     {
  259.         if(avcodec_open2(aCodecCtx, aCodec, NULL) >= 0 )
  260.         {
  261.             WAVEHEADER       whdr;
  262.             int fmt;
  263.             int channels;
  264.  
  265.             printf("audio stream rate %d channels %d format %d\n",
  266.             aCodecCtx->sample_rate, aCodecCtx->channels, aCodecCtx->sample_fmt );
  267.             whdr.riff_id = 0x46464952;
  268.             whdr.riff_format = 0x45564157;
  269.             whdr.wFormatTag = 0x01;
  270.             whdr.nSamplesPerSec = aCodecCtx->sample_rate;
  271.             whdr.nChannels = 2;
  272.             whdr.wBitsPerSample = 16;
  273.  
  274.             sample_rate = aCodecCtx->sample_rate;
  275.  
  276.             fmt = test_wav(&whdr);
  277.  
  278.             if( init_audio(fmt) )
  279.             {
  280.                 decoder_buffer = (uint8_t*)av_mallocz(192000*2+64);
  281.                 if( decoder_buffer != NULL )
  282.                 {
  283.                     astream.lock   = 0;
  284.                     astream.count  = 0;
  285.                     astream.buffer = (char *)av_mallocz(192000*3);
  286.                     if( astream.buffer != NULL )
  287.                         have_sound = 1;
  288.                     else
  289.                         av_free(decoder_buffer);
  290.                 }
  291.                 if( have_sound == 0)
  292.                 {
  293.                         printf("Not enough memory for audio buffers\n");
  294.                 }
  295.             }
  296.         }
  297.         else printf("Cannot open audio codec\n\r");
  298.     }
  299.     else printf("Unsupported audio codec!\n");
  300.  
  301.     if( !init_video(pCodecCtx))
  302.         return 0;
  303.  
  304. //    __asm__ __volatile__("int3");
  305.  
  306.     decoder();
  307.  
  308.   // Free the YUV frame
  309.     av_free(pFrame);
  310.  
  311.  
  312. //__asm__ __volatile__("int3");
  313.  
  314.   // Close the codec
  315.  // avcodec_close(pCodecCtx);
  316.  
  317.   // Close the video file
  318.  // av_close_input_file(pFormatCtx);
  319.  
  320. //__asm__ __volatile__("int3");
  321.  
  322.     return 0;
  323. }
  324.  
  325.  
  326. static int load_frame()
  327. {
  328.     AVPacket  packet;
  329.     int err;
  330.  
  331.     err = av_read_frame(pFormatCtx, &packet);
  332.     if( err == 0)
  333.     {
  334.         if(packet.stream_index==videoStream)
  335.             put_packet(&q_video, &packet);
  336.         else if( (packet.stream_index == audioStream) &&
  337.                   (have_sound != 0) )
  338.         {
  339.             put_packet(&q_audio, &packet);
  340.             if(audio_base == -1.0)
  341.             {
  342.                 if (packet.pts != AV_NOPTS_VALUE)
  343.                     audio_base = get_audio_base() * packet.pts;
  344. //                    printf("audio base %f\n", audio_base);
  345.             };
  346.         }
  347.         else av_free_packet(&packet);
  348.     }
  349.     else if (err != AVERROR_EOF)
  350.         printf("av_read_frame: error %x\n", err);
  351.  
  352.     return err;
  353. }
  354.  
  355.  
  356.  
  357. static int fill_queue()
  358. {
  359.     int err = 0;
  360.     AVPacket  packet;
  361.  
  362. //        __asm__ __volatile__("int3");
  363.  
  364.     while( (q_video.size < 4*1024*1024) &&
  365.             !err )
  366.         err = load_frame();
  367.  
  368.     return err;
  369.  
  370. };
  371.  
  372.  
  373. static void flush_all()
  374. {
  375.     AVPacket  packet;
  376.  
  377.     avcodec_flush_buffers(pCodecCtx);
  378.     avcodec_flush_buffers(aCodecCtx);
  379.     while( get_packet(&q_video, &packet) != 0)
  380.         av_free_packet(&packet);
  381.  
  382.     while( get_packet(&q_audio, &packet)!= 0)
  383.         av_free_packet(&packet);
  384.  
  385.     flush_video();
  386.  
  387.     astream.count = 0;
  388. };
  389.  
  390. void decoder()
  391. {
  392.     int       eof;
  393.     AVPacket  packet;
  394.     int       ret, vret, aret;
  395.  
  396.     int64_t   min_pos, max_pos;
  397.  
  398.     while( player_state != CLOSED )
  399.     {
  400.         int err;
  401.  
  402. //        __asm__ __volatile__("int3");
  403.  
  404.         switch(decoder_state)
  405.         {
  406.             case PREPARE:
  407.                 eof = fill_queue();
  408.  
  409.                 do
  410.                 {
  411.                     if( (q_video.size < 4*1024*1024) &&
  412.                         (eof == 0) )
  413.                     {
  414.                         eof = load_frame();
  415.                     }
  416.                     decode_video(pCodecCtx, &q_video);
  417.                     ret = decode_audio(aCodecCtx, &q_audio);
  418.                 }while(astream.count < resampler_size*2 &&
  419.                        ret == 1);
  420.  
  421.                 sound_state   = PREPARE;
  422.                 decoder_state = PLAY;
  423.                 player_state  = PLAY;
  424.  
  425.             case PLAY:
  426.                 if( (q_video.size < 4*1024*1024) &&
  427.                     (eof == 0) )
  428.                 {
  429.                     eof = load_frame();
  430.                 }
  431.                 vret = decode_video(pCodecCtx, &q_video);
  432.                 aret = decode_audio(aCodecCtx, &q_audio);
  433.                 ret = vret | aret;
  434.  
  435.                 if( eof && !ret)
  436.                 {
  437.                     decoder_state = STOP;
  438.                     continue;
  439.                 };
  440.  
  441.                 if( (vret & aret) == -1)
  442.                 {
  443.                     if( (q_video.size < 4*1024*1024) &&
  444.                         (eof == 0) )
  445.                     {
  446.                         eof = load_frame();
  447.                         yield();
  448.                         continue;
  449.                     };
  450.                     delay(1);
  451.                     continue;
  452.                 }
  453.  
  454.                 yield();
  455.                 continue;
  456.  
  457.             case STOP:
  458.                 delay(1);
  459.                 continue;
  460.  
  461.  
  462.             case PLAY_2_STOP:
  463.                 while(sound_state != STOP)
  464.                     delay(1);
  465.  
  466.                 flush_all();
  467.  
  468.                 if (pFormatCtx->start_time != AV_NOPTS_VALUE)
  469.                     rewind_pos = pFormatCtx->start_time;
  470.                 else
  471.                     rewind_pos = 0;
  472.  
  473.                 ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
  474.                                          rewind_pos, INT64_MAX, 0);
  475.  
  476.                 decoder_state = STOP;
  477.                 break;
  478.  
  479.             case REWIND:
  480.                 while(sound_state != STOP)
  481.                     yield();
  482.  
  483.                 flush_all();
  484.                 int opts = 0;
  485.                 if(rewind_pos < 0)
  486.                 {
  487.                     rewind_pos = -rewind_pos;
  488.                     opts = AVSEEK_FLAG_BACKWARD;
  489.                 };
  490.  
  491.                 if (pFormatCtx->start_time != AV_NOPTS_VALUE)
  492.                     rewind_pos += pFormatCtx->start_time;
  493.  
  494. //                printf("rewind %8"PRId64"\n", rewind_pos);
  495.                 min_pos = rewind_pos - 1000000;
  496.                 max_pos = rewind_pos + 1000000;
  497.  
  498.                 ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
  499.                                          rewind_pos, INT64_MAX, 0);
  500.  
  501. //                ret = avformat_seek_file(pFormatCtx, -1, min_pos,
  502. //                                         rewind_pos, max_pos, opts);
  503. //            __asm__ __volatile__("int3");
  504.  
  505.                 if (ret < 0)
  506.                 {
  507.                     printf("could not seek to position %f\n",
  508.                             (double)rewind_pos / AV_TIME_BASE);
  509.                 }
  510.  
  511. //                printf("restart\n");
  512.                 decoder_state = PREPARE;
  513.                 break;
  514.         }
  515.     };
  516.  
  517.     ret = 1;
  518.  
  519.     while( (player_state != CLOSED) && ret)
  520.     {
  521.         ret =  decode_video(pCodecCtx, &q_video);
  522.         ret |= decode_audio(aCodecCtx, &q_audio);
  523.         delay(1);
  524.     };
  525.     delay(50);
  526.     player_state = CLOSED;
  527.     delay(300);
  528. };
  529. #endif
  530. #endif
  531.