Commit 156dd623 authored by Linshizhi's avatar Linshizhi

Add PktBuffer defs

parent ffa6f65f
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
#include "wasm.h"
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/avutil.h>
///////////////////////////////////////////////////////////////////////////////
// Encoding Part //
///////////////////////////////////////////////////////////////////////////////
static int width_ = 0;
static int height_ = 0;
static int framerate_ = 0;
static int timescale = 90000;
static AVFrame *rgbaFrame;
static unsigned frameIndex = 0;
static AVFrame *frame;
static AVPacket *packet;
static AVCodecContext *cc;
static struct SwsContext* swsCtx = NULL;
static AVPacket *lastPkt = NULL;
EM_PORT_API(int) getPackets(uint8_t *buffer, uint32_t size, uint32_t *osize);
EM_PORT_API(uint8_t) encodeInit(int width, int height, int fps) {
int ret = 0;
width_ = width;
height_ = height;
framerate_ = fps;
const AVCodec *encoder = avcodec_find_encoder_by_name("libx264");
if (encoder == NULL) {
fprintf(stderr, "Unable to find H.264 decoder\n");
return 1;
}
cc = avcodec_alloc_context3(encoder);
if (cc == NULL) {
fprintf(stderr, "Unable to alloc codec context\n");
return 2;
}
// Setup encode parameters
cc->width = width;
cc->height = height;
cc->pix_fmt = AV_PIX_FMT_YUV420P;
cc->time_base = (AVRational){1, timescale};
cc->gop_size = 0;
if ((ret = avcodec_open2(cc, encoder, NULL) < 0)) {
fprintf(stderr, "Unable to open codec context: %s\n",
av_err2str(ret));
return 3;
}
packet = av_packet_alloc();
if (packet == NULL) {
fprintf(stderr, "Could not allocate packet\n");
}
frame = av_frame_alloc();
frame->format = cc->pix_fmt;
frame->width = cc->width;
frame->height = cc->height;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Could not allocate the video frame data\n");
return 4;
}
swsCtx = sws_getCachedContext(swsCtx, width, height, AV_PIX_FMT_RGBA,
width, height, AV_PIX_FMT_YUV420P,
SWS_BICUBIC,
NULL, NULL, NULL);
return 0;
}
/* Ret Values:
* 0: Success
* 1: AGAIN
* 2: Buffer too small
* 3: ERROR */
EM_PORT_API(int) encode(uint8_t *data, uint8_t *buffer, uint32_t size, uint32_t *osize) {
int ret = 0;
if (av_frame_make_writable(frame) < 0) {
fprintf(stderr, "Fail to make frame writable\n");
}
rgbaFrame = av_frame_alloc();
rgbaFrame->format =AV_PIX_FMT_RGBA;
rgbaFrame->height = cc->height;
rgbaFrame->width = cc->width;
avpicture_fill((AVPicture*)rgbaFrame, data, AV_PIX_FMT_RGBA, width_, height_);
//转换的YUV数据存放在frame
int outSliceH = sws_scale(swsCtx, (const uint8_t* const*)rgbaFrame->data, rgbaFrame->linesize, 0, height_,
frame->data, frame->linesize);
if (outSliceH <= 0) {
printf("outSliceH <= 0 \n");
return 3;
}
frame->pts = timescale / framerate_ * frameIndex;
frame->pict_type = AV_PICTURE_TYPE_I;
++frameIndex;
// Encode
ret = avcodec_send_frame(cc, frame);
if (ret < 0) {
fprintf(stderr, "Fail to encoding\n");
}
return getPackets(buffer, size, osize);
}
/* Ret Values:
* 0: Success
* 1: AGAIN or EOF
* 2: Buffer too small
* 3: ERROR */
EM_PORT_API(int) getPackets(uint8_t *buffer, uint32_t size, uint32_t *osize) {
int ret = 0;
uint8_t *pos = buffer;
int remainSize = size;
*osize = 0;
if (lastPkt != NULL && lastPkt->size > remainSize) {
memcpy(pos, lastPkt->data, lastPkt->size);
pos += lastPkt->size;
remainSize -= lastPkt->size;
av_packet_unref(lastPkt);
lastPkt = NULL;
} else if (lastPkt != NULL) {
/* Buffer is too small to containe the packet */
return 2;
}
while (1) {
ret = avcodec_receive_packet(cc, packet);
if (ret < 0) {
ret = 1;
goto DONE;
}
printf("WASM Encode: Packet Size %d\n", packet->size);
// For video frame avcodec_receive_packet should return
// only once.
if (remainSize > packet->size) {
memcpy(pos, packet->data, packet->size);
pos += packet->size;
remainSize -= packet->size;
} else {
lastPkt = packet;
break;
}
av_packet_unref(packet);
}
DONE:
*osize = size - remainSize;
return ret;
}
EM_PORT_API(int) flushEncoder() {
if (avcodec_send_frame(cc, NULL) < 0) {
return 1;
}
return 0;
}
int main(void) {}
......@@ -51,8 +51,8 @@ if [ ! -d "build" ]; then
mkdir build
fi
cd build
emcmake cmake .. -DCMAKE_INSTALL_PREFIX=${BUILD_DIR} -Denable_trmem=OFF -Denable_movmem=ON -DDEBUG=OFF -DIS_EMCC_ENV=ON \
-DCMAKE_CXX_FLAGS=-isystem\ ${LIB_DIR}/ffmpeg.wasm-core
emcmake cmake .. -DCMAKE_INSTALL_PREFIX=${BUILD_DIR} -DSTATICLIB=ON -DDEBUG=OFF -DEMCC=ON \
-DCMAKE_C_FLAGS=-isystem\ ${LIB_DIR}/ffmpeg.wasm-core
emmake make
emmake make install
......@@ -121,15 +121,10 @@ FLAGS_ENCODER=(
FLAGS_MUXER=(
-I$BUILD_DIR/include -L$BUILD_DIR/lib -I$LIB_DIR/ffmpeg.wasm-core -I$LIB_DIR/ffmpeg.protos/src
-Wno-deprecated-declarations -Wno-pointer-sign -Wno-implicit-int-float-conversion -Wno-switch -Wno-parentheses -Qunused-arguments
-lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc -lm -lx264 -lz
-lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc -lm -lx264 -lz -lffmpegprotos
$WASM_DIR/muxer.cc
$LIB_DIR/ffmpeg.protos/src/ioctx.cc
$LIB_DIR/ffmpeg.protos/src/utils.cc
$LIB_DIR/ffmpeg.protos/src/proto/movMemProto.cc
$LIB_DIR/ffmpeg.protos/src/proto/proto.cc
$WASM_DIR/muxer.c
-std=c++2a
-s FORCE_FILESYSTEM=1
-s WASM=1
#-s USE_SDL=0 # use SDL2
......@@ -149,6 +144,7 @@ FLAGS_MUXER=(
emcc "${FLAGS_ENCODER[@]}"
emcc "${FLAGS_MUXER[@]}"
chown "$1:$2" ${DEMO_PATH}/resources/workers/paraencoder.js
chown "$1:$2" ${DEMO_PATH}/resources/workers/paraencoder.js
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment