Advertisement
mnguyen

av_interleaved_write_frame issue

Sep 10th, 2014
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.79 KB | None | 0 0
  1. int renderMovieRequest(movieRequest *movieRequestObj, string outputPath) {
  2.     AVFormatContext *pFormatCtx = NULL;
  3.     size_t            i;
  4.     int             videoStream;
  5.     AVCodecContext  *pCodecCtx = NULL;
  6.     AVCodec         *pCodec = NULL;
  7.     AVFrame         *pFrame = NULL;
  8.     AVFrame         *pFrameRGB = NULL;
  9.     AVPacket        packet = { 0 };
  10.     int             frameFinished;
  11.     int             numBytes;
  12.     uint8_t         *buffer = NULL;
  13.     AVDictionary    *optionsDict = NULL;
  14.     struct SwsContext      *sws_ctx = NULL;
  15.  
  16.     // read in the protobuf file.
  17.     processProtobuf(movieRequestObj);
  18.  
  19.     // Register all formats and codecs
  20.     av_register_all();
  21.  
  22.     vector<clipShPtr> * clips = &(movieRequestObj->clips);
  23.  
  24.     for (size_t clipIdx = 0; clipIdx < clips->size(); ++clipIdx) {
  25.  
  26.         shared_ptr<clip> currentClip = clips->at(clipIdx);
  27.         switch (currentClip->getClipType()) {
  28.             case VIDEO_CLIP: {
  29.                 shared_ptr<videoClip> vidClip = dynamic_pointer_cast<videoClip>(clips->at(clipIdx));
  30.  
  31.                 if (vidClip->shouldHaveSegments) {
  32.                     DLOG("Found segments... :");
  33.                     // add clips to new video
  34.                     // open the file for reading and create a temporary file for output
  35. //                    if (openVideo(pFormatCtx, vidClip->vidFileName.c_str()) != 0) {
  36.                    if(avformat_open_input(&pFormatCtx, vidClip->vidFileName.c_str(), NULL, NULL)!=0) {
  37.                         ELOG("Can't open file!");
  38.                         return -1; // Couldn't open file
  39.                     }
  40.                   // Retrieve stream information
  41.                   if(avformat_find_stream_info(pFormatCtx, NULL)<0)
  42.                     return -1; // Couldn't find stream information
  43.  
  44.                         DLOG("Opened file for reading !! ");
  45.                     // Find the first video stream
  46.                     videoStream=-1;
  47.                     for(i=0; i < pFormatCtx->nb_streams; i++) {
  48.                         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
  49.                             DLOG("Identified stream %i as video stream", i);
  50.                             videoStream=i;
  51.                             break;
  52.                         }
  53.                     }
  54.  
  55.                     if(videoStream==-1) {
  56.                         ELOG("Couldn't find a video stream for %s", vidClip->vidFileName.c_str());
  57.                         return -1; // Didn't find a video stream
  58.                     }
  59.  
  60.                     DLOG("Found video stream getting pointer to codec context");
  61.                     // Get a pointer to the codec context for the video stream
  62.                     pCodecCtx = pFormatCtx->streams[videoStream]->codec;
  63.                     // Find the decoder for the video stream
  64.                     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  65.  
  66.                     if(pCodec==NULL) {
  67.                         ELOG("Unsupported codec!\n");
  68.                         return -1; // Codec not found
  69.                     }
  70.                   // Open codec
  71.                     if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0)
  72.                         return -1; // Could not open codec
  73.  
  74.                 // get the timebase
  75.                     timeBase = (int64_t(pCodecCtx->time_base.num) * AV_TIME_BASE) / int64_t(pCodecCtx->time_base.den);
  76.  
  77.                 // Allocate video frame
  78.                     pFrame=av_frame_alloc();
  79.  
  80.                   // Allocate an AVFrame structure
  81.                     pFrameRGB=av_frame_alloc();
  82.                     if(pFrameRGB==NULL)
  83.                         return -1;
  84.                   // Determine required buffer size and allocate buffer
  85.                     numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
  86.  
  87.                     DLOG("Buffer size allocated: %i", numBytes);
  88.                     buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
  89.  
  90.                     sws_ctx = sws_getContext
  91.                     (
  92.                         pCodecCtx->width,
  93.                         pCodecCtx->height,
  94.                         pCodecCtx->pix_fmt,
  95.                         pCodecCtx->width,
  96.                         pCodecCtx->height,
  97.                         PIX_FMT_RGB24,
  98.                         SWS_BILINEAR,
  99.                         NULL,
  100.                         NULL,
  101.                         NULL
  102.                     );
  103.  
  104.  
  105.                 // Assign appropriate parts of buffer to image planes in pFrameRGB
  106.                 // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
  107.                 // of AVPicture
  108.                     avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
  109.                     DLOG("Filled buffer ");
  110.                     size_t numSegments = vidClip->segments.size();
  111.  
  112.                     DLOG("Found %i segments to process", numSegments);
  113.                     for (size_t segmentIdx = 0; segmentIdx < numSegments; ++segmentIdx) {
  114.                         // seek to the right position
  115.                         DLOG("Processing segment # %i", segmentIdx);
  116.                         int frameOffset = vidClip->segments.at(segmentIdx).first;
  117.                         int clipDuration = vidClip->segments.at(segmentIdx).second;
  118.                         DLOG("Starting Frame Number: %i", frameOffset);
  119.                         DLOG("Segment duration: %i", clipDuration);
  120.  
  121. //                        seek(pFormatCtx, frameOffset);
  122.                         // loop for X frames where X is < frameOffset + clipDuration
  123.                         for (int frameIdx = frameOffset; frameIdx < (frameOffset + clipDuration); ++frameIdx) {
  124.                             DLOG("reading in frame %i", frameIdx);
  125.                             av_init_packet(&packet);
  126.                             int avReadResult = 0;
  127.                             int continueRecording = 1;
  128.                             while(continueRecording == 1) {
  129.                                 avReadResult = av_read_frame(pFormatCtx, &packet);
  130.                                 if(avReadResult != 0){
  131.                                     if (avReadResult != AVERROR_EOF) {
  132.                                         ELOG("av_read_frame error: %s", stringForAVErrorNumber(avReadResult));
  133.                                     } else {
  134.                                         ILOG("End of input file");
  135.                                     }
  136.                                     continueRecording = 0;
  137.                                 }
  138.                                 DLOG("Reading packet in stream: %i", videoStream);
  139.                                 // Is this a packet from the video stream?
  140.                                 if(packet.stream_index==videoStream) {
  141.                                     // Decode video frame
  142.                                     DLOG("Decoding video frame");
  143. //                                    avcodec_decode_video2(pCodecCtx, pFrameRGB, &frameFinished, &packet);
  144.  
  145.                                     // Did we get a video frame?
  146.                                     if(frameFinished) {
  147.                                         // Convert the image from its native format to RGB
  148. //                                        DLOG("Convert Frame to RGB");
  149. //                                        sws_scale
  150. //                                        (
  151. //                                           sws_ctx,
  152. //                                           (uint8_t const * const *)pFrame->data,
  153. //                                           pFrame->linesize,
  154. //                                           0,
  155. //                                           pCodecCtx->height,
  156. //                                           pFrameRGB->data,
  157. //                                           pFrameRGB->linesize
  158. //                                        );
  159.  
  160.  
  161.                                         // Save the frame to disk
  162.                                         if(frameIdx % 10 == 0) {
  163. //                                            SaveFrameLocal(pFrameRGB, pCodecCtx->width, pCodecCtx->height, frameIdx, vidClip->vidFileName.c_str());
  164.                                         }
  165.  
  166.                                         DLOG("writing frame #%i to file.. ", frameIdx);
  167.                                         av_interleaved_write_frame(pFormatCtx, &packet);
  168.                                         DLOG("Done writing frame #%i to file.. ", frameIdx);
  169.                                         frameIdx++;
  170.                                     }
  171.                                 }
  172.  
  173.                                 DLOG("Freeing the packet allocated by av_read_frame");
  174.                                 // Free the packet that was allocated by av_read_frame
  175.                                 av_free_packet(&packet);
  176.                             }
  177.                                 // Free the RGB image
  178.  
  179.                             DLOG("Cleaning up frame allocations");
  180.                             av_free(buffer);
  181.                             av_free(pFrameRGB);
  182.                             // Free the YUV frame
  183.                             av_free(pFrame);
  184.  
  185.                         }
  186.                     }
  187.  
  188.                 }
  189.  
  190.             } // end video clip processing
  191.  
  192.             break;
  193.  
  194.             case TITLE_CLIP: {
  195.  
  196.             break;
  197.  
  198.             default:
  199.                 ELOG("Failed to identify clip");
  200.                 break;
  201.             }
  202.         } // end switch statement
  203.  
  204.     } // end main for loop -> clip iteration
  205.     DLOG("Writing trailer to file");
  206.     av_write_trailer(pFormatCtx);
  207.  
  208.     // Close the codec
  209.     DLOG("Closing codec");
  210.     avcodec_close(pCodecCtx);
  211.  
  212.     // Close the video file
  213.     DLOG("Closing output file");
  214.     avformat_close_input(&pFormatCtx);
  215.  
  216.     return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement