Hello,
I am writing a code to decode h264 stream coming from raspi. I have
written a code but i am not sure my read packet function neads anz change
or not. i am attaching my code with this mail. Thank you.
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "H264Decoder.h"
#include <conio.h>
#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif
#define _CRT_SECURE_NO_WARNINGS
#define __STDC_CONSTANT_MACROS
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
};
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define AV_INPUT_BUFFER_PADDING_SIZE 32
using namespace std;
int read_packet(void *opaque, uint8_t *buf,int buf_size)
{
printf("Read packet Function activated\n");
struct buffer_data *bd = (struct buffer_data *)opaque;
buf_size = FFMIN((unsigned int)buf_size, bd->size);
printf("ptr:%p size:%d\n", bd->ptr, bd->size);
/* copy internal buffer data to buf */
memcpy(buf, bd->ptr, buf_size);
bd->ptr += buf_size;
bd->size -= buf_size;
return buf_size;
}
int decodeWithShow (int *ACount, AVFormatContext * ApFormatCtx, AVPacket *Apacket, AVCodecContext *ApCodecCtx, int Avideoindex,
AVFrame * ApFrame, AVFrame * ApFrameRGB, SwsContext *Aimg_convert_ctxRGB)
{
int ret, got_picture;
int y_size;
IplImage * AFrame = NULL;
cvNamedWindow ("Frame", CV_WINDOW_AUTOSIZE);
while(av_read_frame(ApFormatCtx, Apacket) >=0 )
{
if(Apacket->stream_index==Avideoindex)
{
ACount++;
std::cout<<"count="<<ACount<<"\n";
ret = avcodec_decode_video2(ApCodecCtx, ApFrame, &got_picture, Apacket);
if(ret < 0)
{
printf("Decode Error.\n");
return -1;
}
if(got_picture)
{
sws_scale(Aimg_convert_ctxRGB, (const uint8_t* const*)ApFrame->data, ApFrame->linesize, 0, ApCodecCtx->height,
ApFrameRGB->data, ApFrameRGB->linesize);
y_size = ApCodecCtx->width*ApCodecCtx->height;
printf("Succeed to decode 1 frame!\n");
// load the decoded frames buffer for IplImage
try {
// adapt target image, if necessary
bool mustCreate = (AFrame == NULL);
if (!mustCreate)
mustCreate = (AFrame->width != ApCodecCtx->width) || (AFrame->height != ApCodecCtx->height);
if (mustCreate)
{
cvReleaseImage(&AFrame);
AFrame = cvCreateImage(cvSize(ApCodecCtx->width,ApCodecCtx->height), IPL_DEPTH_8U, 3); // CV_8UC3
}
memcpy(AFrame->imageData,ApFrameRGB->data[0], 3 * ApCodecCtx->width * ApCodecCtx->height);
cvCvtColor(AFrame,AFrame,CV_RGB2BGR);
cvShowImage ("Frame", AFrame);
cv::waitKey(40);
} catch (std::exception & e)
{
std::cout<<"cv exception: "<<e.what()<<"\n";
}
}
}
av_free_packet(Apacket);
// av_frame_unref(ApFrame);
// av_frame_unref(ApFrameRGB);
}
}
int receive(int socket)
{
int recv_size = 0, read_size= 0, write_size, packet_index = 0,stat, imsize, size ,recvSize=0;
uint8_t imagearray[40960] = "0"; //imagearray[43008] = "0";
char incomingarry [4096] = "0";
struct timeval timeout = {10,0};
fd_set fds;
int buffer_fd, buffer_out;
struct buffer_data bd;
AVFormatContext *pFormatCtx = NULL;
int i = 0, videoindex = 0;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame,*pFrameRGB;
uint8_t *out_buffer, *out_bufferRGB;
AVPacket *packet;
int y_size;
int ret, got_picture;
struct SwsContext *img_convert_ctx, *img_convert_ctxRGB;
uint8_t *avio_ctx_buffer = NULL;
size_t avio_ctx_buffer_size;
AVIOContext *avio_ctx;
int count;
IplImage *AFrame;
//for(int packetIndex = 0; packetIndex<1000; packetIndex++)
// while(TRUE)
/* {
FD_ZERO(&fds);//Related to socket
FD_SET(socket,&fds);
buffer_fd = select(FD_SETSIZE, &fds, NULL, NULL, &timeout);//Related to socket
if (buffer_fd < 0)
{
cout<<"error: bad file descriptor set"<<endl;
return -1;
}
if (buffer_fd == 0) {
cout<<"error: buffer read timeout expired."<<endl;
return -1;
}*/
for(int packetIndex = 0; packetIndex<1000; packetIndex++)
{
cout<<"decoding packet"<<packetIndex<<endl;
int count=0;
int totalsize= 0;
do
{
do
{
recvSize = recv(socket, incomingarry, sizeof(incomingarry), 0);
count++;
}while(recvSize < 4096);
for (int i = 0; i < recvSize; i++){
imagearray[totalsize + i] = incomingarry[i];
}
totalsize = recvSize + totalsize;
recvSize = NULL;
cout<<"Total packet size: "<< totalsize << endl;
}while(totalsize < 40960);
bd.ptr = imagearray;
bd.size = sizeof(imagearray);
pFormatCtx = avformat_alloc_context();
avio_ctx_buffer = NULL;
avio_ctx_buffer_size = 8192 ; //8192; //2048; //
avio_ctx_buffer = (uint8_t *)av_malloc(avio_ctx_buffer_size);
if (!avio_ctx_buffer) {
printf("Can not malloc avio_ctx_buffer\n");
goto end;
}
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, &bd, &read_packet, NULL, NULL);
if (!avio_ctx){
printf("Can not alloc avio_ctx\n");
goto end;
}
pFormatCtx->pb = avio_ctx;
pFormatCtx->flags = AVFMT_FLAG_CUSTOM_IO;
if(avformat_open_input(&pFormatCtx,NULL,NULL,NULL)!=0){
printf("Couldn't open input stream.\n");
goto end;
}
if(avformat_find_stream_info(pFormatCtx,NULL)<0){
printf("Couldn't find stream information.\n");
// goto end;
}
videoindex=-1;
for(unsigned int i=0; i < pFormatCtx -> nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
if(videoindex==-1)
{
printf("Didn't find a video stream.\n");
goto end;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
printf("Codec not found.\n");
goto end;
}
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
{
printf("Could not open codec.\n");
goto end;
}
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
out_buffer = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
out_bufferRGB = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameRGB, out_bufferRGB, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
packet = (AVPacket *)av_malloc(sizeof(AVPacket));
img_convert_ctxRGB = sws_getContext(pCodecCtx -> width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
count = 0;
AFrame = NULL;
cvNamedWindow ("Frame", CV_WINDOW_AUTOSIZE);
decodeWithShow (&count, pFormatCtx, packet, pCodecCtx, videoindex, pFrame, pFrameRGB, img_convert_ctxRGB);
cout<<"Totalsize: "<< totalsize<<endl;
memset(imagearray, 0, sizeof(imagearray));
avformat_close_input(&pFormatCtx);
av_freep(&avio_ctx->buffer);
av_freep(&avio_ctx);
end:
avformat_close_input(&pFormatCtx);
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
if (avio_ctx) {
av_freep(&avio_ctx->buffer);
av_freep(&avio_ctx);
}
av_file_unmap(avio_ctx_buffer,avio_ctx_buffer_size);
}
return 0;
};
int main(int argc, char* argv[])
{
av_register_all();
avformat_network_init();
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR)
{
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
receive(ClientSocket);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user