<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Hello all,<br>
<br>
I need help in understanding what I am doing wrong in a section of
which takes a pixel array encoded as RGB24 from SDL2 and making it
work with h.264 encoding. I am converting to YUV format via
sw_scale(), but still no luck.<br>
<br>
Input: RGB24 encoded array as used in SDL2's SDL_Surface with
dimension 256 width by 144 height<br>
Output: H.264 video with dimension 256 by 144<br>
<br>
<br>
<blockquote>void *encodeToVideo(void *ignore){<br>
<br>
AVCodec *codec;<br>
AVCodecContext *c= NULL;<br>
int i, ret, got_output;<br>
AVFrame *_frame;<br>
AVPacket pkt;<br>
uint8_t endcode[] = { 0, 0, 1, 0xb7 };<br>
i = 0;<br>
queue<SDL_Surface*> freeLater;<br>
<br>
/* find the video encoder */<br>
avcodec_register_all();<br>
codec = avcodec_find_encoder(AV_CODEC_ID_H264);<br>
if (!codec) {<br>
fprintf(stderr, "Codec not found\n");<br>
exit(1);<br>
}<br>
<br>
c = avcodec_alloc_context3(codec);<br>
if (!c) {<br>
fprintf(stderr, "Could not allocate video codec context\n");<br>
exit(1);<br>
}<br>
<br>
/* put sample parameters */<br>
c->bit_rate = 400000;<br>
c->width = 256;<br>
c->height = 144;<br>
/* frames per second */<br>
c->time_base = (AVRational){1,30};<br>
/* emit one intra frame every frames*/<br>
c->gop_size = 1;<br>
c->max_b_frames = 0;<br>
c->pix_fmt = AV_PIX_FMT_YUV420P;<br>
<br>
av_opt_set(c->priv_data, "zerolatency", "veryfast", 0);<br>
<br>
/* open codec */<br>
if (avcodec_open2(c, codec, NULL) < 0) {<br>
fprintf(stderr, "Could not open codec\n");<br>
exit(1);<br>
}<br>
<br>
_frame = av_frame_alloc();<br>
if (!_frame) {<br>
fprintf(stderr, "Could not allocate video frame\n");<br>
exit(1);<br>
}<br>
_frame->format = c->pix_fmt;<br>
_frame->width = c->width;<br>
_frame->height = c->height;<br>
<br>
/* the image can be allocated by any means and av_image_alloc()
is<br>
* just the most convenient way if av_malloc() is to be used */<br>
ret = av_image_alloc(_frame->data, _frame->linesize,
c->width, c->height,<br>
c->pix_fmt, 32);<br>
if (ret < 0) {<br>
fprintf(stderr, "Could not allocate raw picture buffer\n");<br>
exit(1);<br>
}<br>
<br>
while(!renderFramesDone || !renderFramesOut->empty()){<br>
if(renderFramesOut->empty()) continue;<br>
SDL_Surface *imageToEncode = renderFramesOut->front();<br>
renderFramesOut->pop();<br>
freeLater.push(imageToEncode);<br>
<br>
av_init_packet(&pkt);<br>
pkt.data = NULL; // packet data will be allocated by the
encoder<br>
pkt.size = 0;<br>
<br>
fflush(stdout);<br>
<br>
<br>
struct SwsContext* convertCtx;<br>
convertCtx = sws_getContext(256, 144, AV_PIX_FMT_RGB24, <br>
256, 144, AV_PIX_FMT_YUV420P, 0,
0, 0, 0);<br>
<br>
uint8_t *inData[1] = {(uint8_t *)(imageToEncode->pixels)};<br>
int inLinesize[1] = { 256 };<br>
sws_scale(convertCtx, inData, inLinesize, 0, 144,
_frame->data, _frame->linesize);<br>
sws_freeContext(convertCtx);<br>
<br>
_frame->pts = i++;<br>
<br>
/* encode the image */<br>
ret = avcodec_encode_video2(c, &pkt, _frame,
&got_output);<br>
<br>
if (ret < 0) {<br>
fprintf(stdout, "Error encoding frame\n");<br>
exit(1);<br>
}<br>
<br>
if(got_output){<br>
fflush(stdout);<br>
fwrite(pkt.data, 1, pkt.size, stdout);<br>
av_packet_unref(&pkt);<br>
}<br>
<br>
}<br>
<br>
<br>
/* get the delayed frames */<br>
for (got_output = 1; got_output; i++) {<br>
fflush(stdout);<br>
<br>
ret = avcodec_encode_video2(c, &pkt, NULL,
&got_output);<br>
if (ret < 0) {<br>
fprintf(stderr, "Error encoding frame\n");<br>
exit(1);<br>
}<br>
<br>
if (got_output) {<br>
fprintf(stderr, "Write frame %3d (size=%5d)\n", i,
pkt.size);<br>
fwrite(pkt.data, 1, pkt.size, stdout);<br>
av_packet_unref(&pkt);<br>
}<br>
}<br>
<br>
<br>
/* add sequence end code to have a real mpeg file */<br>
fwrite(endcode, 1, sizeof(endcode), stdout);<br>
fclose(stdout);<br>
<br>
avcodec_close(c);<br>
av_free(c);<br>
av_freep(_frame->data);<br>
av_frame_free(&_frame);<br>
<br>
while(!freeLater.empty()){<br>
SDL_FreeSurface(freeLater.front());<br>
freeLater.pop();<br>
}<br>
<br>
encodeToVideoDone = true;<br>
return NULL;<br>
}<br>
</blockquote>
<br>
</body>
</html>