Adding DTS support for B-series DTV
Posted: Tue Nov 09, 2010 12:06 pm
Some weeks ago I started the project of adding DTS support to samsung DTV since my B650 can not handle it.
According to the rules (http://forum.samygo.tv/viewtopic.php?f=5&t=607) I will describe and explain my hack.
It will look easier than it actually had been, because I will leave out all the dead ends I went into...
At the beginning of this little project the first issue that I encountered was the fact that the builtin ffmpeg libray (version 0.4) lacks DTS/DCA support. This can be seen when loading an DTS movie. You will get something like this:
Obviously the sample rate (should be 48000) is not detected correctly. So the first requirement is to replace the library with an external one.
The class "CParsingMedia" inside exeDSP is the interface beween Samsung code and ffmpeg library. The method "CParsingMedia::PrepareParsing()" loads the modules and gets required symbols.
I compiled one of the latest ffmpeg libraries (0.6), optimized DCA stuff and copied the modules into /mtd_rwarea/lib. Then I replaced "CParsingMedia::PrepareParsing()" with the following function:
Finally I was able to get the AVFormatContext populated properly, and also the dump information shows up correctly:
The backside of this medal: at least it breaks MKV support since the internal structures changed heavily from ffmpeg 0.4 to 0.6 and the Samsung engineers use these structures within "CParsingMedia::SetAudioStreamInfo()" and "CParsingMedia::SetVideoStreamInfo()".
So finally I ended up in re-writing almost the complete class "CParsingMedia"...
According to the rules (http://forum.samygo.tv/viewtopic.php?f=5&t=607) I will describe and explain my hack.
It will look easier than it actually had been, because I will leave out all the dead ends I went into...
At the beginning of this little project the first issue that I encountered was the fact that the builtin ffmpeg libray (version 0.4) lacks DTS/DCA support. This can be seen when loading an DTS movie. You will get something like this:
Code: Select all
===============[DUMP FORMAT]==============
* [FFMPEG LIBRARY] Ver. 2008/11/24(^__^) modified by C.Lucifer (0.4) *
Input #0, mpeg, from '/mtd_wiselink/MOVIE001/dts_experience.vob':
Duration: 00:01:17.17, start: 0.233567, bitrate: 8692 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 7000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x88]: Audio: dca, 0 Hz, 5.1, s16
The class "CParsingMedia" inside exeDSP is the interface beween Samsung code and ffmpeg library. The method "CParsingMedia::PrepareParsing()" loads the modules and gets required symbols.
I compiled one of the latest ffmpeg libraries (0.6), optimized DCA stuff and copied the modules into /mtd_rwarea/lib. Then I replaced "CParsingMedia::PrepareParsing()" with the following function:
Code: Select all
#define FFMPEG_LIB_PATH "/mtd_rwarea/lib/"
/* use external FFMPEG libraries */
void CParsingMedia::PrepareParsingExtFfmpeg(void)
{
ROSE_PRINT(0x4,"[CParsingMedia] %s In", __FUNCTION__ );
hLib_avutil = dlopen( FFMPEG_LIB_PATH "libavutil.so.50", RTLD_LAZY );
dlError = dlerror();
if( hLib_avutil == NULL ){
ROSE_PRINT(0x4000,"[libavutil.so dlopen error] %s", dlError );
goto exit_close_avutil;
}
/* ffmpeg 0.6 */
hLib_avcore = dlopen( FFMPEG_LIB_PATH "libavcore.so.0", RTLD_LAZY );
dlError = dlerror();
if( hLib_avcore == NULL ){
ROSE_PRINT(0x4000,"[libavcore.so.0 dlopen error] %s", dlError );
// goto exit_close_avutil;
}
hLib_avcodec = dlopen( FFMPEG_LIB_PATH "libavcodec.so.52", RTLD_LAZY );
dlError = dlerror();
if( hLib_avcodec == NULL ){
ROSE_PRINT(0x4000,"[libavcodec.so dlopen error] %s", dlError );
goto exit_close_avcodec;
}
hLib_avformat = dlopen( FFMPEG_LIB_PATH "libavformat.so.52", RTLD_LAZY );
dlError = dlerror();
if( hLib_avformat == NULL ){
ROSE_PRINT(0x4000,"[libavformat.so dlopen error] %s", dlError );
goto exit_close_avformat;
}
av_register_all222 = (av_register_all_t)dlsym(hLib_avformat,"av_register_all");
if( av_register_all222 == NULL ){
ROSE_PRINT(0x4000,"[av_register_all222 dlsym error]");
goto exit_close_avformat;
}
av_open_input_file222 = (av_open_input_file_t)dlsym(hLib_avformat,"av_open_input_file");
if( av_open_input_file222 == NULL ){
ROSE_PRINT(0x4000,"[av_open_input_file222 dlsym error]");
goto exit_close_avformat;
}
av_close_input_file222 = (av_close_input_file_t)dlsym(hLib_avformat,"av_close_input_file");
if( av_close_input_file222 == NULL ){
ROSE_PRINT(0x4000,"[av_close_input_file222 dlsym error]");
goto exit_close_avformat;
}
av_find_stream_info222 = (av_find_stream_info_t)dlsym(hLib_avformat,"av_find_stream_info");
if( av_find_stream_info222 == NULL ){
ROSE_PRINT(0x4000,"[av_find_stream_info222 dlsym error]");
goto exit_close_avformat;
}
dump_format222 = (dump_format_t)dlsym(hLib_avformat,"dump_format");
if( dump_format222 == NULL ){
ROSE_PRINT(0x4000,"[dump_format222 dlsym error]");
goto exit_close_avformat;
}
getMpeg4AACObjetType222 = (getMpeg4AACObjetType_t)dlsym(hLib_avformat,"getMpeg4AACObjetType");
if( getMpeg4AACObjetType222 == NULL ){
ROSE_PRINT(0x4000,"[getMpeg4AACObjetType222 dlsym error]");
goto exit_close_avformat;
}
getMpeg4AACSBR222 = (getMpeg4AACSBR_t)dlsym(hLib_avformat,"getMpeg4AACSBR");
if( getMpeg4AACSBR222 == NULL ){
ROSE_PRINT(0x4000,"[getMpeg4AACSBR222 dlsym error]");
goto exit_close_avformat;
}
/* all OK */
ROSE_PRINT(0x4,"[CParsingMedia] %s Out", __FUNCTION__ );
return;
exit_close_avformat:
dlclose( hLib_avformat );
exit_close_avcodec:
dlclose( hLib_avcodec );
exit_close_avutil:
dlclose( hLib_avutil );
return;
}
Code: Select all
===============[DUMP FORMAT]==============
Input #0, mpeg, from '/mtd_wiselink/MOVIE001/dts_experience.vob':
Duration: 00:01:17.17, start: 0.233567, bitrate: 8692 kb/s
Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p, 720x480 [PAR 8:9 DAR 4:3], 7000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x88]: Audio: dca, 48000 Hz, 5.1, s16, 1536 kb/s
==========================================
So finally I ended up in re-writing almost the complete class "CParsingMedia"...