int film::process () { int audioSize; uint8_t *buffer; uint8_t *buffer2; int frameFinished; int numBytes; shot s; static struct SwsContext *img_convert_ctx = NULL; create_main_dir (); string graphpath = this->global_path + "/"; g = new graph (600, 400, graphpath, threshold, this); g->set_title ("Motion quantity"); /* * Register all formats and codecs */ av_register_all (); if (av_open_input_file (&pFormatCtx, input_path.c_str (), NULL, 0, NULL) != 0) { string error_msg = "Impossible to open file"; error_msg += input_path; shotlog (error_msg); return -1; // Couldn't open file } /* * Retrieve stream information */ if (av_find_stream_info (pFormatCtx) < 0) return -1; // Couldn't find stream information // dump_format (pFormatCtx, 0, path.c_str (), false); videoStream = -1; audioStream = -1; /* * Detect streams types */ for (int j = 0; j < pFormatCtx->nb_streams; j++) { switch (pFormatCtx->streams[j]->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: videoStream = j; break; case AVMEDIA_TYPE_AUDIO: audioStream = j; break; default: break; } } /* * Get a pointer to the codec context for the video stream */ if (audioStream != -1) { if (audio_set) { string xml_audio = graphpath + "/" + "audio.xml"; init_xml (xml_audio); } pCodecCtxAudio = pFormatCtx->streams[audioStream]->codec; pCodecAudio = avcodec_find_decoder (pCodecCtxAudio->codec_id); if (pCodecAudio == NULL) return -1; // Codec not found if (avcodec_open (pCodecCtxAudio, pCodecAudio) < 0) return -1; // Could not open codec } update_metadata (); /* * Find the decoder for the video stream */ if (videoStream != -1) { pCodecCtx = pFormatCtx->streams[videoStream]->codec; pCodec = avcodec_find_decoder (pCodecCtx->codec_id); if (pCodec == NULL) return -1; // Codec not found if (avcodec_open (pCodecCtx, pCodec) < 0) return -1; // Could not open codec /* * Allocate video frame */ pFrame = avcodec_alloc_frame (); pFrameRGB = avcodec_alloc_frame (); pFrameRGBprev = avcodec_alloc_frame (); /* * Determine required buffer size and allocate buffer */ numBytes = avpicture_get_size (PIX_FMT_RGB24, width, height); buffer = (uint8_t *) malloc (sizeof (uint8_t) * numBytes); buffer2 = (uint8_t *) malloc (sizeof (uint8_t) * numBytes); /* * Assign appropriate parts of buffer to image planes in pFrameRGB */ avpicture_fill ((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24, width, height); avpicture_fill ((AVPicture *) pFrameRGBprev, buffer2, PIX_FMT_RGB24, width, height); /* * Mise en place du premier plan */ s.fbegin = 0; s.msbegin = 0; s.myid = 0; shots.push_back (s); } checknumber = (samplerate * samplearg) / 1000; /* * Boucle de traitement principale du flux */ this->frame_number = 0; while (av_read_frame (pFormatCtx, &packet) >= 0) { if (packet.stream_index == videoStream) { AVPacket pkt; av_init_packet (&pkt); pkt.data = packet.data; pkt.size = packet.size; avcodec_decode_video2 (pCodecCtx, pFrame, &frameFinished, &pkt); if (frameFinished) { // Convert the image into RGB24 if (! img_convert_ctx) { img_convert_ctx = sws_getContext(width, height, pCodecCtx->pix_fmt, width, height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL); if (! img_convert_ctx) { fprintf(stderr, "Cannot initialize the conversion context!\n"); exit(1); } } /* API: int sws_scale(SwsContext *c, uint8_t *src, int srcStride[], int srcSliceY, int srcSliceH, uint8_t dst[], int dstStride[] ) */ sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); /* Old API doc (cf http://www.dranger.com/ffmpeg/functions.html ) int img_convert(AVPicture *dst, int dst_pix_fmt, const AVPicture *src, int src_pix_fmt, int src_width, int src_height) */ /* img_convert ((AVPicture *) pFrameRGB, PIX_FMT_RGB24, (AVPicture *) pFrame, pCodecCtx->pix_fmt, width, height); */ this->frame_number ++; /* Si ce n'est pas la permiere image */ if ( this->frame_number > 2) { CompareFrame (pFrameRGB, pFrameRGBprev); } else { /* * Cas ou c'est la premiere image, on cree la premiere image dans tous les cas */ image *begin_i = new image (this, width, height, s.myid, BEGIN); begin_i->create_img_dir (); begin_i->SaveFrame (pFrameRGB); shots.back ().img_begin = begin_i; } memcpy (buffer2, buffer, numBytes); } } if (audio_set && (packet.stream_index == audioStream)) { process_audio (); } /* * Free the packet that was allocated by av_read_frame */ if (packet.data != NULL) av_free_packet (&packet); } if (videoStream != -1) { /* Mise en place de la dernière image */ int lastFrame = this->frame_number; shots.back ().fduration = lastFrame - shots.back ().fbegin; shots.back ().msduration = int (((shots.back ().fduration) * 1000) / fps); duration.mstotal = int (shots.back ().msduration + shots.back ().msbegin); image *end_i = new image (this, width, height, shots.back ().myid, END); end_i->SaveFrame (pFrameRGB); shots.back ().img_end = end_i; /* * Graphe de la qté de mvmt */ g->init_gd (); g->draw_all_canvas (); g->draw_color_datas (); g->draw_datas (); if (video_set) { string xml_color = graphpath + "/" + "video.xml"; g->write_xml (xml_color); } g->save (); /* * Free the RGB images */ free (buffer); free (buffer2); av_free (pFrameRGB); av_free (pFrame); av_free (pFrameRGBprev); avcodec_close (pCodecCtx); } /* * Close the codec */ if (audioStream != -1) { /* Fermetrure du fichier xml */ if (audio_set) close_xml (); avcodec_close (pCodecCtxAudio); } /* * Close the video file */ av_close_input_file (pFormatCtx); }
int main(int argc, char *argv[]) { int c, cmd, ret; conf_info_t info = {0}; char *config = DEFAULT_INTERNAL; xmlKeepBlanksDefault(0); xmlTreeIndentString = "\t"; if (argc < 2) { usage(argv[0]); return 1; } cmd = command_decode(argv[1]); /* parse params */ while ((c = getopt_long(argc, argv, OPTSTRING, long_opts, NULL)) != -1) { switch (c) { case 'h': usage(argv[0]); return 0; case 'c': config = optarg; break; case 'p': switch (optarg[0]) { case 'i': case 'I': info.type = PL_INPUT; break; case 'm': case 'M': info.type = PL_INTERMEDIATE; break; case 'o': case 'O': info.type = PL_OUTPUT; break; default: fprintf(stderr, "Unknown plugin type '%c'\n", optarg[0]); return 1; } break; case 'n': info.name = optarg; break; case 's': info.sofile = optarg; break; case 't': info.thread = optarg; break; case 'f': info.force = 1; break; default: return 1; } } ret = open_xml(&info, config); if (ret != 0) { return 1; } switch (cmd) { case CMD_ADD: ret = add_plugin(&info); break; case CMD_REMOVE: ret = remove_plugin(&info); break; case CMD_LIST: ret = list_plugins(&info); break; default: fprintf(stderr, "Unknown command '%s'\n", argv[1]); ret = 1; break; } if (ret == 0 && cmd != CMD_LIST) { save_xml(&info, config); } close_xml(&info); return ret; }