Hi Andrey, Thanks for the help!
1. Lib versions: Using the shared library and my code below, I tried 0.8.3 (PC) and 08d2cee4 (Mac) and could not scan the file. However, I tried the static executable of 0.8 and 0.10 on Mac and I *could* transcode it to MP4. 2. Link to video (it's almost 2gb): http://dl.dropbox.com/u/28441949/00793.MTS 3. Simplified, but compilable source code: int Scan(const char *inputfile) { totalFrames = 0; frameLocation = 0; AVFormatContext *pFormatCtx; unsigned int i, videoStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrameYUV; int numBytes; uint8_t *buffer; clock_t start = clock(); // Register all formats and codecs av_register_all(); // Open video file if(av_open_input_file(&pFormatCtx, inputfile, NULL, 0, NULL)!=0) { return -1; // Couldn't open file } // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) { return -2; // Couldn't find stream information } // Dump information about file onto standard error dump_format(pFormatCtx, 0, inputfile, false); // Find the first video stream videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoStream=i; break; } } if(videoStream==-1) { return -3; // Didn't find a video stream } // Get a pointer to the codec context for the video stream pCodecCtx = pFormatCtx->streams[videoStream]->codec; // get duration double duration = double(pFormatCtx->duration) / AV_TIME_BASE; cout << "Video duration: " << duration << std::endl; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { return -4; // Codec not found } // Inform the codec that we can handle truncated bitstreams -- i.e., // bitstreams where frame boundaries can fall in the middle of packets if(pCodec->capabilities & CODEC_CAP_TRUNCATED) pCodecCtx->flags|=CODEC_FLAG_TRUNCATED; // Open codec if(avcodec_open(pCodecCtx, pCodec)<0) { return -5; // Could not open codec } std::cout << "Using codec: " << pCodec->name << std::endl; // Allocate video frame pFrame=avcodec_alloc_frame(); // Allocate an AVFrame structure pFrameYUV=avcodec_alloc_frame(); if(pFrameYUV==NULL) { return -6; } // Determine required buffer size and allocate buffer // originally: PIX_FMT_RGB24 numBytes=avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in pFrameRGB // originally: PIX_FMT_RGB24 avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height); totalFrames = pFormatCtx->streams[videoStream]->nb_frames; printf("Frames: %d\n", totalFrames); AVPacket packet; int isFrameFinished = 0; int pixelScanCount = 0; std::cout << "videoWidth = " << pCodecCtx->width << std::endl; std::cout << "videoHeight = " << pCodecCtx->height << std::endl; while (av_read_frame(pFormatCtx, &packet) >= 0) { // Is this a packet from the video stream? if (packet.stream_index == videoStream && frameLocation++ % frameSkip == 0) { // Decode video frame avcodec_decode_video2(pCodecCtx, pFrame, &isFrameFinished, &packet); // Did we get a video frame? if (isFrameFinished) { // SCANNING GOES HERE pixelScanCount = 0; for (int y = 0; y < pCodecCtx->height; y++) { uint8_t *p = pFrame->data[0] + y * pFrame->linesize[0]; // this gets Y' in YUV for (int x = 0; x < pCodecCtx->width; x++) { pixelScanCount++; //printf("Frame %d at %d, %d has Y'=%d\n", frameLocation, x, y, p[x]); } } av_free_packet(&packet); } else // frame isn't finished. not sure why we'd hit this { av_free_packet(&packet); } } } delete [] buffer; av_free(pFrameYUV); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); } 4. When I enabled av_log_set_level(AV_LOG_DEBUG) in my app, I saw several of these: [h264 @ 09FC0940] Frame num gap 10 8 [h264 @ 09FC0940] Frame num gap 15 12 [h264 @ 09FC0940] Frame num gap 15 13 [h264 @ 09FC0940] Frame num gap 20 17 ... So considering the fact that the command-line utility was able to transcode, I'm assuming there's something wrong in my code. I've seen some warnings for deprecated functions so maybe that's my problem? Thanks! Simon On Mon, Feb 6, 2012 at 2:56 AM, Andrey Utkin <[email protected] > wrote: > Please help us help you - provide > - version of libs you use > - compilable minimized source code of your app > - this sample file > > BTW, did you try to transcode it with ffmpeg command-line utility? If > it also fails, please provide its full output with -loglevel debug > BTW2 try to av_log_set_level(AV_LOG_DEBUG); in your app - maybe you'll > see useful messages on stderr. > > > -- > Andrey Utkin > _______________________________________________ > Libav-user mailing list > [email protected] > http://ffmpeg.org/mailman/listinfo/libav-user >
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
