Subversion Repositories Kolibri OS

Rev

Rev 2427 | Go to most recent revision | Blame | Last modification | View Log | Download | 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 "../winlib/winlib.h"
  14.  
  15. #include "sound.h"
  16. #include "fplay.h"
  17.  
  18. volatile enum player_state player_state;
  19.  
  20. uint32_t win_width, win_height;
  21.  
  22. void decoder();
  23.  
  24. AVFormatContext *pFormatCtx;
  25. AVCodecContext  *pCodecCtx;
  26. AVCodecContext  *aCodecCtx;
  27. AVCodec         *pCodec;
  28. AVCodec         *aCodec;
  29. AVFrame         *pFrame;
  30. int             videoStream;
  31. int             audioStream;
  32.  
  33. int             have_sound = 0;
  34.  
  35. uint8_t     *decoder_buffer;
  36. extern int sample_rate;
  37. char *movie_file;
  38.  
  39. void flush_video();
  40.  
  41. queue_t  q_video;
  42. queue_t  q_audio;
  43. int64_t  rewind_pos;
  44.  
  45. int64_t stream_duration;
  46.  
  47. extern double audio_base;
  48.  
  49. double get_audio_base()
  50. {
  51.  
  52.   return (double)av_q2d(pFormatCtx->streams[audioStream]->time_base)*1000;
  53.  
  54. };
  55.  
  56.  
  57. int main( int argc, char *argv[])
  58. {
  59.     int i;
  60.  
  61.     if(argc < 2) {
  62.         printf("Please provide a movie file\n");
  63.         return -1;
  64.     }
  65.  
  66.     movie_file = argv[1];
  67.     /* register all codecs, demux and protocols */
  68.  
  69. //    av_log_set_level(AV_LOG_INFO);
  70.  
  71.     avcodec_register_all();
  72.     avdevice_register_all();
  73.     av_register_all();
  74.  
  75.     if( avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) < 0)
  76.     {
  77.         printf("Cannot open file %s\n\r", argv[1]);
  78.         return -1; // Couldn't open file
  79.     };
  80.  
  81.     pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
  82.  
  83.   // Retrieve stream information
  84.     if(avformat_find_stream_info(pFormatCtx, NULL)<0)
  85.     {
  86.         printf("Cannot find streams\n\r");
  87.         return -1;
  88.     };
  89.  
  90. //    __asm__ __volatile__("int3");
  91.  
  92. //  dump_format(pFormatCtx, 0, argv[1], 0);
  93.  
  94. //    stream_duration = 1000.0 * pFormatCtx->duration * av_q2d(AV_TIME_BASE_Q);
  95.     stream_duration = pFormatCtx->duration;
  96.    
  97.     printf("duration %f\n", (double)stream_duration);
  98.    // Find the first video stream
  99.     videoStream=-1;
  100.     audioStream=-1;
  101.     for(i=0; i < pFormatCtx->nb_streams; i++)
  102.     {
  103. //        pFormatCtx->streams[i]->discard = AVDISCARD_ALL;
  104.  
  105.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
  106.             && videoStream < 0)
  107.         {
  108.             videoStream=i;
  109.             video_time_base = pFormatCtx->streams[i]->time_base;
  110.             if(stream_duration == 0)
  111. //                stream_duration = 1000.0 *
  112. //                              pFormatCtx->streams[i]->duration *
  113. //                              av_q2d(pFormatCtx->streams[i]->time_base);
  114.                stream_duration = pFormatCtx->streams[i]->duration;
  115.                              
  116.         }
  117.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
  118.             audioStream < 0)
  119.         {
  120.             audioStream=i;
  121.             if(stream_duration == 0)
  122. //                stream_duration = 1000.0 *
  123. //                              pFormatCtx->streams[i]->duration *
  124. //                              av_q2d(pFormatCtx->streams[i]->time_base);
  125.                stream_duration = pFormatCtx->streams[i]->duration;
  126.  
  127.         }
  128.     }
  129.  
  130.     if(videoStream==-1)
  131.     {
  132.         printf("Video stream not detected\n\r");
  133.         return -1; // Didn't find a video stream
  134.     }
  135.  
  136.     player_state = PLAY_INIT;
  137.  
  138.  //   __asm__ __volatile__("int3");
  139.  
  140.     // Get a pointer to the codec context for the video stream
  141.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  142.     aCodecCtx=pFormatCtx->streams[audioStream]->codec;
  143.  
  144.   // Find the decoder for the video stream
  145.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  146.     if(pCodec==NULL) {
  147.         printf("Unsupported codec with id %d for input stream %d\n",
  148.         pCodecCtx->codec_id, videoStream);
  149.         return -1; // Codec not found
  150.     }
  151.  
  152.     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
  153.     {
  154.         printf("Error while opening codec for input stream %d\n",
  155.                 videoStream);
  156.         return -1; // Could not open codec
  157.     };
  158.  
  159.     if (aCodecCtx->channels > 0)
  160.             aCodecCtx->request_channels = FFMIN(2, aCodecCtx->channels);
  161.     else
  162.             aCodecCtx->request_channels = 2;
  163.  
  164.     aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
  165.  
  166.     if(aCodec)
  167.     {
  168.         if(avcodec_open2(aCodecCtx, aCodec, NULL) >= 0 )
  169.         {
  170.             WAVEHEADER       whdr;
  171.             int fmt;
  172.  
  173.             printf("audio stream rate %d channels %d\n",
  174.             aCodecCtx->sample_rate, aCodecCtx->channels);
  175.  
  176.             whdr.riff_id = 0x46464952;
  177.             whdr.riff_format = 0x45564157;
  178.             whdr.wFormatTag = 0x01;
  179.             whdr.nSamplesPerSec = aCodecCtx->sample_rate;
  180.             whdr.nChannels = aCodecCtx->channels;
  181.             whdr.wBitsPerSample = 16;
  182.  
  183.             sample_rate = aCodecCtx->sample_rate;
  184.  
  185.             fmt = test_wav(&whdr);
  186.  
  187.             if( init_audio(fmt) )
  188.             {
  189.                 decoder_buffer = (uint8_t*)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE*2+64);
  190.                 if( decoder_buffer != NULL )
  191.                 {
  192.                     astream.lock   = 0;
  193.                     astream.count  = 0;
  194.                     astream.buffer = (char *)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE*8);
  195.                     if( astream.buffer != NULL )
  196.                         have_sound = 1;
  197.                     else
  198.                         av_free(decoder_buffer);
  199.                 }
  200.                 if( have_sound == 0)
  201.                 {
  202.                         printf("Not enough memory for audio buffers\n");
  203.                 }
  204.             }
  205.         }
  206.         else printf("Cannot open audio codec\n\r");
  207.     }
  208.     else printf("Unsupported audio codec!\n");
  209.  
  210.     if( !init_video(pCodecCtx))
  211.         return 0;
  212.  
  213. //    __asm__ __volatile__("int3");
  214.  
  215.     decoder();
  216.  
  217.   // Free the YUV frame
  218.     av_free(pFrame);
  219.  
  220.  
  221. //__asm__ __volatile__("int3");
  222.  
  223.   // Close the codec
  224.  // avcodec_close(pCodecCtx);
  225.  
  226.   // Close the video file
  227.  // av_close_input_file(pFormatCtx);
  228.  
  229. //__asm__ __volatile__("int3");
  230.  
  231.     return 0;
  232. }
  233.  
  234.  
  235. static int fill_queue()
  236. {
  237.     int eof = 0;
  238.     AVPacket  packet;
  239.  
  240.     while( !eof)
  241.     {
  242.         int err;
  243.  
  244. //        __asm__ __volatile__("int3");
  245.  
  246.         if(q_video.size+q_audio.size < 2*1024*1024)
  247.         {
  248.             err = av_read_frame(pFormatCtx, &packet);
  249.             if( err < 0)
  250.             {
  251.                 eof = 1;
  252.                 if (err != AVERROR_EOF)
  253.                     printf("av_read_frame: error %x\n", err);
  254.                 break;
  255.             }
  256.             if(packet.stream_index==videoStream)
  257.             {
  258.                 put_packet(&q_video, &packet);
  259.             }
  260.             else if( (packet.stream_index == audioStream) &&
  261.                  (have_sound != 0) )
  262.             {
  263.                 put_packet(&q_audio, &packet);
  264.                 if(audio_base == -1.0)
  265.                 {
  266.                     if (packet.dts != AV_NOPTS_VALUE)
  267.                         audio_base = get_audio_base() * packet.dts;
  268. //                    printf("audio base %f\n", audio_base);
  269.                 };
  270.             }
  271.             else
  272.             {
  273.                 av_free_packet(&packet);
  274.             };
  275.         }
  276.         else break;
  277.     };
  278.  
  279.     return eof;
  280.  
  281. };
  282.  
  283.  
  284. void decoder()
  285. {
  286.     int       eof;
  287.     AVPacket  packet;
  288.     int       ret;
  289.  
  290.     eof = fill_queue();
  291.  
  292.     while( player_state != CLOSED && !eof)
  293.     {
  294.         int err;
  295.  
  296. //        __asm__ __volatile__("int3");
  297.  
  298.         if( player_state == PAUSE )
  299.         {
  300.             delay(1);
  301.             continue;
  302.         };
  303.  
  304.         if( player_state == REWIND )
  305.         {
  306.  //           int64_t timestamp = 0;
  307.  //           int stream_index = av_find_default_stream_index(pFormatCtx);
  308.  
  309.  //           __asm__ __volatile__("int3");
  310.  
  311.             if (pFormatCtx->start_time != AV_NOPTS_VALUE)
  312.                 rewind_pos += pFormatCtx->start_time;
  313.  
  314.             printf("rewind %8"PRId64"\n", rewind_pos);
  315.            
  316.             ret = avformat_seek_file(pFormatCtx, -1, INT64_MIN,
  317.                                      rewind_pos, INT64_MAX, 0);
  318. //            ret = avformat_seek_file(pFormatCtx, -1, 0,
  319. //                                 0, INT64_MAX, 0);
  320. //            __asm__ __volatile__("int3");
  321.  
  322.             if (ret < 0)
  323.             {
  324.                 printf("could not seek to position %f\n",
  325.                         (double)rewind_pos / AV_TIME_BASE);
  326.             }
  327.             else
  328.             {
  329.                 avcodec_flush_buffers(pCodecCtx);
  330.                 avcodec_flush_buffers(aCodecCtx);
  331.  
  332.                 while( get_packet(&q_video, &packet) != 0)
  333.                     av_free_packet(&packet);
  334.  
  335.                 while( get_packet(&q_audio, &packet)!= 0)
  336.                     av_free_packet(&packet);
  337.                 audio_base = -1.0;
  338.  
  339.   //              __asm__ __volatile__("int3");
  340.  
  341.                 eof = fill_queue();
  342.             };
  343.             yield();
  344.  
  345.             flush_video();
  346.  
  347.             player_state = REWIND_2_PLAY;
  348.             printf("restart\n");
  349.             continue;
  350.         };
  351.  
  352.         if(q_video.size+q_audio.size < 4*1024*1024)
  353.         {
  354.             err = av_read_frame(pFormatCtx, &packet);
  355.             if( err < 0)
  356.             {
  357.                 eof = 1;
  358.                 if (err != AVERROR_EOF)
  359.                     printf("av_read_frame: error %x\n", err);
  360.                 continue;
  361.             }
  362.             if(packet.stream_index==videoStream)
  363.             {
  364.                 put_packet(&q_video, &packet);
  365.             }
  366.             else if( (packet.stream_index == audioStream) &&
  367.                  (have_sound != 0) )
  368.             {
  369.                 put_packet(&q_audio, &packet);
  370.             }
  371.             else
  372.             {
  373.                 av_free_packet(&packet);
  374.             };
  375.             decode_video(pCodecCtx, &q_video);
  376.             decode_audio(aCodecCtx, &q_audio);
  377.             continue;
  378.         };
  379.         decode_video(pCodecCtx, &q_video);
  380.         decode_audio(aCodecCtx, &q_audio);
  381.         delay(1);
  382.     };
  383.  
  384.     ret = 1;
  385.  
  386.     while( (player_state != CLOSED) && ret)
  387.     {
  388.         ret =  decode_video(pCodecCtx, &q_video);
  389.         ret |= decode_audio(aCodecCtx, &q_audio);
  390.         delay(1);
  391.     };
  392.     delay(50);
  393.     player_state = CLOSED;
  394.     delay(300);
  395. };
  396.  
  397.