| 1 | #define __STDC_CONSTANT_MACROS
|
|---|
| 2 | #pragma warning(disable:4244)
|
|---|
| 3 |
|
|---|
| 4 | extern "C"
|
|---|
| 5 | {
|
|---|
| 6 | #include <libavformat/avformat.h>
|
|---|
| 7 | #include <libswscale/swscale.h>
|
|---|
| 8 | #include <libavcodec/avcodec.h>
|
|---|
| 9 | #include <libavutil/opt.h>
|
|---|
| 10 | }
|
|---|
| 11 |
|
|---|
| 12 | int main(int argc, char *argv[])
|
|---|
| 13 | {
|
|---|
| 14 | av_register_all();
|
|---|
| 15 |
|
|---|
| 16 | AVFormatContext* pFormatCtx;
|
|---|
| 17 | if (argc == 2)
|
|---|
| 18 | {
|
|---|
| 19 | av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL);
|
|---|
| 20 | }
|
|---|
| 21 | else
|
|---|
| 22 | {
|
|---|
| 23 | printf("need filename\n");
|
|---|
| 24 |
|
|---|
| 25 | return -1;
|
|---|
| 26 | }
|
|---|
| 27 |
|
|---|
| 28 | av_find_stream_info(pFormatCtx);
|
|---|
| 29 | dump_format(pFormatCtx, 0, "test", 0);
|
|---|
| 30 |
|
|---|
| 31 | AVCodecContext* pCodecCtx;
|
|---|
| 32 |
|
|---|
| 33 | // i know first stream is at index 0, simplified here
|
|---|
| 34 | unsigned int videoStream = 0;
|
|---|
| 35 | pCodecCtx = pFormatCtx->streams[videoStream]->codec;
|
|---|
| 36 |
|
|---|
| 37 | AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
|
|---|
| 38 | avcodec_open(pCodecCtx, pCodec);
|
|---|
| 39 |
|
|---|
| 40 | AVFrame* pFrame = avcodec_alloc_frame();
|
|---|
| 41 | AVFrame* pFrameRGB = avcodec_alloc_frame();
|
|---|
| 42 |
|
|---|
| 43 | PixelFormat destFormat = PIX_FMT_YUV420P;
|
|---|
| 44 |
|
|---|
| 45 | // Determine required buffer size and allocate buffer
|
|---|
| 46 | int numBytes = avpicture_get_size(destFormat, pCodecCtx->width, pCodecCtx->height);
|
|---|
| 47 | uint8_t* buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
|
|---|
| 48 | avpicture_fill((AVPicture *)pFrameRGB, buffer, destFormat, pCodecCtx->width, pCodecCtx->height);
|
|---|
| 49 |
|
|---|
| 50 | int frameFinished;
|
|---|
| 51 | AVPacket packet;
|
|---|
| 52 |
|
|---|
| 53 | SwsContext* swsContext = sws_alloc_context();
|
|---|
| 54 | //AVOption options;
|
|---|
| 55 | av_opt_set_defaults(swsContext);
|
|---|
| 56 | av_set_int(swsContext, "sws_flags", SWS_POINT);
|
|---|
| 57 | av_set_int(swsContext, "srcw", pCodecCtx->width);
|
|---|
| 58 | av_set_int(swsContext, "srch", pCodecCtx->height);
|
|---|
| 59 | av_set_int(swsContext, "dstw", pCodecCtx->width);
|
|---|
| 60 | av_set_int(swsContext, "dsth", pCodecCtx->height);
|
|---|
| 61 | av_set_int(swsContext, "src_format", pCodecCtx->pix_fmt);
|
|---|
| 62 | av_set_int(swsContext, "dst_format", destFormat);
|
|---|
| 63 | av_set_int(swsContext, "src_range", 1);
|
|---|
| 64 | av_set_int(swsContext, "dst_range", 1);
|
|---|
| 65 |
|
|---|
| 66 | sws_init_context(swsContext, NULL, NULL); //success
|
|---|
| 67 |
|
|---|
| 68 | while(av_read_frame(pFormatCtx, &packet) >= 0)
|
|---|
| 69 | {
|
|---|
| 70 | // Is this a packet from the video stream?
|
|---|
| 71 | if(packet.stream_index == videoStream)
|
|---|
| 72 | {
|
|---|
| 73 | // Decode video frame
|
|---|
| 74 | avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
|
|---|
| 75 |
|
|---|
| 76 | // Did we get a video frame?
|
|---|
| 77 | if(frameFinished)
|
|---|
| 78 | {
|
|---|
| 79 | AVPicture &pic = *(AVPicture*)pFrame;
|
|---|
| 80 | AVPicture &picDst = *(AVPicture*)pFrameRGB;
|
|---|
| 81 | // [CRASH HERE]
|
|---|
| 82 | sws_scale(swsContext, &pic.data[0], &pic.linesize[0], 0, pCodecCtx->height, &picDst.data[0], &picDst.linesize[0]);
|
|---|
| 83 | //
|
|---|
| 84 | printf(".");
|
|---|
| 85 | }
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | // Free the packet that was allocated by av_read_frame
|
|---|
| 89 | av_free_packet(&packet);
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | av_free(buffer);
|
|---|
| 93 | av_free(pFrameRGB);
|
|---|
| 94 | av_free(pFrame);
|
|---|
| 95 | sws_freeContext(swsContext);
|
|---|
| 96 | avcodec_close(pCodecCtx);
|
|---|
| 97 | av_close_input_file(pFormatCtx);
|
|---|
| 98 |
|
|---|
| 99 | return 0;
|
|---|
| 100 | }
|
|---|