Skip to content

Commit 0f4170f

Browse files
committed
add decode exception, add sdl support
1 parent 175845e commit 0f4170f

File tree

8 files changed

+79
-16
lines changed

8 files changed

+79
-16
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ h264_data = source.read()
3030
#### 2. Use VideoDecoder
3131
```python
3232
decoder = VideoDecoder()
33+
# output OpenCV format frame
3334
frames = decoder.decode(h264_data)
34-
# frames can be NULL or List<frame>
35+
# output SDL format frame
36+
frames = decoder.decode(h264_data, 1)
3537
```
3638

3739
#### 3. Use VideoEncoder

nvcodec-python.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static PyObject* VideoSource_read(NvCodec* Self)
3333
AVPacket *packet = av_packet_alloc();
3434
if(videoSource_read(m_handle, packet) < 0){
3535
av_packet_free(&packet);
36-
return NULL;
36+
return Py_None;
3737
}
3838
PyObject* rtn = PyBytes_FromStringAndSize((const char*)packet->data, packet->size);
3939
av_packet_free(&packet);
@@ -105,23 +105,31 @@ static PyObject* VideoDecoder_decode(NvCodec* Self, PyObject* pArgs)
105105

106106
unsigned char* data;
107107
int len;
108-
if(!PyArg_ParseTuple(pArgs, "y#", &data, &len)){
108+
unsigned int type = 0;
109+
if(!PyArg_ParseTuple(pArgs, "y#|I", &data, &len, &type)){
109110
PyErr_SetString(PyExc_ValueError, "Parse the argument FAILED! You should video byte data!");
110-
return NULL;
111+
return Py_None;
111112
}
112113

113-
videoFrameList* list = videoDecoder_decode(m_handle, data, len);
114+
PyObject* rtn = Py_BuildValue("[]");
115+
char error_str[128];
116+
videoFrameList* list = videoDecoder_decode(m_handle, data, len, error_str);
114117
if(list == NULL){
115-
Py_INCREF(Py_None);
116-
return Py_None;
118+
if(error_str[0] != NULL){
119+
PyErr_Format(PyExc_ValueError, "%s", error_str);
120+
return NULL;
121+
}
122+
return rtn;
117123
}
118124

119-
PyObject* rtn = Py_BuildValue("[]");
120125
npy_intp dims[3] = {(npy_intp)(list->height), (npy_intp)(list->width), 4};
121126
PyObject* tempFrame;
122127
for(int i = 0;i<list->length;i++){
123128
tempFrame = PyArray_SimpleNewFromData(3, dims, NPY_UINT8, list->pFrames + (i*(list->perFrameSize)));
124129
PyArray_ENABLEFLAGS((PyArrayObject*) tempFrame, NPY_ARRAY_OWNDATA);
130+
if(type != 0){
131+
tempFrame = PyArray_SwapAxes((PyArrayObject*)tempFrame, 0, 1);
132+
}
125133
PyList_Append(rtn, tempFrame);
126134
}
127135
videoFrameList_destory(&list);

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def build_extensions(self):
3030

3131
from distutils.core import setup, Extension
3232
setup(name='pynvcodec',
33-
version='0.0.4',
33+
version='0.0.5',
3434
ext_modules=[module],
3535
cmdclass={'build_ext': custom_build_ext},
3636
author="Usingnet",

src/cuvid/NvDecoder/NvDecoder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat)
178178
;
179179
m_videoInfo << std::endl;
180180

181+
// std::cout << m_videoInfo.str();
182+
181183
int nDecodeSurface = pVideoFormat->min_num_decode_surfaces;
182184

183185
CUVIDDECODECAPS decodecaps;
@@ -192,7 +194,9 @@ int NvDecoder::HandleVideoSequence(CUVIDEOFORMAT *pVideoFormat)
192194
CUDA_DRVAPI_CALL(cuCtxPopCurrent(NULL));
193195

194196
if(!decodecaps.bIsSupported){
197+
std::cout << m_videoInfo.str();
195198
NVDEC_THROW_ERROR("Codec not supported on this GPU", CUDA_ERROR_NOT_SUPPORTED);
199+
// NVDEC_THROW_ERROR("Codec not supported on this GPU", CUDA_ERROR_NOT_SUPPORTED);
196200
return nDecodeSurface;
197201
}
198202

src/decoder.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,24 @@ videoFrameList* videoFrameList_init(int width, int height, int length){
5151
}
5252

5353

54-
videoFrameList* videoDecoder_decode(videoDecoderHandle handle, u_int8_t* in, size_t in_size){
54+
videoFrameList* videoDecoder_decode(videoDecoderHandle handle, u_int8_t* in, size_t in_size, char*error){
5555
int nFrameReturned;
5656
int i;
5757
int frameSize;
5858
uint8_t *pVideo = NULL, *pFrame;
5959
videoFrameList* frameList = NULL;
6060
CUdeviceptr dpFrame = 0, nv12Frame = 0;
61-
62-
nFrameReturned = DEC(handle)->Decode(in, in_size);
61+
if(error!=NULL){
62+
error[0] = NULL;
63+
}
64+
try{
65+
nFrameReturned = DEC(handle)->Decode(in, in_size);
66+
}catch(NVDECException e){
67+
if(error != NULL){
68+
strcpy(error, e.what());
69+
}
70+
return NULL;
71+
}
6372
for (i = 0; i < nFrameReturned; i++) {
6473
pFrame = DEC(handle)->GetFrame();
6574
frameSize = DEC(handle)->GetFrameSize();

src/decoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ typedef struct
3737

3838
videoDecoderHandle videoDecoder_init(enum AVCodecID codec);
3939
int videoDecoder_destroy(videoDecoderHandle handle);
40-
videoFrameList* videoDecoder_decode(videoDecoderHandle handle, u_int8_t* in, size_t in_size);
40+
videoFrameList* videoDecoder_decode(videoDecoderHandle handle, u_int8_t* in, size_t in_size, char*error);
4141
void videoFrameList_destory(videoFrameList**);
4242
videoFrameList* videoFrameList_init(int width, int height, int length);
4343

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
sys.path.append(lib_path)
77
from nvcodec import VideoSource, VideoDecoder, VideoEncoder
88

9-
source = VideoSource("rtmp://58.200.131.2:1935/livetv/hunantv", 0)
9+
source = VideoSource("rtmp://58.200.131.2:1935/livetv/hunantv")
1010
decoder = VideoDecoder()
1111
while True:
1212
h264_data = source.read()
13+
if not h264_data:
14+
break
1315
frames = decoder.decode(h264_data)
14-
if frames:
15-
cv2.imshow("Demo", frames[0])
16+
for frame in frames:
17+
cv2.imshow("Demo", frame)
1618
cv2.waitKey(1)
19+

tests/python/read_source_sdl.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import os
2+
import sys
3+
from cv2 import cv2
4+
import sdl2
5+
import sdl2.ext
6+
import numpy
7+
import time
8+
9+
lib_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../build/lib.linux-x86_64-3.6'))
10+
sys.path.append(lib_path)
11+
from nvcodec import VideoSource, VideoDecoder, VideoEncoder
12+
13+
windowArray = None
14+
window = None
15+
16+
def showImage(image):
17+
global windowArray, window
18+
if windowArray is None:
19+
sdl2.ext.init()
20+
window = sdl2.ext.Window("test", size=(image.shape[0],image.shape[1]))
21+
window.show()
22+
windowSurf = sdl2.SDL_GetWindowSurface(window.window)
23+
windowArray = sdl2.ext.pixels3d(windowSurf.contents)
24+
numpy.copyto(windowArray, image)
25+
window.refresh()
26+
27+
28+
# source = VideoSource("rtmp://58.200.131.2:1935/livetv/hunantv")
29+
source = VideoSource("/tmp/1.mp4")
30+
decoder = VideoDecoder()
31+
while True:
32+
h264_data = source.read()
33+
if not h264_data:
34+
break
35+
frames = decoder.decode(h264_data, 1)
36+
for frame in frames:
37+
showImage(frame)

0 commit comments

Comments
 (0)