#include <stdio.h>
#include <conio.h>
#define INBUF_SIZE 4096*8
extern "C"{
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
}
typedef struct{
AVCodec *pCodec;
AVCodecContext *pCodecContext;
AVCodecParserContext *pCodecParserCtx;
AVFrame *frame;
AVPacket pkt;
} CodecCtx;
typedef struct{
FILE *pFin;
FILE *pFout;
char *pNameIn;
char *pNameOut;
} IOParam;
int Open_deocder(CodecCtx &ctx) {
avcodec_register_all();
av_init_packet(&(ctx.pkt));
ctx.pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!ctx.pCodec) return -1;
ctx.pCodecContext = avcodec_alloc_context3(ctx.pCodec);
if (!ctx.pCodecContext) return -2;
if (ctx.pCodec->capabilities & AV_CODEC_CAP_TRUNCATED)
ctx.pCodecContext->flags |= AV_CODEC_FLAG_TRUNCATED;
ctx.pCodecParserCtx = av_parser_init(AV_CODEC_ID_H264);
if (!ctx.pCodecParserCtx) return -3;
if (avcodec_open2(ctx.pCodecContext, ctx.pCodec, NULL) < 0)
return -4;
ctx.frame = av_frame_alloc();
if (!ctx.frame) return -5;
return 0;
}
int Open_files(IOParam &IOParam){
IOParam.pFin = fopen(IOParam.pNameIn, "rb");
if (!IOParam.pFin) return -1;
IOParam.pFout = fopen(IOParam.pNameOut, "wb");
if (!IOParam.pFout) return -2;
return 0;
}
void Close_decoder(CodecCtx &ctx) {
avcodec_close(ctx.pCodecContext);
av_free(ctx.pCodecContext);
av_frame_free(&(ctx.frame));
}
void Close_files(IOParam &IOParam){
fclose(IOParam.pFin);
fclose(IOParam.pFout);
}
void write_out_yuv_frame(const CodecCtx &ctx, IOParam &in_out){
uint8_t **pBuf = ctx.frame->data;
int* pStride = ctx.frame->linesize;
for (int color_idx = 0; color_idx < 3; color_idx++){
int nWidth = color_idx == 0 ? ctx.frame->width : ctx.frame->width / 2;
int nHeight = color_idx == 0 ? ctx.frame->height : ctx.frame->height / 2;
for(int idx=0;idx < nHeight; idx++){
fwrite(pBuf[color_idx],1, nWidth, in_out.pFout);
pBuf[color_idx] += pStride[color_idx];
}
fflush(in_out.pFout);
}
}
void errReport(char *info, int val){
fprintf(stderr, "ERR: %s code=%d\n",info, val);
getch();
exit(0);
}
int main(){
int ret = 0;
uint8_t *pDataPtr = NULL;
int uDataSize = 0;
int got_picture, len;
CodecCtx ctx;
IOParam inputoutput;
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
inputoutput.pNameIn = "output.h264";
inputoutput.pNameOut = "output.yuv";
if ((ret = Open_files(inputoutput)) < 0)
errReport("Open_files", ret);
if ((ret = Open_deocder(ctx)) < 0)
errReport("Open_deocder", ret);
printf("start...");
while(1){
uDataSize = fread_s(inbuf,INBUF_SIZE, 1, INBUF_SIZE, inputoutput.pFin);
if (0 == uDataSize) break;
pDataPtr = inbuf;
printf("\n%d:", uDataSize);
while(uDataSize > 0){
len = av_parser_parse2(ctx.pCodecParserCtx, ctx.pCodecContext,
&(ctx.pkt.data), &(ctx.pkt.size),
pDataPtr, uDataSize,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
pDataPtr += len;
uDataSize -= len;
if (0 == ctx.pkt.size) continue;
printf("#%d ", ctx.pkt.size);
if ((ret = avcodec_decode_video2(ctx.pCodecContext, ctx.frame, &got_picture, &(ctx.pkt))) < 0)
errReport("avcodec_decode_video2", ret);
if (got_picture)
write_out_yuv_frame(ctx, inputoutput);
} //while(uDataSize > 0)
}//while(1)
printf("\navcodec_decode --- ok\n");
Close_files(inputoutput);
Close_decoder(ctx);
getch();
return 1;
}
结果:
start...
32768:#13608 #2874 #3004 #2936 #3056 #2834 #2947
32768:#3244 #2968 #3169 #2907 #2768 #3049 #2806 #2775
32768:#11163 #2199 #2656 #3094 #2748 #2635 #2704 #2514 #3012 #2668 #2343 #2419 #2178
32768:#2275 #2389 #8866 #1925 #2012 #1905 #2052 #1962 #1725 #1834 #1794 #1861 #2335
32768:#1896 #1602 #1536 #1444 #9972 #1218 #1151 #1360 #1262 #1600 #1335 #1274 #1579 #1559 #1928 #2488
32768:#2427 #1943 #2043 #11943 #1903 #2128 #2078 #2232 #2601 #2356
32768:#2450 #2199 #2394 #2386 #2480 #2353 #2713 #2703 #13073
32768:#2419 #2505 #2663 #2779 #2768 #2719 #2764 #2683 #2630 #2682 #2605 #2841
32768:#2775 #2850 #11016 #2287 #2290 #2185 #2309 #2282 #2538 #2497
32768:#2182 #2299 #2613 #2625 #2570 #2568 #2377 #6449 #2081 #2660 #3017 #2966
32768:#2847 #2868 #2600 #2528 #2639 #2381 #2126 #1993 #2004 #2429 #5975 #2424
32768:#2469 #2356 #2243 #2126 #2255 #2306 #2055 #2108 #2247 #2177 #2127 #1978 #2182
32768:#5718 #2514 #2368 #2419 #2708 #2211 #2412 #2239 #2051 #2650 #2483 #2633 #2903
32768:#2840 #2955 #7095 #2550 #3186 #3601 #4648 #4912
32768:#5104 #4509 #4306 #4736 #4201 #3756 #3812 #4556
32768:#4009 #12211 #2685 #2673 #2617 #3052 #2901 #3114
32768:#3404 #3301 #3253 #3252 #3187 #3003 #3159 #3386
32768:#12008 #2805 #3079 #3197 #3205 #3264 #3438 #3550 #3461
32768:#3627 #3374 #3051 #3046 #3568 #3012 #11388 #2462
32768:#2448 #3454 #3822 #3105 #3048 #3115 #2868 #2926 #2956 #2847 #2983
32768:#3165 #3523 #8540 #2347 #2312 #2208 #2235 #2143 #2161 #2040 #1888
32768:#1751 #1584 #1491 #1372 #1344 #1485 #5945 #1395 #2013 #1744 #1685 #1645 #1677 #1668 #1653 #1546 #1595
32768:#1955 #2053 #2062 #1917 #7307 #1926 #2274 #2309 #2560 #2909 #3008 #3094
32768:#3380 #3566 #3714 #4090 #4126 #4283 #4272
32768:#9617 #3941 #3591 #3359 #3126 #2962 #2788 #2790 #2940 #3207
32768:#3072 #2779 #2873 #3136 #3133 #9304 #2647 #2782 #2966
32768:#2929 #3104 #3135 #3210 #3204 #3096 #3418 #3378 #3414 #3331
32768:#3445 #9037 #3093 #2948 #2929 #3082 #2819 #2603 #2729
17267:#2642 #2608 #2875 #2633 #2690 #2728
avcodec_decode --- ok